wifi: mac80211: fix a expired vs. cancel race in roc
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Thu, 28 Sep 2023 14:35:36 +0000 (17:35 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 23 Oct 2023 09:45:17 +0000 (11:45 +0200)
commit9ad08fb1bcfdebfe71f9485affacfc24dd1b486b
treeabe4e6e110f313ea9535784e970101eb4f51343e
parent271d14b37fa5f2f9bd9e22711c3ba6b1532c8de1
wifi: mac80211: fix a expired vs. cancel race in roc

When the remain on channel is removed at the time it should
have expired, we have a race: the driver could be handling
the flow of the expiration while mac80211 is cancelling
that very same remain on channel request.

This wouldn't be problem in itself, but since mac80211
can send the next request to the driver in the cancellation
flow, we can get to the following situation:

           CPU0                             CPU1
expiration of roc in driver
ieee80211_remain_on_channel_expired()
                                         Cancellation of the roc
schedules a worker (hw_roc_done)
                                         Add next roc
hw_roc_done_wk runs and ends
the second roc prematurely.

Since, by design, there is only one single request sent to the
driver at a time, we can safely assume that after the cancel()
request returns from the driver, we should not handle any worker
that handles the expiration of the request.

Cancel the hw_roc_done worker after the cancellation to make
sure we start the next one with a clean slate.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230928172905.4e4469be20ac.Iab0525f5cc4698acf23eab98b8b1eec02099cde0@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/offchannel.c