Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

wifi: mac80211: use wiphy_hrtimer_work for csa.switch_work

The work item may be scheduled relatively far in the future. As the
event happens at a specific point in time, the normal timer accuracy is
not sufficient in that case.

Switch to use wiphy_hrtimer_work so that the accuracy is sufficient. To
make this work, use the same clock to store the timestamp.

CC: stable@vger.kernel.org
Fixes: ec3252bff7b6 ("wifi: mac80211: use wiphy work for channel switch")
Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20251028125710.68258c7e4ac4.I4ff2b2cdffbbf858bf5f08baccc7a88c4f9efe6f@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>

authored by

Benjamin Berg and committed by
Johannes Berg
fbc1cc69 3f654d53

+14 -14
+1 -1
net/mac80211/chan.c
··· 1290 1290 &link->csa.finalize_work); 1291 1291 break; 1292 1292 case NL80211_IFTYPE_STATION: 1293 - wiphy_delayed_work_queue(sdata->local->hw.wiphy, 1293 + wiphy_hrtimer_work_queue(sdata->local->hw.wiphy, 1294 1294 &link->u.mgd.csa.switch_work, 0); 1295 1295 break; 1296 1296 case NL80211_IFTYPE_UNSPECIFIED:
+2 -2
net/mac80211/ieee80211_i.h
··· 1017 1017 bool operating_11g_mode; 1018 1018 1019 1019 struct { 1020 - struct wiphy_delayed_work switch_work; 1020 + struct wiphy_hrtimer_work switch_work; 1021 1021 struct cfg80211_chan_def ap_chandef; 1022 1022 struct ieee80211_parsed_tpe tpe; 1023 - unsigned long time; 1023 + ktime_t time; 1024 1024 bool waiting_bcn; 1025 1025 bool ignored_same_chan; 1026 1026 bool blocked_tx;
+2 -2
net/mac80211/link.c
··· 472 472 * from there. 473 473 */ 474 474 if (link->conf->csa_active) 475 - wiphy_delayed_work_queue(local->hw.wiphy, 475 + wiphy_hrtimer_work_queue(local->hw.wiphy, 476 476 &link->u.mgd.csa.switch_work, 477 477 link->u.mgd.csa.time - 478 - jiffies); 478 + ktime_get_boottime()); 479 479 } 480 480 481 481 for_each_set_bit(link_id, &add, IEEE80211_MLD_MAX_NUM_LINKS) {
+9 -9
net/mac80211/mlme.c
··· 2594 2594 return; 2595 2595 } 2596 2596 2597 - wiphy_delayed_work_queue(sdata->local->hw.wiphy, 2597 + wiphy_hrtimer_work_queue(sdata->local->hw.wiphy, 2598 2598 &link->u.mgd.csa.switch_work, 0); 2599 2599 } 2600 2600 ··· 2753 2753 .timestamp = timestamp, 2754 2754 .device_timestamp = device_timestamp, 2755 2755 }; 2756 - unsigned long now; 2756 + u32 csa_time_tu; 2757 + ktime_t now; 2757 2758 int res; 2758 2759 2759 2760 lockdep_assert_wiphy(local->hw.wiphy); ··· 2984 2983 csa_ie.mode); 2985 2984 2986 2985 /* we may have to handle timeout for deactivated link in software */ 2987 - now = jiffies; 2988 - link->u.mgd.csa.time = now + 2989 - TU_TO_JIFFIES((max_t(int, csa_ie.count, 1) - 1) * 2990 - link->conf->beacon_int); 2986 + now = ktime_get_boottime(); 2987 + csa_time_tu = (max_t(int, csa_ie.count, 1) - 1) * link->conf->beacon_int; 2988 + link->u.mgd.csa.time = now + us_to_ktime(ieee80211_tu_to_usec(csa_time_tu)); 2991 2989 2992 2990 if (ieee80211_vif_link_active(&sdata->vif, link->link_id) && 2993 2991 local->ops->channel_switch) { ··· 3001 3001 } 3002 3002 3003 3003 /* channel switch handled in software */ 3004 - wiphy_delayed_work_queue(local->hw.wiphy, 3004 + wiphy_hrtimer_work_queue(local->hw.wiphy, 3005 3005 &link->u.mgd.csa.switch_work, 3006 3006 link->u.mgd.csa.time - now); 3007 3007 return; ··· 8849 8849 else 8850 8850 link->u.mgd.req_smps = IEEE80211_SMPS_OFF; 8851 8851 8852 - wiphy_delayed_work_init(&link->u.mgd.csa.switch_work, 8852 + wiphy_hrtimer_work_init(&link->u.mgd.csa.switch_work, 8853 8853 ieee80211_csa_switch_work); 8854 8854 8855 8855 ieee80211_clear_tpe(&link->conf->tpe); ··· 10064 10064 &link->u.mgd.request_smps_work); 10065 10065 wiphy_work_cancel(link->sdata->local->hw.wiphy, 10066 10066 &link->u.mgd.recalc_smps); 10067 - wiphy_delayed_work_cancel(link->sdata->local->hw.wiphy, 10067 + wiphy_hrtimer_work_cancel(link->sdata->local->hw.wiphy, 10068 10068 &link->u.mgd.csa.switch_work); 10069 10069 } 10070 10070