diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-06-25 06:32:01 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-06-25 06:32:01 -0400 |
commit | da7878d75b8520c9ae00d27dfbbce546a7bfdfbb (patch) | |
tree | 547fd497a80818a60ac36831377d5df97868173c /net/bluetooth | |
parent | 0e50a4c6ab94ffe7e5515b86b5df9e5abc8c6b13 (diff) | |
parent | 543cf4cb3fe6f6cae3651ba918b9c56200b257d0 (diff) |
Merge branch 'linus' into x86/pebs
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/rfcomm/core.c | 2 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/tty.c | 13 |
2 files changed, 13 insertions, 2 deletions
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index eb62558e9b09..0c2c93735e93 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
@@ -423,8 +423,8 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err) | |||
423 | 423 | ||
424 | rfcomm_dlc_lock(d); | 424 | rfcomm_dlc_lock(d); |
425 | d->state = BT_CLOSED; | 425 | d->state = BT_CLOSED; |
426 | rfcomm_dlc_unlock(d); | ||
427 | d->state_change(d, err); | 426 | d->state_change(d, err); |
427 | rfcomm_dlc_unlock(d); | ||
428 | 428 | ||
429 | skb_queue_purge(&d->tx_queue); | 429 | skb_queue_purge(&d->tx_queue); |
430 | rfcomm_dlc_unlink(d); | 430 | rfcomm_dlc_unlink(d); |
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index c3f749abb2d0..c9191871c1e0 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c | |||
@@ -566,11 +566,22 @@ static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err) | |||
566 | if (dlc->state == BT_CLOSED) { | 566 | if (dlc->state == BT_CLOSED) { |
567 | if (!dev->tty) { | 567 | if (!dev->tty) { |
568 | if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) { | 568 | if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) { |
569 | if (rfcomm_dev_get(dev->id) == NULL) | 569 | /* Drop DLC lock here to avoid deadlock |
570 | * 1. rfcomm_dev_get will take rfcomm_dev_lock | ||
571 | * but in rfcomm_dev_add there's lock order: | ||
572 | * rfcomm_dev_lock -> dlc lock | ||
573 | * 2. rfcomm_dev_put will deadlock if it's | ||
574 | * the last reference | ||
575 | */ | ||
576 | rfcomm_dlc_unlock(dlc); | ||
577 | if (rfcomm_dev_get(dev->id) == NULL) { | ||
578 | rfcomm_dlc_lock(dlc); | ||
570 | return; | 579 | return; |
580 | } | ||
571 | 581 | ||
572 | rfcomm_dev_del(dev); | 582 | rfcomm_dev_del(dev); |
573 | rfcomm_dev_put(dev); | 583 | rfcomm_dev_put(dev); |
584 | rfcomm_dlc_lock(dlc); | ||
574 | } | 585 | } |
575 | } else | 586 | } else |
576 | tty_hangup(dev->tty); | 587 | tty_hangup(dev->tty); |