forked from Minki/linux
[PATCH] bcm43xx: netlink deadlock fix
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 <arjan@linux.intel.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Cc: Michael Buesch <mb@bu3sch.de> Cc: "John W. Linville" <linville@tuxdriver.com> Cc: Jeff Garzik <jeff@garzik.org> Acked-by: "David S. Miller" <davem@davemloft.net> Cc: jamal <hadi@cyberus.ca> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
b02454f435
commit
6abd219c6e
@ -156,7 +156,7 @@ static void netlink_sock_destruct(struct sock *sk)
|
|||||||
|
|
||||||
static void netlink_table_grab(void)
|
static void netlink_table_grab(void)
|
||||||
{
|
{
|
||||||
write_lock_bh(&nl_table_lock);
|
write_lock_irq(&nl_table_lock);
|
||||||
|
|
||||||
if (atomic_read(&nl_table_users)) {
|
if (atomic_read(&nl_table_users)) {
|
||||||
DECLARE_WAITQUEUE(wait, current);
|
DECLARE_WAITQUEUE(wait, current);
|
||||||
@ -166,9 +166,9 @@ static void netlink_table_grab(void)
|
|||||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||||
if (atomic_read(&nl_table_users) == 0)
|
if (atomic_read(&nl_table_users) == 0)
|
||||||
break;
|
break;
|
||||||
write_unlock_bh(&nl_table_lock);
|
write_unlock_irq(&nl_table_lock);
|
||||||
schedule();
|
schedule();
|
||||||
write_lock_bh(&nl_table_lock);
|
write_lock_irq(&nl_table_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
__set_current_state(TASK_RUNNING);
|
__set_current_state(TASK_RUNNING);
|
||||||
@ -178,7 +178,7 @@ static void netlink_table_grab(void)
|
|||||||
|
|
||||||
static __inline__ void netlink_table_ungrab(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);
|
wake_up(&nl_table_wait);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user