From: Arjan van de Ven reported by Jure Repinc: > > http://bugzilla.kernel.org/show_bug.cgi?id=6773 > > checked out dmesg output and found the message > > > > ====================================================== > > [ BUG: hard-safe -> hard-unsafe lock order detected! ] > > ------------------------------------------------------ > > > > starting at line 660 of the dmesg.txt that I will attach. The patch below should fix the deadlock, albeit I suspect it's not the "right" fix; the right fix may well be to move the rx processing in bcm43xx to softirq context. [it's debatable, ipw2200 hit this exact same bug; at some point it's better to bite the bullet and move this to the common layer as my patch below does] Make the nl_table_lock irq-safe; it's taken for read in various netlink functions, including functions that several wireless drivers (ipw2200, bcm43xx) want to call from hardirq context. The deadlock was found by the lock validator. Signed-off-by: Arjan van de Ven Signed-off-by: Ingo Molnar Signed-off-by: Herbert Xu Cc: Michael Buesch Cc: "John W. Linville" Cc: Jeff Garzik Cc: "David S. Miller" Cc: jamal Signed-off-by: Andrew Morton --- net/netlink/af_netlink.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff -puN net/netlink/af_netlink.c~bcm43xx-netlink-deadlock-fix net/netlink/af_netlink.c --- a/net/netlink/af_netlink.c~bcm43xx-netlink-deadlock-fix +++ a/net/netlink/af_netlink.c @@ -156,7 +156,7 @@ static void netlink_sock_destruct(struct static void netlink_table_grab(void) { - write_lock_bh(&nl_table_lock); + write_lock_irq(&nl_table_lock); if (atomic_read(&nl_table_users)) { DECLARE_WAITQUEUE(wait, current); @@ -166,9 +166,9 @@ static void netlink_table_grab(void) set_current_state(TASK_UNINTERRUPTIBLE); if (atomic_read(&nl_table_users) == 0) break; - write_unlock_bh(&nl_table_lock); + write_unlock_irq(&nl_table_lock); schedule(); - write_lock_bh(&nl_table_lock); + write_lock_irq(&nl_table_lock); } __set_current_state(TASK_RUNNING); @@ -178,7 +178,7 @@ static void netlink_table_grab(void) static __inline__ void netlink_table_ungrab(void) { - write_unlock_bh(&nl_table_lock); + write_unlock_irq(&nl_table_lock); wake_up(&nl_table_wait); } _