From: Narendra K Date: Tue, 25 Sep 2012 07:53:19 +0000 (+0000) Subject: qlcnic: Fix scheduling while atomic bug X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=68b3f28c11bf896be32ad2a2e151aaa5f4a7c98e;p=openwrt%2Fstaging%2Fblogic.git qlcnic: Fix scheduling while atomic bug In the device close path, 'qlcnic_fw_destroy_ctx' and 'qlcnic_poll_rsp' call msleep. But 'qlcnic_fw_destroy_ctx' and 'qlcnic_poll_rsp' are called with 'adapter->tx_clean_lock' spin lock held resulting in scheduling while atomic bug causing the following trace. I observed that the commit 012dc19a45b2b9cc2ebd14aaa401cf782c2abba4 from John Fastabend addresses a similar issue in ixgbevf driver. Adopting the same approach used in the commit, this patch uses mdelay to address the issue. [79884.999115] BUG: scheduling while atomic: ip/30846/0x00000002 [79885.005562] INFO: lockdep is turned off. [79885.009958] Modules linked in: qlcnic fuse nf_conntrack_netbios_ns nf_conntrack_broadcast ipt_MASQUERADE bnep bluetooth rfkill ip6table_mangle ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 ip6table_filter ip6_tables iptable_nat nf_nat iptable_mangle ipt_REJECT nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack nf_conntrack iptable_filter ip_tables dcdbas coretemp kvm_intel kvm iTCO_wdt ixgbe iTCO_vendor_support crc32c_intel ghash_clmulni_intel nfsd microcode sb_edac pcspkr edac_core dca bnx2x shpchp auth_rpcgss nfs_acl lpc_ich mfd_core mdio lockd libcrc32c wmi acpi_pad acpi_power_meter sunrpc uinput sd_mod sr_mod cdrom crc_t10dif ahci libahci libata megaraid_sas usb_storage dm_mirror dm_region_hash dm_log dm_mod [last unloaded: qlcnic] [79885.083608] Pid: 30846, comm: ip Tainted: G W O 3.6.0-rc7+ #1 [79885.090805] Call Trace: [79885.093569] [] __schedule_bug+0x68/0x76 [79885.099699] [] __schedule+0x99e/0xa00 [79885.105634] [] schedule+0x29/0x70 [79885.111186] [] schedule_timeout+0x16f/0x350 [79885.117724] [] ? init_object+0x4a/0x90 [79885.123770] [] ? __internal_add_timer+0x140/0x140 [79885.130873] [] schedule_timeout_uninterruptible+0x1e/0x20 [79885.138773] [] msleep+0x20/0x30 [79885.144159] [] qlcnic_issue_cmd+0xef/0x290 [qlcnic] [79885.151478] [] qlcnic_fw_cmd_destroy_rx_ctx+0x55/0x90 [qlcnic] [79885.159868] [] qlcnic_fw_destroy_ctx+0x2d/0xa0 [qlcnic] [79885.167576] [] __qlcnic_down+0x11d/0x180 [qlcnic] [79885.174708] [] qlcnic_close+0x18/0x20 [qlcnic] [79885.181547] [] __dev_close_many+0x95/0xe0 [79885.187899] [] __dev_close+0x38/0x50 [79885.193761] [] __dev_change_flags+0xa1/0x180 [79885.200419] [] dev_change_flags+0x28/0x70 [79885.206779] [] do_setlink+0x378/0xa00 [79885.212731] [] ? nla_parse+0x31/0xe0 [79885.218612] [] rtnl_newlink+0x37e/0x560 [79885.224768] [] ? selinux_capable+0x39/0x50 [79885.231217] [] ? security_capable+0x18/0x20 [79885.237765] [] rtnetlink_rcv_msg+0x114/0x2f0 [79885.244412] [] ? rtnl_lock+0x17/0x20 [79885.250280] [] ? rtnl_lock+0x17/0x20 [79885.256148] [] ? __rtnl_unlock+0x20/0x20 [79885.262413] [] netlink_rcv_skb+0xa1/0xb0 [79885.268661] [] rtnetlink_rcv+0x25/0x40 [79885.274727] [] netlink_unicast+0x19d/0x220 [79885.281146] [] netlink_sendmsg+0x305/0x3f0 [79885.287595] [] ? sock_update_classid+0x148/0x2e0 [79885.294650] [] sock_sendmsg+0xbc/0xf0 [79885.300600] [] __sys_sendmsg+0x3ac/0x3c0 [79885.306853] [] ? up_read+0x23/0x40 [79885.312510] [] ? do_page_fault+0x2bc/0x570 [79885.318968] [] ? sys_brk+0x44/0x150 [79885.324715] [] ? fget_light+0x24c/0x520 [79885.330875] [] sys_sendmsg+0x49/0x90 [79885.336707] [] system_call_fastpath+0x16/0x1b Signed-off-by: Narendra K Signed-off-by: David S. Miller --- diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c index b8ead696141e..2a179d087207 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c @@ -15,7 +15,7 @@ qlcnic_poll_rsp(struct qlcnic_adapter *adapter) do { /* give atleast 1ms for firmware to respond */ - msleep(1); + mdelay(1); if (++timeout > QLCNIC_OS_CRB_RETRY_COUNT) return QLCNIC_CDRP_RSP_TIMEOUT; @@ -601,7 +601,7 @@ void qlcnic_fw_destroy_ctx(struct qlcnic_adapter *adapter) qlcnic_fw_cmd_destroy_tx_ctx(adapter); /* Allow dma queues to drain after context reset */ - msleep(20); + mdelay(20); } }