From 35d2cfb27392c73096b9cbdb0e250a900474301f Mon Sep 17 00:00:00 2001 From: Cyril Bur Date: Thu, 25 Feb 2016 13:27:18 +1100 Subject: [PATCH] net/ncsi: Fix possible deadlock caught with lockdep Bringing the interfaces down with ifdown -a directly after boot causes a lockdep warning. It appears that a network interrupt would result in an attempt to acquire that lock again. The solution is to soft disable interrupts. ================================= [ INFO: inconsistent lock state ] 4.3.6 #1 Not tainted --------------------------------- inconsistent {IN-SOFTIRQ-W} -> {SOFTIRQ-ON-W} usage. ip/934 [HC0[0]:SC0[0]:HE1:SE1] takes: (&(&ndp->ndp_package_lock)->rlock){+.?...}, at: [] ncsi_stop_dev+0x14/0x50 {IN-SOFTIRQ-W} state was registered at: [] _raw_spin_lock+0x28/0x38 [] ncsi_add_package+0x64/0xf0 [] ncsi_rsp_handler_sp+0x80/0xe0 [] ncsi_rcv_rsp+0xd4/0x104 [] __netif_receive_skb_core+0x6c4/0x808 [] netif_receive_skb_internal+0xb4/0x138 [] napi_gro_receive+0x48/0x9c [] ftgmac100_poll+0x360/0x59c [] net_rx_action+0xe8/0x2a0 [] __do_softirq+0x108/0x26c [] do_softirq+0x48/0x70 [] __local_bh_enable_ip+0xc8/0x104 [] __dev_queue_xmit+0x654/0x6c4 [] ncsi_xmit_cmd+0x1d4/0x208 [] ncsi_dev_start+0xd0/0x3c0 [] ncsi_dev_work+0x1b8/0x1fc [] process_one_work+0x228/0x3cc [] worker_thread+0x2a4/0x3d8 [] kthread+0xc4/0xd8 [] ret_from_fork+0x14/0x28 irq event stamp: 2009 hardirqs last enabled at (2009): [] __local_bh_enable_ip+0xe4/0x104 hardirqs last disabled at (2007): [] __local_bh_enable_ip+0x64/0x104 softirqs last enabled at (2008): [] dev_deactivate_many+0x270/0x2ac softirqs last disabled at (2006): [] dev_deactivate_many+0x254/0x2ac other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(&(&ndp->ndp_package_lock)->rlock); lock(&(&ndp->ndp_package_lock)->rlock); *** DEADLOCK *** 1 lock held by ip/934: #0: (rtnl_mutex){+.+.+.}, at: [] devinet_ioctl+0x15c/0x6c8 stack backtrace: CPU: 0 PID: 934 Comm: ip Not tainted 4.3.6 #1 Hardware name: ASpeed SoC [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [] (show_stack) from [] (print_usage_bug.part.11+0x220/0x288) [] (print_usage_bug.part.11) from [] (mark_lock+0x400/0x678) [] (mark_lock) from [] (__lock_acquire+0xa0c/0x1a9c) [] (__lock_acquire) from [] (lock_acquire+0x9c/0xbc) [] (lock_acquire) from [] (_raw_spin_lock+0x28/0x38) [] (_raw_spin_lock) from [] (ncsi_stop_dev+0x14/0x50) [] (ncsi_stop_dev) from [] (ftgmac100_stop+0x1c/0x28) [] (ftgmac100_stop) from [] (__dev_close_many+0xa0/0xc8) [] (__dev_close_many) from [] (__dev_close+0x20/0x34) [] (__dev_close) from [] (__dev_change_flags+0x8c/0x138) [] (__dev_change_flags) from [] (dev_change_flags+0x18/0x48) [] (dev_change_flags) from [] (devinet_ioctl+0x32c/0x6c8) [] (devinet_ioctl) from [] (sock_ioctl+0x26c/0x2d0) [] (sock_ioctl) from [] (do_vfs_ioctl+0x588/0x67c) [] (do_vfs_ioctl) from [] (SyS_ioctl+0x34/0x5c) [] (SyS_ioctl) from [] (ret_fast_syscall+0x0/0x1c) Signed-off-by: Cyril Bur Signed-off-by: Joel Stanley --- net/ncsi/ncsi-manage.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c index 24ff6c28533265..ef1de7feb5268c 100644 --- a/net/ncsi/ncsi-manage.c +++ b/net/ncsi/ncsi-manage.c @@ -907,10 +907,10 @@ void ncsi_stop_dev(struct ncsi_dev *nd) struct ncsi_dev_priv *ndp = TO_NCSI_DEV_PRIV(nd); struct ncsi_package *tmp, *np; - spin_lock(&ndp->ndp_package_lock); + spin_lock_bh(&ndp->ndp_package_lock); list_for_each_entry_safe(np, tmp, &ndp->ndp_packages, np_node) ncsi_release_package(np); - spin_unlock(&ndp->ndp_package_lock); + spin_unlock_bh(&ndp->ndp_package_lock); } EXPORT_SYMBOL_GPL(ncsi_stop_dev);