diff options
author | Bing Zhao <bzhao@marvell.com> | 2012-11-15 15:58:47 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-12-03 11:37:57 -0800 |
commit | d467bca7112c08e3981ec568fad9e7d091e3328b (patch) | |
tree | 3fc76e0653056a5218f5a4bc764b4a66f73a289b | |
parent | 5410faf6a70b35a851246e32b6b3adfec72a5ffa (diff) |
mwifiex: fix system hang issue in cmd timeout error case
commit b1a47aa5e1e159e2cb06d7dfcc17ef5149b09299 upstream.
Reported by Tim Shepard:
I was seeing sporadic failures (wedgeups), and the majority of those
failures I saw printed the printouts in mwifiex_cmd_timeout_func with
cmd = 0xe5 which is CMD_802_11_HS_CFG_ENH. When this happens, two
minutes later I get notified that the rtcwake thread is blocked, like
this:
INFO: task rtcwake:3495 blocked for more than 120 seconds.
To get the hung thread unblocked we wake up the cmd wait queue and
cancel the ioctl.
Reported-by: Tim Shepard <shep@laptop.org>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/net/wireless/mwifiex/cmdevt.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index 565527aee0e..95382f1ebce 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -887,9 +887,6 @@ mwifiex_cmd_timeout_func(unsigned long function_context) return; } cmd_node = adapter->curr_cmd; - if (cmd_node->wait_q_enabled) - adapter->cmd_wait_q.status = -ETIMEDOUT; - if (cmd_node) { adapter->dbg.timeout_cmd_id = adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index]; @@ -935,6 +932,14 @@ mwifiex_cmd_timeout_func(unsigned long function_context) dev_err(adapter->dev, "ps_mode=%d ps_state=%d\n", adapter->ps_mode, adapter->ps_state); + + if (cmd_node->wait_q_enabled) { + adapter->cmd_wait_q.status = -ETIMEDOUT; + wake_up_interruptible(&adapter->cmd_wait_q.wait); + mwifiex_cancel_pending_ioctl(adapter); + /* reset cmd_sent flag to unblock new commands */ + adapter->cmd_sent = false; + } } if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) mwifiex_init_fw_complete(adapter); |