]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
another bluetooth patch
authorGreg Kroah-Hartman <gregkh@suse.de>
Mon, 16 Jun 2008 19:43:31 +0000 (12:43 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 16 Jun 2008 19:43:31 +0000 (12:43 -0700)
review-2.6.25/bluetooth-rfcomm_dev_state_change-deadlock-fix.patch [new file with mode: 0644]
review-2.6.25/series

diff --git a/review-2.6.25/bluetooth-rfcomm_dev_state_change-deadlock-fix.patch b/review-2.6.25/bluetooth-rfcomm_dev_state_change-deadlock-fix.patch
new file mode 100644 (file)
index 0000000..3c4ea3c
--- /dev/null
@@ -0,0 +1,74 @@
+From 537d59af73d894750cff14f90fe2b6d77fbab15b Mon Sep 17 00:00:00 2001
+From: Dave Young <hidave.darkstar@gmail.com>
+Date: Sun, 1 Jun 2008 23:50:52 -0700
+Subject: [PATCH] bluetooth: rfcomm_dev_state_change deadlock fix
+
+From: Dave Young <hidave.darkstar@gmail.com>
+
+commit 537d59af73d894750cff14f90fe2b6d77fbab15b in mainline
+
+There's logic in __rfcomm_dlc_close:
+       rfcomm_dlc_lock(d);
+       d->state = BT_CLOSED;
+       d->state_changed(d, err);
+       rfcomm_dlc_unlock(d);
+
+In rfcomm_dev_state_change, it's possible that rfcomm_dev_put try to
+take the dlc lock, then we will deadlock.
+
+Here fixed it by unlock dlc before rfcomm_dev_get in
+rfcomm_dev_state_change.
+
+why not unlock just before rfcomm_dev_put? it's because there's
+another problem.  rfcomm_dev_get/rfcomm_dev_del will take
+rfcomm_dev_lock, but in rfcomm_dev_add the lock order is :
+rfcomm_dev_lock --> dlc lock
+
+so I unlock dlc before the taken of rfcomm_dev_lock.
+
+Actually it's a regression caused by commit
+1905f6c736cb618e07eca0c96e60e3c024023428 ("bluetooth :
+__rfcomm_dlc_close lock fix"), the dlc state_change could be two
+callbacks : rfcomm_sk_state_change and rfcomm_dev_state_change. I
+missed the rfcomm_sk_state_change that time.
+
+Thanks Arjan van de Ven <arjan@linux.intel.com> for the effort in
+commit 4c8411f8c115def968820a4df6658ccfd55d7f1a ("bluetooth: fix
+locking bug in the rfcomm socket cleanup handling") but he missed the
+rfcomm_dev_state_change lock issue.
+
+Signed-off-by: Dave Young <hidave.darkstar@gmail.com>
+Acked-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/bluetooth/rfcomm/tty.c |   13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+--- a/net/bluetooth/rfcomm/tty.c
++++ b/net/bluetooth/rfcomm/tty.c
+@@ -566,11 +566,22 @@ static void rfcomm_dev_state_change(stru
+       if (dlc->state == BT_CLOSED) {
+               if (!dev->tty) {
+                       if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) {
+-                              if (rfcomm_dev_get(dev->id) == NULL)
++                              /* Drop DLC lock here to avoid deadlock
++                               * 1. rfcomm_dev_get will take rfcomm_dev_lock
++                               *    but in rfcomm_dev_add there's lock order:
++                               *    rfcomm_dev_lock -> dlc lock
++                               * 2. rfcomm_dev_put will deadlock if it's
++                               *    the last reference
++                               */
++                              rfcomm_dlc_unlock(dlc);
++                              if (rfcomm_dev_get(dev->id) == NULL) {
++                                      rfcomm_dlc_lock(dlc);
+                                       return;
++                              }
+                               rfcomm_dev_del(dev);
+                               rfcomm_dev_put(dev);
++                              rfcomm_dlc_lock(dlc);
+                       }
+               } else
+                       tty_hangup(dev->tty);
index debd5a61a5d00c302bbb5c0362199f7cdaffa7a2..fc5aef7de206d6a45a2fe57d15b722fd6fb1a8a4 100644 (file)
@@ -14,6 +14,7 @@ sunhv-fix-locking-in-non-paged-i-o-case.patch
 af_key-fix-selector-family-initialization.patch
 ax25-fix-null-pointer-dereference-and-lockup.patch
 bluetooth-fix-locking-bug-in-the-rfcomm-socket-cleanup-handling.patch
+bluetooth-rfcomm_dev_state_change-deadlock-fix.patch
 can-fix-copy_from_user-results-interpretation.patch
 cassini-only-use-chip-checksum-for-ipv4-packets.patch
 net-fix-call-to-change_rx_flags-in-dev_change_flags.patch