lkml.org 
[lkml]   [2019]   [Jul]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 4.19 121/158] wil6210: drop old event after wmi_call timeout
    Date
    From: Ahmad Masri <amasri@codeaurora.org>

    [ 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>
    ---
    drivers/net/wireless/ath/wil6210/wmi.c | 13 ++++++++++++-
    1 file changed, 12 insertions(+), 1 deletion(-)

    diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
    index 6e3b3031f29b..2010f771478d 100644
    --- a/drivers/net/wireless/ath/wil6210/wmi.c
    +++ b/drivers/net/wireless/ath/wil6210/wmi.c
    @@ -2816,7 +2816,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));
    --
    2.20.1
    \
     
     \ /
      Last update: 2019-07-15 17:45    [W:4.105 / U:0.036 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site