tcp/dccp: use rcu locking in inet_diag_find_one_icsk()
authorEric Dumazet <edumazet@google.com>
Fri, 1 Apr 2016 15:52:15 +0000 (08:52 -0700)
committerDavid S. Miller <davem@davemloft.net>
Tue, 5 Apr 2016 02:11:19 +0000 (22:11 -0400)
RX packet processing holds rcu_read_lock(), so we can remove
pairs of rcu_read_lock()/rcu_read_unlock() in lookup functions
if inet_diag also holds rcu before calling them.

This is needed anyway as __inet_lookup_listener() and
inet6_lookup_listener() will soon no longer increment
refcount on the found listener.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/inet_diag.c
net/ipv4/inet_hashtables.c
net/ipv6/inet6_hashtables.c

index 5fdb02f5598ebd47d303d5a2df2f1cef4ea5073d..ea8df527b2799b34113edf2c7846381b79c41559 100644 (file)
@@ -356,6 +356,7 @@ struct sock *inet_diag_find_one_icsk(struct net *net,
 {
        struct sock *sk;
 
+       rcu_read_lock();
        if (req->sdiag_family == AF_INET)
                sk = inet_lookup(net, hashinfo, NULL, 0, req->id.idiag_dst[0],
                                 req->id.idiag_dport, req->id.idiag_src[0],
@@ -376,9 +377,11 @@ struct sock *inet_diag_find_one_icsk(struct net *net,
                                          req->id.idiag_if);
        }
 #endif
-       else
+       else {
+               rcu_read_unlock();
                return ERR_PTR(-EINVAL);
-
+       }
+       rcu_read_unlock();
        if (!sk)
                return ERR_PTR(-ENOENT);
 
index bc68eced0105716dca6f04abbdd491a1cfb9e908..387338d71dcde9ebca429b7378c8ed7ef0a1f167 100644 (file)
@@ -220,7 +220,6 @@ struct sock *__inet_lookup_listener(struct net *net,
        bool select_ok = true;
        u32 phash = 0;
 
-       rcu_read_lock();
 begin:
        result = NULL;
        hiscore = 0;
@@ -269,7 +268,6 @@ found:
                        goto begin;
                }
        }
-       rcu_read_unlock();
        return result;
 }
 EXPORT_SYMBOL_GPL(__inet_lookup_listener);
@@ -312,7 +310,6 @@ struct sock *__inet_lookup_established(struct net *net,
        unsigned int slot = hash & hashinfo->ehash_mask;
        struct inet_ehash_bucket *head = &hashinfo->ehash[slot];
 
-       rcu_read_lock();
 begin:
        sk_nulls_for_each_rcu(sk, node, &head->chain) {
                if (sk->sk_hash != hash)
@@ -339,7 +336,6 @@ begin:
 out:
        sk = NULL;
 found:
-       rcu_read_unlock();
        return sk;
 }
 EXPORT_SYMBOL_GPL(__inet_lookup_established);
index d253f32874c9034e2bd060e920175f45437e2732..e6ef6ce1ed74b4f63ac47b3df9d9b27e000be35b 100644 (file)
@@ -69,7 +69,6 @@ struct sock *__inet6_lookup_established(struct net *net,
        struct inet_ehash_bucket *head = &hashinfo->ehash[slot];
 
 
-       rcu_read_lock();
 begin:
        sk_nulls_for_each_rcu(sk, node, &head->chain) {
                if (sk->sk_hash != hash)
@@ -90,7 +89,6 @@ begin:
 out:
        sk = NULL;
 found:
-       rcu_read_unlock();
        return sk;
 }
 EXPORT_SYMBOL(__inet6_lookup_established);
@@ -138,7 +136,6 @@ struct sock *inet6_lookup_listener(struct net *net,
        unsigned int hash = inet_lhashfn(net, hnum);
        struct inet_listen_hashbucket *ilb = &hashinfo->listening_hash[hash];
 
-       rcu_read_lock();
 begin:
        result = NULL;
        hiscore = 0;
@@ -187,7 +184,6 @@ found:
                        goto begin;
                }
        }
-       rcu_read_unlock();
        return result;
 }
 EXPORT_SYMBOL_GPL(inet6_lookup_listener);