Patchwork [net-next] ipv6: avoid taking locks at socket dismantle

login
register
mail settings
Submitter Eric Dumazet
Date Dec. 5, 2012, 7:18 p.m.
Message ID <1354735090.31222.21.camel@edumazet-glaptop>
Download mbox | patch
Permalink /patch/203926/
State Accepted
Delegated to: David Miller
Headers show

Comments

Eric Dumazet - Dec. 5, 2012, 7:18 p.m.
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>
---
 net/ipv6/anycast.c |    3 +++
 net/ipv6/mcast.c   |    3 +++
 2 files changed, 6 insertions(+)



--
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
David Stevens - Dec. 5, 2012, 9:07 p.m.
> 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
David Miller - Dec. 5, 2012, 9:21 p.m.
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
David Miller - Dec. 5, 2012, 9:26 p.m.
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

Patch

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) {