original_kernel/net/core
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
..
Makefile net: support time stamping in phy devices. 2010-07-18 19:15:26 -07:00
datagram.c net/core: EXPORT_SYMBOL cleanups 2010-07-12 12:57:55 -07:00
dev.c net: use rcu_barrier() in rollback_registered_many 2010-09-14 14:27:29 -07:00
dev_addr_lists.c
drop_monitor.c drop_monitor: use genl_register_family_with_ops() 2010-07-26 20:59:42 -07:00
dst.c __dst_free(): put EXPORT_SYMBOLS after the fct 2010-07-20 13:28:03 -07:00
ethtool.c
fib_rules.c
filter.c
flow.c net/core: EXPORT_SYMBOL cleanups 2010-07-12 12:57:55 -07:00
gen_estimator.c pkt_sched: Fix lockdep warning on est_tree_lock in gen_estimator 2010-09-02 13:22:11 -07:00
gen_stats.c net/core: EXPORT_SYMBOL cleanups 2010-07-12 12:57:55 -07:00
iovec.c net/core: EXPORT_SYMBOL cleanups 2010-07-12 12:57:55 -07:00
kmap_skb.h
link_watch.c net/core: EXPORT_SYMBOL cleanups 2010-07-12 12:57:55 -07:00
neighbour.c net/core: neighbour update Oops 2010-07-14 18:02:16 -07:00
net-sysfs.c sysfs: add attribute to indicate hw address assignment type 2010-07-24 20:49:29 -07:00
net-sysfs.h
net-traces.c
net_namespace.c
netevent.c net/core: EXPORT_SYMBOL cleanups 2010-07-12 12:57:55 -07:00
netpoll.c Revert "net: remove zap_completion_queue" 2010-08-03 00:24:04 -07:00
pktgen.c net: core: don't use own hex_to_bin() method 2010-07-23 12:50:51 -07:00
request_sock.c
rtnetlink.c net/core: EXPORT_SYMBOL cleanups 2010-07-12 12:57:55 -07:00
scm.c net/core: EXPORT_SYMBOL cleanups 2010-07-12 12:57:55 -07:00
skbuff.c gro: Re-fix different skb headrooms 2010-09-08 10:32:15 -07:00
sock.c net: fix a lockdep splat 2010-09-24 22:26:10 -07:00
stream.c net/core: EXPORT_SYMBOL cleanups 2010-07-12 12:57:55 -07:00
sysctl_net_core.c
timestamping.c net: support time stamping in phy devices. 2010-07-18 19:15:26 -07:00
user_dma.c
utils.c net/core: EXPORT_SYMBOL cleanups 2010-07-12 12:57:55 -07:00