aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/inet6_connection_sock.c
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2015-10-02 14:43:32 -0400
committerDavid S. Miller <davem@davemloft.net>2015-10-03 07:32:41 -0400
commit079096f103faca2dd87342cca6f23d4b34da8871 (patch)
treefa3fb0fdc064f1611c464384e70a7a402179808f /net/ipv6/inet6_connection_sock.c
parent2feda34192a379f8b35a7c6c5826b2f23e884f32 (diff)
tcp/dccp: install syn_recv requests into ehash table
In this patch, we insert request sockets into TCP/DCCP regular ehash table (where ESTABLISHED and TIMEWAIT sockets are) instead of using the per listener hash table. ACK packets find SYN_RECV pseudo sockets without having to find and lock the listener. In nominal conditions, this halves pressure on listener lock. Note that this will allow for SO_REUSEPORT refinements, so that we can select a listener using cpu/numa affinities instead of the prior 'consistent hash', since only SYN packets will apply this selection logic. We will shrink listen_sock in the following patch to ease code review. Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Ying Cai <ycai@google.com> Cc: Willem de Bruijn <willemb@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/inet6_connection_sock.c')
-rw-r--r--net/ipv6/inet6_connection_sock.c67
1 files changed, 0 insertions, 67 deletions
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
index ea915aa5e4e2..5d1c7cee2cb2 100644
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -94,73 +94,6 @@ struct dst_entry *inet6_csk_route_req(const struct sock *sk,
94} 94}
95EXPORT_SYMBOL(inet6_csk_route_req); 95EXPORT_SYMBOL(inet6_csk_route_req);
96 96
97/*
98 * request_sock (formerly open request) hash tables.
99 */
100static u32 inet6_synq_hash(const struct in6_addr *raddr, const __be16 rport,
101 const u32 rnd, const u32 synq_hsize)
102{
103 u32 c;
104
105 c = jhash_3words((__force u32)raddr->s6_addr32[0],
106 (__force u32)raddr->s6_addr32[1],
107 (__force u32)raddr->s6_addr32[2],
108 rnd);
109
110 c = jhash_2words((__force u32)raddr->s6_addr32[3],
111 (__force u32)rport,
112 c);
113
114 return c & (synq_hsize - 1);
115}
116
117struct request_sock *inet6_csk_search_req(struct sock *sk,
118 const __be16 rport,
119 const struct in6_addr *raddr,
120 const struct in6_addr *laddr,
121 const int iif)
122{
123 struct inet_connection_sock *icsk = inet_csk(sk);
124 struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt;
125 struct request_sock *req;
126 u32 hash = inet6_synq_hash(raddr, rport, lopt->hash_rnd,
127 lopt->nr_table_entries);
128
129 spin_lock(&icsk->icsk_accept_queue.syn_wait_lock);
130 for (req = lopt->syn_table[hash]; req != NULL; req = req->dl_next) {
131 const struct inet_request_sock *ireq = inet_rsk(req);
132
133 if (ireq->ir_rmt_port == rport &&
134 req->rsk_ops->family == AF_INET6 &&
135 ipv6_addr_equal(&ireq->ir_v6_rmt_addr, raddr) &&
136 ipv6_addr_equal(&ireq->ir_v6_loc_addr, laddr) &&
137 (!ireq->ir_iif || ireq->ir_iif == iif)) {
138 atomic_inc(&req->rsk_refcnt);
139 WARN_ON(req->sk != NULL);
140 break;
141 }
142 }
143 spin_unlock(&icsk->icsk_accept_queue.syn_wait_lock);
144
145 return req;
146}
147EXPORT_SYMBOL_GPL(inet6_csk_search_req);
148
149void inet6_csk_reqsk_queue_hash_add(struct sock *sk,
150 struct request_sock *req,
151 const unsigned long timeout)
152{
153 struct inet_connection_sock *icsk = inet_csk(sk);
154 struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt;
155 const u32 h = inet6_synq_hash(&inet_rsk(req)->ir_v6_rmt_addr,
156 inet_rsk(req)->ir_rmt_port,
157 lopt->hash_rnd, lopt->nr_table_entries);
158
159 reqsk_queue_hash_req(&icsk->icsk_accept_queue, h, req, timeout);
160 inet_csk_reqsk_queue_added(sk);
161}
162EXPORT_SYMBOL_GPL(inet6_csk_reqsk_queue_hash_add);
163
164void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr) 97void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr)
165{ 98{
166 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) uaddr; 99 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) uaddr;