diff options
author | Cathy Luo <cluo@marvell.com> | 2016-09-20 17:19:03 +0200 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2016-09-26 19:39:42 +0200 |
commit | 5476f8030d9a9f7082ba5a4d4f0a1bfbf6936800 (patch) | |
tree | 478d84df8e7fc531d7fdb4df11bf6e8162168508 /drivers/net/wireless | |
parent | mwifiex: fix kernel crash for USB chipsets (diff) | |
download | linux-5476f8030d9a9f7082ba5a4d4f0a1bfbf6936800.tar.xz linux-5476f8030d9a9f7082ba5a4d4f0a1bfbf6936800.zip |
mwifiex: fix race condition causing tx timeout
It's been observed that in a corner case mwifiex_usb_tx_complete()
gets called before we exit from mwifiex_usb_host_to_card() after
submitting the urb. 'data_sent' flag remains set in this case. It
blocks further Tx packets and triggers watchdog timeout.
The problem is fixed by setting data_sent and port_block flag at
correct place.
Signed-off-by: Cathy Luo <cluo@marvell.com>
Signed-off-by: Shengzhen Li <szli@marvell.com>
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/marvell/mwifiex/usb.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/drivers/net/wireless/marvell/mwifiex/usb.c b/drivers/net/wireless/marvell/mwifiex/usb.c index e8283dc1f088..8fd51e42ea5e 100644 --- a/drivers/net/wireless/marvell/mwifiex/usb.c +++ b/drivers/net/wireless/marvell/mwifiex/usb.c @@ -897,6 +897,13 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep, else atomic_inc(&port->tx_data_urb_pending); + if (ep != card->tx_cmd_ep && + atomic_read(&port->tx_data_urb_pending) == + MWIFIEX_TX_DATA_URB) { + port->block_status = true; + adapter->data_sent = mwifiex_usb_data_sent(adapter); + } + if (usb_submit_urb(tx_urb, GFP_ATOMIC)) { mwifiex_dbg(adapter, ERROR, "%s: usb_submit_urb failed\n", __func__); @@ -905,6 +912,7 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep, } else { atomic_dec(&port->tx_data_urb_pending); port->block_status = false; + adapter->data_sent = false; if (port->tx_data_ix) port->tx_data_ix--; else @@ -916,9 +924,7 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep, if (ep != card->tx_cmd_ep && atomic_read(&port->tx_data_urb_pending) == MWIFIEX_TX_DATA_URB) { - port->block_status = true; - ret = -ENOSR; - goto done; + return -ENOSR; } } |