diff mbox

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

Message ID 1354735090.31222.21.camel@edumazet-glaptop
State Accepted, archived
Delegated to: David Miller
Headers show

Commit Message

Eric Dumazet Dec. 5, 2012, 7:18 p.m. UTC
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

Comments

David Stevens Dec. 5, 2012, 9:07 p.m. UTC | #1
> 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. UTC | #2
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. UTC | #3
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 mbox

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