inet: drop prev pointer handling in request sock
authorEric Dumazet <edumazet@google.com>
Fri, 20 Mar 2015 02:04:19 +0000 (19:04 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 20 Mar 2015 16:40:25 +0000 (12:40 -0400)
When request sock are put in ehash table, the whole notion
of having a previous request to update dl_next is pointless.

Also, following patch will get rid of big purge timer,
so we want to delete a request sock without holding listener lock.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
14 files changed:
include/net/inet6_connection_sock.h
include/net/inet_connection_sock.h
include/net/request_sock.h
include/net/tcp.h
net/dccp/dccp.h
net/dccp/ipv4.c
net/dccp/ipv6.c
net/dccp/minisocks.c
net/ipv4/inet_connection_sock.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_minisocks.c
net/ipv6/inet6_connection_sock.c
net/ipv6/tcp_ipv6.c

index 74af137..15bd408 100644 (file)
@@ -29,7 +29,6 @@ struct dst_entry *inet6_csk_route_req(struct sock *sk, struct flowi6 *fl6,
                                      const struct request_sock *req);
 
 struct request_sock *inet6_csk_search_req(const struct sock *sk,
-                                         struct request_sock ***prevp,
                                          const __be16 rport,
                                          const struct in6_addr *raddr,
                                          const struct in6_addr *laddr,
index b9a6b0a..423a461 100644 (file)
@@ -257,7 +257,6 @@ inet_csk_rto_backoff(const struct inet_connection_sock *icsk,
 struct sock *inet_csk_accept(struct sock *sk, int flags, int *err);
 
 struct request_sock *inet_csk_search_req(const struct sock *sk,
-                                        struct request_sock ***prevp,
                                         const __be16 rport,
                                         const __be32 raddr,
                                         const __be32 laddr);
@@ -310,17 +309,15 @@ static inline int inet_csk_reqsk_queue_is_full(const struct sock *sk)
 }
 
 static inline void inet_csk_reqsk_queue_unlink(struct sock *sk,
-                                              struct request_sock *req,
-                                              struct request_sock **prev)
+                                              struct request_sock *req)
 {
-       reqsk_queue_unlink(&inet_csk(sk)->icsk_accept_queue, req, prev);
+       reqsk_queue_unlink(&inet_csk(sk)->icsk_accept_queue, req);
 }
 
 static inline void inet_csk_reqsk_queue_drop(struct sock *sk,
-                                            struct request_sock *req,
-                                            struct request_sock **prev)
+                                            struct request_sock *req)
 {
-       inet_csk_reqsk_queue_unlink(sk, req, prev);
+       inet_csk_reqsk_queue_unlink(sk, req);
        inet_csk_reqsk_queue_removed(sk, req);
        reqsk_free(req);
 }
index e7ef863..6522390 100644 (file)
@@ -50,6 +50,7 @@ int inet_rtx_syn_ack(struct sock *parent, struct request_sock *req);
 struct request_sock {
        struct sock_common              __req_common;
 #define rsk_refcnt                     __req_common.skc_refcnt
+#define rsk_hash                       __req_common.skc_hash
 
        struct request_sock             *dl_next;
        struct sock                     *rsk_listener;
@@ -216,11 +217,16 @@ static inline int reqsk_queue_empty(struct request_sock_queue *queue)
 }
 
 static inline void reqsk_queue_unlink(struct request_sock_queue *queue,
-                                     struct request_sock *req,
-                                     struct request_sock **prev_req)
+                                     struct request_sock *req)
 {
+       struct listen_sock *lopt = queue->listen_opt;
+       struct request_sock **prev;
+
        write_lock(&queue->syn_wait_lock);
-       *prev_req = req->dl_next;
+       prev = &lopt->syn_table[req->rsk_hash];
+       while (*prev != req)
+               prev = &(*prev)->dl_next;
+       *prev = req->dl_next;
        write_unlock(&queue->syn_wait_lock);
 }
 
@@ -300,7 +306,6 @@ static inline void reqsk_queue_hash_req(struct request_sock_queue *queue,
        req->num_retrans = 0;
        req->num_timeout = 0;
        req->sk = NULL;
-       req->dl_next = lopt->syn_table[hash];
 
        /* before letting lookups find us, make sure all req fields
         * are committed to memory and refcnt initialized.
@@ -308,7 +313,9 @@ static inline void reqsk_queue_hash_req(struct request_sock_queue *queue,
        smp_wmb();
        atomic_set(&req->rsk_refcnt, 1);
 
+       req->rsk_hash = hash;
        write_lock(&queue->syn_wait_lock);
+       req->dl_next = lopt->syn_table[hash];
        lopt->syn_table[hash] = req;
        write_unlock(&queue->syn_wait_lock);
 }
index 5b29835..082fd79 100644 (file)
@@ -406,8 +406,7 @@ enum tcp_tw_status tcp_timewait_state_process(struct inet_timewait_sock *tw,
                                              struct sk_buff *skb,
                                              const struct tcphdr *th);
 struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
-                          struct request_sock *req, struct request_sock **prev,
-                          bool fastopen);
+                          struct request_sock *req, bool fastopen);
 int tcp_child_process(struct sock *parent, struct sock *child,
                      struct sk_buff *skb);
 void tcp_enter_loss(struct sock *sk);
index 3b1d64d..2396f50 100644 (file)
@@ -280,8 +280,7 @@ struct sock *dccp_v4_request_recv_sock(struct sock *sk, struct sk_buff *skb,
                                       struct request_sock *req,
                                       struct dst_entry *dst);
 struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb,
-                           struct request_sock *req,
-                           struct request_sock **prev);
+                           struct request_sock *req);
 
 int dccp_child_process(struct sock *parent, struct sock *child,
                       struct sk_buff *skb);
index e7ad291..5bffbba 100644 (file)
@@ -288,11 +288,11 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)
        }
 
        switch (sk->sk_state) {
-               struct request_sock *req , **prev;
+               struct request_sock *req;
        case DCCP_LISTEN:
                if (sock_owned_by_user(sk))
                        goto out;
-               req = inet_csk_search_req(sk, &prev, dh->dccph_dport,
+               req = inet_csk_search_req(sk, dh->dccph_dport,
                                          iph->daddr, iph->saddr);
                if (!req)
                        goto out;
@@ -314,7 +314,7 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)
                 * created socket, and POSIX does not want network
                 * errors returned from accept().
                 */
-               inet_csk_reqsk_queue_drop(sk, req, prev);
+               inet_csk_reqsk_queue_drop(sk, req);
                goto out;
 
        case DCCP_REQUESTING:
@@ -448,13 +448,11 @@ static struct sock *dccp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
        const struct dccp_hdr *dh = dccp_hdr(skb);
        const struct iphdr *iph = ip_hdr(skb);
        struct sock *nsk;
-       struct request_sock **prev;
        /* Find possible connection requests. */
-       struct request_sock *req = inet_csk_search_req(sk, &prev,
-                                                      dh->dccph_sport,
+       struct request_sock *req = inet_csk_search_req(sk, dh->dccph_sport,
                                                       iph->saddr, iph->daddr);
-       if (req != NULL)
-               return dccp_check_req(sk, skb, req, prev);
+       if (req)
+               return dccp_check_req(sk, skb, req);
 
        nsk = inet_lookup_established(sock_net(sk), &dccp_hashinfo,
                                      iph->saddr, dh->dccph_sport,
diff --cc net/dccp/ipv6.c
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge