1
linux/net/sunrpc
Eric Dumazet f064af1e50 net: fix a lockdep splat
We have for each socket :

One spinlock (sk_slock.slock)
One rwlock (sk_callback_lock)

Possible scenarios are :

(A) (this is used in net/sunrpc/xprtsock.c)
read_lock(&sk->sk_callback_lock) (without blocking BH)
<BH>
spin_lock(&sk->sk_slock.slock);
...
read_lock(&sk->sk_callback_lock);
...

(B)
write_lock_bh(&sk->sk_callback_lock)
stuff
write_unlock_bh(&sk->sk_callback_lock)

(C)
spin_lock_bh(&sk->sk_slock)
...
write_lock_bh(&sk->sk_callback_lock)
stuff
write_unlock_bh(&sk->sk_callback_lock)
spin_unlock_bh(&sk->sk_slock)

This (C) case conflicts with (A) :

CPU1 [A]                         CPU2 [C]
read_lock(callback_lock)
<BH>                             spin_lock_bh(slock)
<wait to spin_lock(slock)>
                                 <wait to write_lock_bh(callback_lock)>

We have one problematic (C) use case in inet_csk_listen_stop() :

local_bh_disable();
bh_lock_sock(child); // spin_lock_bh(&sk->sk_slock)
WARN_ON(sock_owned_by_user(child));
...
sock_orphan(child); // write_lock_bh(&sk->sk_callback_lock)

lockdep is not happy with this, as reported by Tetsuo Handa

It seems only way to deal with this is to use read_lock_bh(callbacklock)
everywhere.

Thanks to Jarek for pointing a bug in my first attempt and suggesting
this solution.

Reported-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Tested-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
CC: Jarek Poplawski <jarkao2@gmail.com>
Tested-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2010-09-24 22:26:10 -07:00
..
auth_gss SUNRPC: Defer deleting the security context until gss_do_free_ctx() 2010-08-04 08:55:14 -04:00
xprtrdma rpcrdma: Fix SQ size calculation when memreg is FRMR 2010-08-11 12:47:24 -04:00
addr.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
auth_generic.c SUNRPC: Clean up of rpc_bindcred() 2010-08-04 08:54:08 -04:00
auth_null.c SUNRPC: Move the bound cred to struct rpc_rqst 2010-08-04 08:54:09 -04:00
auth_unix.c SUNRPC: Move the bound cred to struct rpc_rqst 2010-08-04 08:54:09 -04:00
auth.c nfs: update for module_param_named API change 2010-08-11 23:04:15 +09:30
backchannel_rqst.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
bc_svc.c Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6 2010-04-11 14:53:53 -07:00
cache.c net: sunrpc: removed duplicated #include 2010-08-06 17:05:39 -04:00
clnt.c SUNRPC: Move the bound cred to struct rpc_rqst 2010-08-04 08:54:09 -04:00
Kconfig NFS: Fix the selection of security flavours in Kconfig 2010-08-17 17:42:45 -04:00
Makefile
rpc_pipe.c sunrpc: Pushdown the bkl from ioctl 2010-05-22 17:44:19 +02:00
rpcb_clnt.c kernel-wide: replace USHORT_MAX, SHORT_MAX and SHORT_MIN with USHRT_MAX, SHRT_MAX and SHRT_MIN 2010-05-25 08:07:02 -07:00
sched.c SUNRPC: Reduce asynchronous RPC task stack usage 2010-08-04 08:54:09 -04:00
socklib.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
stats.c SUNRPC: Move the task->tk_bytes_sent and tk_rtt to struct rpc_rqst 2010-05-14 15:09:36 -04:00
sunrpc_syms.c Merge branch 'for-2.6.36' of git://linux-nfs.org/~bfields/linux 2010-08-07 14:24:41 -07:00
sunrpc.h
svc_xprt.c Merge commit 'v2.6.34-rc6' 2010-05-04 11:29:05 -04:00
svc.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
svcauth_unix.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
svcauth.c net: Move && and || to end of previous line 2009-11-29 16:55:45 -08:00
svcsock.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6 2010-05-20 21:04:44 -07:00
sysctl.c sysctl: Drop & in front of every proc_handler. 2009-11-18 08:37:40 -08:00
timer.c
xdr.c xdr: Add an export for the helper function write_bytes_to_xdr_buf() 2010-05-14 15:09:18 -04:00
xprt.c SUNRPC: prevent task_cleanup running on freed xprt 2010-08-04 08:54:10 -04:00
xprtsock.c net: fix a lockdep splat 2010-09-24 22:26:10 -07:00