Message ID | 1354735090.31222.21.camel@edumazet-glaptop |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
> From: Eric Dumazet <edumazet@google.com> > > ipv6_sock_mc_close() is called for ipv6 sockets at close time, and most > of them don't use multicast. > > Add a test to avoid contention on a shared spinlock. > > Same heuristic applies for ipv6_sock_ac_close(), to avoid contention > on a shared rwlock. What prevents a different thread from racing with the tests for NULL on these? +-DLS -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
From: David Stevens <dlstevens@us.ibm.com> Date: Wed, 5 Dec 2012 16:07:16 -0500 >> From: Eric Dumazet <edumazet@google.com> >> >> ipv6_sock_mc_close() is called for ipv6 sockets at close time, and most >> of them don't use multicast. >> >> Add a test to avoid contention on a shared spinlock. >> >> Same heuristic applies for ipv6_sock_ac_close(), to avoid contention >> on a shared rwlock. > > What prevents a different thread from racing with the > tests for NULL on these? The socket is being torn apart, which means that operations on it's FD are no longer possible, which means that no other thread can add entries to these lists. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Eric Dumazet <eric.dumazet@gmail.com> Date: Wed, 05 Dec 2012 11:18:10 -0800 > From: Eric Dumazet <edumazet@google.com> > > ipv6_sock_mc_close() is called for ipv6 sockets at close time, and most > of them don't use multicast. > > Add a test to avoid contention on a shared spinlock. > > Same heuristic applies for ipv6_sock_ac_close(), to avoid contention > on a shared rwlock. > > Signed-off-by: Eric Dumazet <edumazet@google.com> Applied. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c index 2f4f584..757a810 100644 --- a/net/ipv6/anycast.c +++ b/net/ipv6/anycast.c @@ -189,6 +189,9 @@ void ipv6_sock_ac_close(struct sock *sk) struct net *net = sock_net(sk); int prev_index; + if (!np->ipv6_ac_list) + return; + write_lock_bh(&ipv6_sk_ac_lock); pac = np->ipv6_ac_list; np->ipv6_ac_list = NULL; diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index b19ed51..28dfa5f 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -284,6 +284,9 @@ void ipv6_sock_mc_close(struct sock *sk) struct ipv6_mc_socklist *mc_lst; struct net *net = sock_net(sk); + if (!rcu_access_pointer(np->ipv6_mc_list)) + return; + spin_lock(&ipv6_sk_mc_lock); while ((mc_lst = rcu_dereference_protected(np->ipv6_mc_list, lockdep_is_held(&ipv6_sk_mc_lock))) != NULL) {