Skip to content

Commit 93a77c1

Browse files
edumazetdavem330
authored andcommitted
tcp: add tcp_inet6_sk() helper
TCP ipv6 fast path dereferences a pointer to get to the inet6 part of a tcp socket, but given the fixed memory placement, we can do better and avoid a possible cache line miss. This also reduces register pressure, since we let the compiler know about this memory placement. Signed-off-by: Eric Dumazet <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent f8d6ae0 commit 93a77c1

File tree

1 file changed

+26
-18
lines changed

1 file changed

+26
-18
lines changed

net/ipv6/tcp_ipv6.c

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,17 @@ static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(const struct sock *sk,
9090
}
9191
#endif
9292

93+
/* Helper returning the inet6 address from a given tcp socket.
94+
* It can be used in TCP stack instead of inet6_sk(sk).
95+
* This avoids a dereference and allow compiler optimizations.
96+
*/
97+
static struct ipv6_pinfo *tcp_inet6_sk(const struct sock *sk)
98+
{
99+
struct tcp6_sock *tcp6 = container_of(tcp_sk(sk), struct tcp6_sock, tcp);
100+
101+
return &tcp6->inet6;
102+
}
103+
93104
static void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb)
94105
{
95106
struct dst_entry *dst = skb_dst(skb);
@@ -99,7 +110,7 @@ static void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb)
99110

100111
sk->sk_rx_dst = dst;
101112
inet_sk(sk)->rx_dst_ifindex = skb->skb_iif;
102-
inet6_sk(sk)->rx_dst_cookie = rt6_get_cookie(rt);
113+
tcp_inet6_sk(sk)->rx_dst_cookie = rt6_get_cookie(rt);
103114
}
104115
}
105116

@@ -138,7 +149,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
138149
struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr;
139150
struct inet_sock *inet = inet_sk(sk);
140151
struct inet_connection_sock *icsk = inet_csk(sk);
141-
struct ipv6_pinfo *np = inet6_sk(sk);
152+
struct ipv6_pinfo *np = tcp_inet6_sk(sk);
142153
struct tcp_sock *tp = tcp_sk(sk);
143154
struct in6_addr *saddr = NULL, *final_p, final;
144155
struct ipv6_txoptions *opt;
@@ -390,7 +401,7 @@ static int tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
390401
if (sk->sk_state == TCP_CLOSE)
391402
goto out;
392403

393-
if (ipv6_hdr(skb)->hop_limit < inet6_sk(sk)->min_hopcount) {
404+
if (ipv6_hdr(skb)->hop_limit < tcp_inet6_sk(sk)->min_hopcount) {
394405
__NET_INC_STATS(net, LINUX_MIB_TCPMINTTLDROP);
395406
goto out;
396407
}
@@ -405,7 +416,7 @@ static int tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
405416
goto out;
406417
}
407418

408-
np = inet6_sk(sk);
419+
np = tcp_inet6_sk(sk);
409420

410421
if (type == NDISC_REDIRECT) {
411422
if (!sock_owned_by_user(sk)) {
@@ -478,7 +489,7 @@ static int tcp_v6_send_synack(const struct sock *sk, struct dst_entry *dst,
478489
enum tcp_synack_type synack_type)
479490
{
480491
struct inet_request_sock *ireq = inet_rsk(req);
481-
struct ipv6_pinfo *np = inet6_sk(sk);
492+
struct ipv6_pinfo *np = tcp_inet6_sk(sk);
482493
struct ipv6_txoptions *opt;
483494
struct flowi6 *fl6 = &fl->u.ip6;
484495
struct sk_buff *skb;
@@ -737,7 +748,7 @@ static void tcp_v6_init_req(struct request_sock *req,
737748
{
738749
bool l3_slave = ipv6_l3mdev_skb(TCP_SKB_CB(skb)->header.h6.flags);
739750
struct inet_request_sock *ireq = inet_rsk(req);
740-
const struct ipv6_pinfo *np = inet6_sk(sk_listener);
751+
const struct ipv6_pinfo *np = tcp_inet6_sk(sk_listener);
741752

742753
ireq->ir_v6_rmt_addr = ipv6_hdr(skb)->saddr;
743754
ireq->ir_v6_loc_addr = ipv6_hdr(skb)->daddr;
@@ -1066,9 +1077,8 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
10661077
{
10671078
struct inet_request_sock *ireq;
10681079
struct ipv6_pinfo *newnp;
1069-
const struct ipv6_pinfo *np = inet6_sk(sk);
1080+
const struct ipv6_pinfo *np = tcp_inet6_sk(sk);
10701081
struct ipv6_txoptions *opt;
1071-
struct tcp6_sock *newtcp6sk;
10721082
struct inet_sock *newinet;
10731083
struct tcp_sock *newtp;
10741084
struct sock *newsk;
@@ -1088,11 +1098,10 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
10881098
if (!newsk)
10891099
return NULL;
10901100

1091-
newtcp6sk = (struct tcp6_sock *)newsk;
1092-
inet_sk(newsk)->pinet6 = &newtcp6sk->inet6;
1101+
inet_sk(newsk)->pinet6 = tcp_inet6_sk(newsk);
10931102

10941103
newinet = inet_sk(newsk);
1095-
newnp = inet6_sk(newsk);
1104+
newnp = tcp_inet6_sk(newsk);
10961105
newtp = tcp_sk(newsk);
10971106

10981107
memcpy(newnp, np, sizeof(struct ipv6_pinfo));
@@ -1156,12 +1165,11 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
11561165
ip6_dst_store(newsk, dst, NULL, NULL);
11571166
inet6_sk_rx_dst_set(newsk, skb);
11581167

1159-
newtcp6sk = (struct tcp6_sock *)newsk;
1160-
inet_sk(newsk)->pinet6 = &newtcp6sk->inet6;
1168+
inet_sk(newsk)->pinet6 = tcp_inet6_sk(newsk);
11611169

11621170
newtp = tcp_sk(newsk);
11631171
newinet = inet_sk(newsk);
1164-
newnp = inet6_sk(newsk);
1172+
newnp = tcp_inet6_sk(newsk);
11651173

11661174
memcpy(newnp, np, sizeof(struct ipv6_pinfo));
11671175

@@ -1276,9 +1284,9 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
12761284
*/
12771285
static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
12781286
{
1279-
struct ipv6_pinfo *np = inet6_sk(sk);
1280-
struct tcp_sock *tp;
1287+
struct ipv6_pinfo *np = tcp_inet6_sk(sk);
12811288
struct sk_buff *opt_skb = NULL;
1289+
struct tcp_sock *tp;
12821290

12831291
/* Imagine: socket is IPv6. IPv4 packet arrives,
12841292
goes to IPv4 receive handler and backlogged.
@@ -1524,7 +1532,7 @@ static int tcp_v6_rcv(struct sk_buff *skb)
15241532
return 0;
15251533
}
15261534
}
1527-
if (hdr->hop_limit < inet6_sk(sk)->min_hopcount) {
1535+
if (hdr->hop_limit < tcp_inet6_sk(sk)->min_hopcount) {
15281536
__NET_INC_STATS(net, LINUX_MIB_TCPMINTTLDROP);
15291537
goto discard_and_relse;
15301538
}
@@ -1669,7 +1677,7 @@ static void tcp_v6_early_demux(struct sk_buff *skb)
16691677
struct dst_entry *dst = READ_ONCE(sk->sk_rx_dst);
16701678

16711679
if (dst)
1672-
dst = dst_check(dst, inet6_sk(sk)->rx_dst_cookie);
1680+
dst = dst_check(dst, tcp_inet6_sk(sk)->rx_dst_cookie);
16731681
if (dst &&
16741682
inet_sk(sk)->rx_dst_ifindex == skb->skb_iif)
16751683
skb_dst_set_noref(skb, dst);

0 commit comments

Comments
 (0)