Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=4ce61d1c7a8ef4c1337fa983a3036d4010e3c19e
Commit:     4ce61d1c7a8ef4c1337fa983a3036d4010e3c19e
Parent:     689d79469b64662440a93ffbd1cbf994510bcbf6
Author:     Satyam Sharma <[EMAIL PROTECTED]>
AuthorDate: Wed May 16 23:50:16 2007 -0700
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Thu May 17 14:20:30 2007 -0700

    [BLUETOOTH]: Fix locking in hci_sock_dev_event().
    
    We presently use lock_sock() to acquire a lock on a socket in
    hci_sock_dev_event(), but this goes BUG because lock_sock()
    can sleep and we're already holding a read-write spinlock at
    that point. So, we must use the non-sleeping BH version,
    bh_lock_sock().
    
    However, hci_sock_dev_event() is called from user context and
    hence using simply bh_lock_sock() will deadlock against a
    concurrent softirq that tries to acquire a lock on the same
    socket. Hence, disabling BH's before acquiring the socket lock
    and enable them afterwards, is the proper solution to fix
    socket locking in hci_sock_dev_event().
    
    Signed-off-by: Satyam Sharma <[EMAIL PROTECTED]>
    Signed-off-by: Marcel Holtmann <[EMAIL PROTECTED]>
    Signed-off-by: Jiri Kosina <[EMAIL PROTECTED]>
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
---
 net/bluetooth/hci_sock.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index bfc9a35..1dae3df 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -665,7 +665,8 @@ static int hci_sock_dev_event(struct notifier_block *this, 
unsigned long event,
                /* Detach sockets from device */
                read_lock(&hci_sk_list.lock);
                sk_for_each(sk, node, &hci_sk_list.head) {
-                       lock_sock(sk);
+                       local_bh_disable();
+                       bh_lock_sock_nested(sk);
                        if (hci_pi(sk)->hdev == hdev) {
                                hci_pi(sk)->hdev = NULL;
                                sk->sk_err = EPIPE;
@@ -674,7 +675,8 @@ static int hci_sock_dev_event(struct notifier_block *this, 
unsigned long event,
 
                                hci_dev_put(hdev);
                        }
-                       release_sock(sk);
+                       bh_unlock_sock(sk);
+                       local_bh_enable();
                }
                read_unlock(&hci_sk_list.lock);
        }
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to