diff options
author | Ahmad Masri <amasri@codeaurora.org> | 2019-06-16 10:26:07 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-07-26 09:10:38 +0200 |
commit | 0ecba23bbc730e9b88e8f5d2c30573b39d2095f4 (patch) | |
tree | 3aa6c414c6c3ff0a38e3b82113869ec3bff9b2d2 /drivers | |
parent | a1b5ed07288f0ec7967585929e404b5068903178 (diff) | |
download | linux-stable-0ecba23bbc730e9b88e8f5d2c30573b39d2095f4.tar.gz linux-stable-0ecba23bbc730e9b88e8f5d2c30573b39d2095f4.tar.bz2 linux-stable-0ecba23bbc730e9b88e8f5d2c30573b39d2095f4.zip |
wil6210: drop old event after wmi_call timeout
[ Upstream commit 1a276003111c0404f6bfeffe924c5a21f482428b ]
This change fixes a rare race condition of handling WMI events after
wmi_call expires.
wmi_recv_cmd immediately handles an event when reply_buf is defined and
a wmi_call is waiting for the event.
However, in case the wmi_call has already timed-out, there will be no
waiting/running wmi_call and the event will be queued in WMI queue and
will be handled later in wmi_event_handle.
Meanwhile, a new similar wmi_call for the same command and event may
be issued. In this case, when handling the queued event we got WARN_ON
printed.
Fixing this case as a valid timeout and drop the unexpected event.
Signed-off-by: Ahmad Masri <amasri@codeaurora.org>
Signed-off-by: Maya Erez <merez@codeaurora.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/ath/wil6210/wmi.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index d89cd41e78ac..89a75ff29410 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -3220,7 +3220,18 @@ static void wmi_event_handle(struct wil6210_priv *wil, /* check if someone waits for this event */ if (wil->reply_id && wil->reply_id == id && wil->reply_mid == mid) { - WARN_ON(wil->reply_buf); + if (wil->reply_buf) { + /* event received while wmi_call is waiting + * with a buffer. Such event should be handled + * in wmi_recv_cmd function. Handling the event + * here means a previous wmi_call was timeout. + * Drop the event and do not handle it. + */ + wil_err(wil, + "Old event (%d, %s) while wmi_call is waiting. Drop it and Continue waiting\n", + id, eventid2name(id)); + return; + } wmi_evt_call_handler(vif, id, evt_data, len - sizeof(*wmi)); |