Re: [Bugme-new] [Bug 12515] New: possible circular locking #0: (sk_lock-AF_PACKET){--..}, at: [<c1279838>] sock_setsockopt+0x12b/0x4a4

Previous thread: HCI crash after tearing down ppp connection by Johannes Berg on Tuesday, January 27, 2009 - 12:01 pm. (3 messages)

Next thread: [PATCH] ide/net: flip the order of SATA and network init by Arjan van de Ven on Tuesday, January 27, 2009 - 3:19 pm. (7 messages)

(switched to email.  Please respond via emailed reply-to-all, not via the
bugzilla web interface).

On Tue, 20 Jan 2009 10:16:38 -0800 (PST)

More info at the link.  Vegard did some analysis, had a shot at fixing
it, but it seems that he missed.

--


There has been some discussion under subject
&quot;Re: [PATCH] net: fix setsockopt() locking errors&quot;
and I hope it is archived somewhere via netdev@vger.kernel.org .
If not, Jarek Poplawski and Peter Zijlstra have some clues
what to do and I am waiting for Vegard Nossum to give me
another patch to test.


Here is some part of the discussion ,hopefully the most important
part:


Since it's really needed, and Vegard started doing it like this, I
guess he will try to add the missing pieces.

Thanks again,
Jarek P.






--


I have tested the patch below in bugzilla and cannot reproduce anymore.
dmesg(1) output in bugzilla.

Martin


------- Comment #8 from vegard.nossum@gmail.com  2009-01-27 14:38 -------
Created an attachment (id=20018)
 --&gt; (http://bugzilla.kernel.org/attachment.cgi?id=20018&amp;action=view)
[PATCH] net: fix setsockopt() locking errors #2

Andrew, I just missed a case because the actual call to copy_from_user was in a
different file altogether.

There might be more, but I didn't really have the time to look for everything
yet.

In the meantime, I give you this patch, which includes the SO_ATTACH_FILTER
socket option, which is what was reported to fail with the first patch applied.

I also don't REALLY think this is a regression, it's just lockdep that got
smarter (or the insertion of a might_fault() something something made it more
likely to show up -- I think this was info from Peter, but I don't remember

--


Dave pointed out that a spin lock is illegal for this purpose
as vm_insert_page can do a GFP_KERNEL allocation.  So I've added
a mutex for this.

I've also widened the critical section in packet_set_ring since
we need the mapped check to be within it.

packet: Avoid lock_sock in mmap handler

As the mmap handler gets called under mmap_sem, and we may grab
mmap_sem elsewhere under the socket lock to access user data, we
should avoid grabbing the socket lock in the mmap handler.

Since the only thing we care about in the mmap handler is for
pg_vec* to be invariant, i.e., to exclude packet_set_ring, we
can achieve this by simply using sk_receive_queue.lock.

I resisted the temptation to create a new spin lock because the
mmap path isn't exactly common.

Signed-off-by: Herbert Xu &lt;herbert@gondor.apana.org.au&gt;

diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 5f94db2..9454d4a 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -77,6 +77,7 @@
 #include &lt;linux/poll.h&gt;
 #include &lt;linux/module.h&gt;
 #include &lt;linux/init.h&gt;
+#include &lt;linux/mutex.h&gt;
 
 #ifdef CONFIG_INET
 #include &lt;net/inet_common.h&gt;
@@ -175,6 +176,7 @@ struct packet_sock {
 #endif
 	struct packet_type	prot_hook;
 	spinlock_t		bind_lock;
+	struct mutex		pg_vec_lock;
 	unsigned int		running:1,	/* prot_hook is attached*/
 				auxdata:1,
 				origdev:1;
@@ -1069,6 +1071,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol)
 	 */
 
 	spin_lock_init(&amp;po-&gt;bind_lock);
+	mutex_init(&amp;po-&gt;pg_vec_lock);
 	po-&gt;prot_hook.func = packet_rcv;
 
 	if (sock-&gt;type == SOCK_PACKET)
@@ -1865,6 +1868,7 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing
 	synchronize_net();
 
 	err = -EBUSY;
+	mutex_lock(&amp;po-&gt;pg_vec_lock);
 	if (closing || atomic_read(&amp;po-&gt;mapped) == 0) {
 		err = 0;
 #define XC(a, b) ({ __typeof__ ((a)) __t; __t = (a); (a) = (b); __t; })
@@ -1886,6 +1890,7 @@ static int packet_set_ring(struct sock *sk, ...

On Fri, Jan 30, 2009 at 11:49:47PM +1100, Herbert Xu wrote:

So, Dave is stronger than the temptation...

Jarek P.
--


Heh, that sentence should be removed from the description.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV&gt;HI~} &lt;herbert@gondor.apana.org.au&gt;
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--


From: Herbert Xu &lt;herbert@gondor.apana.org.au&gt;

I might leave it in there for laughs :-)
--


From: Herbert Xu &lt;herbert@gondor.apana.org.au&gt;

Looks good, applied.

I rewrote the commit message as follows so that it actually
matches what happens in the fix ;-)

--------------------
packet: Avoid lock_sock in mmap handler

As the mmap handler gets called under mmap_sem, and we may grab
mmap_sem elsewhere under the socket lock to access user data, we
should avoid grabbing the socket lock in the mmap handler.

Since the only thing we care about in the mmap handler is for
pg_vec* to be invariant, i.e., to exclude packet_set_ring, we
can achieve this by simply using a new mutex.

Signed-off-by: Herbert Xu &lt;herbert@gondor.apana.org.au&gt;
Signed-off-by: David S. Miller &lt;davem@davemloft.net&gt;
--

Previous thread: HCI crash after tearing down ppp connection by Johannes Berg on Tuesday, January 27, 2009 - 12:01 pm. (3 messages)

Next thread: [PATCH] ide/net: flip the order of SATA and network init by Arjan van de Ven on Tuesday, January 27, 2009 - 3:19 pm. (7 messages)