Message ID | 20200527193919.1655228-1-bigeasy@linutronix.de (mailing list archive) |
---|---|
State | New, archived |
Delegated to: | Marcel Holtmann |
Headers | show |
Series | Bluetooth: Acquire sk_lock.slock without disabling interrupts | expand |
Hi Sebastian,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on bluetooth-next/master]
[also build test WARNING on v5.7-rc7 next-20200526]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
url: https://github.com/0day-ci/linux/commits/Sebastian-Andrzej-Siewior/Bluetooth-Acquire-sk_lock-slock-without-disabling-interrupts/20200528-034222
base: https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git master
:::::: branch date: 9 hours ago
:::::: commit date: 9 hours ago
config: i386-randconfig-s001-20200528 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-13) 9.3.0
reproduce:
# apt-get install sparse
# sparse version: v0.6.1-240-gf0fe1cd9-dirty
# save the attached .config to linux build tree
make W=1 C=1 ARCH=i386 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'
If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>
sparse warnings: (new ones prefixed by >>)
>> net/bluetooth/rfcomm/sock.c:64:13: sparse: sparse: context imbalance in 'rfcomm_sk_state_change' - wrong count at exit
# https://github.com/0day-ci/linux/commit/dc48a377813eebe5a9e4818d98f51df0da9476fc
git remote add linux-review https://github.com/0day-ci/linux
git remote update linux-review
git checkout dc48a377813eebe5a9e4818d98f51df0da9476fc
vim +/rfcomm_sk_state_change +64 net/bluetooth/rfcomm/sock.c
^1da177e4c3f41 Linus Torvalds 2005-04-16 63
^1da177e4c3f41 Linus Torvalds 2005-04-16 @64 static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
^1da177e4c3f41 Linus Torvalds 2005-04-16 65 {
^1da177e4c3f41 Linus Torvalds 2005-04-16 66 struct sock *sk = d->owner, *parent;
fad003b6c8e3d9 Gustavo Padovan 2010-08-14 67
^1da177e4c3f41 Linus Torvalds 2005-04-16 68 if (!sk)
^1da177e4c3f41 Linus Torvalds 2005-04-16 69 return;
^1da177e4c3f41 Linus Torvalds 2005-04-16 70
^1da177e4c3f41 Linus Torvalds 2005-04-16 71 BT_DBG("dlc %p state %ld err %d", d, d->state, err);
^1da177e4c3f41 Linus Torvalds 2005-04-16 72
dc48a377813eeb Sebastian Andrzej Siewior 2020-05-27 73 spin_lock_bh(&sk->sk_lock.slock);
^1da177e4c3f41 Linus Torvalds 2005-04-16 74
^1da177e4c3f41 Linus Torvalds 2005-04-16 75 if (err)
^1da177e4c3f41 Linus Torvalds 2005-04-16 76 sk->sk_err = err;
^1da177e4c3f41 Linus Torvalds 2005-04-16 77
^1da177e4c3f41 Linus Torvalds 2005-04-16 78 sk->sk_state = d->state;
^1da177e4c3f41 Linus Torvalds 2005-04-16 79
^1da177e4c3f41 Linus Torvalds 2005-04-16 80 parent = bt_sk(sk)->parent;
^1da177e4c3f41 Linus Torvalds 2005-04-16 81 if (parent) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 82 if (d->state == BT_CLOSED) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 83 sock_set_flag(sk, SOCK_ZAPPED);
^1da177e4c3f41 Linus Torvalds 2005-04-16 84 bt_accept_unlink(sk);
^1da177e4c3f41 Linus Torvalds 2005-04-16 85 }
676d23690fb62b David S. Miller 2014-04-11 86 parent->sk_data_ready(parent);
^1da177e4c3f41 Linus Torvalds 2005-04-16 87 } else {
^1da177e4c3f41 Linus Torvalds 2005-04-16 88 if (d->state == BT_CONNECTED)
94a86df0108255 Marcel Holtmann 2013-10-13 89 rfcomm_session_getaddr(d->session,
94a86df0108255 Marcel Holtmann 2013-10-13 90 &rfcomm_pi(sk)->src, NULL);
^1da177e4c3f41 Linus Torvalds 2005-04-16 91 sk->sk_state_change(sk);
^1da177e4c3f41 Linus Torvalds 2005-04-16 92 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 93
dc48a377813eeb Sebastian Andrzej Siewior 2020-05-27 94 spin_lock_bh(&sk->sk_lock.slock);
^1da177e4c3f41 Linus Torvalds 2005-04-16 95
^1da177e4c3f41 Linus Torvalds 2005-04-16 96 if (parent && sock_flag(sk, SOCK_ZAPPED)) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 97 /* We have to drop DLC lock here, otherwise
^1da177e4c3f41 Linus Torvalds 2005-04-16 98 * rfcomm_sock_destruct() will dead lock. */
^1da177e4c3f41 Linus Torvalds 2005-04-16 99 rfcomm_dlc_unlock(d);
^1da177e4c3f41 Linus Torvalds 2005-04-16 100 rfcomm_sock_kill(sk);
^1da177e4c3f41 Linus Torvalds 2005-04-16 101 rfcomm_dlc_lock(d);
^1da177e4c3f41 Linus Torvalds 2005-04-16 102 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 103 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 104
:::::: The code at line 64 was first introduced by commit
:::::: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Linux-2.6.12-rc2
:::::: TO: Linus Torvalds <torvalds@ppc970.osdl.org>
:::::: CC: Linus Torvalds <torvalds@ppc970.osdl.org>
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index b4eaf21360ef2..ad6ba6ce23436 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -64,15 +64,13 @@ static void rfcomm_sk_data_ready(struct rfcomm_dlc *d, struct sk_buff *skb) static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err) { struct sock *sk = d->owner, *parent; - unsigned long flags; if (!sk) return; BT_DBG("dlc %p state %ld err %d", d, d->state, err); - local_irq_save(flags); - bh_lock_sock(sk); + spin_lock_bh(&sk->sk_lock.slock); if (err) sk->sk_err = err; @@ -93,8 +91,7 @@ static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err) sk->sk_state_change(sk); } - bh_unlock_sock(sk); - local_irq_restore(flags); + spin_lock_bh(&sk->sk_lock.slock); if (parent && sock_flag(sk, SOCK_ZAPPED)) { /* We have to drop DLC lock here, otherwise
There was a lockdep which led to commit fad003b6c8e3d ("Bluetooth: Fix inconsistent lock state with RFCOMM") Lockdep noticed that `sk->sk_lock.slock' was acquired without disabling the softirq while the lock was also used in softirq context. Unfortunately the solution back then was to disable interrupts before acquiring the lock which however made lockdep happy. It would have been enough to simply disable the softirq. Disabling interrupts before acquiring a spinlock_t is not allowed on PREEMPT_RT because these locks are converted to 'sleeping' spinlocks. Use spin_lock_bh() in order to acquire the `sk_lock.slock'. Reported-by: Luis Claudio R. Goncalves <lclaudio@uudg.org> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- net/bluetooth/rfcomm/sock.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)