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

wifi: mac80211: don't WARN for late channel/color switch

There's really no value in the WARN stack trace etc., the reason
for this happening isn't directly related to the calling function
anyway. Also, syzbot has been observing it constantly, and there's
no way we can resolve it there - those systems are just slow.

Instead print an error message (once) and add a comment about what
really causes this message.

Reported-by: syzbot+468656785707b0e995df@syzkaller.appspotmail.com
Reported-by: syzbot+18c783c5cf6a781e3e2c@syzkaller.appspotmail.com
Reported-by: syzbot+d5924d5cffddfccab68e@syzkaller.appspotmail.com
Reported-by: syzbot+7d73d99525d1ff7752ef@syzkaller.appspotmail.com
Reported-by: syzbot+8e6e002c74d1927edaf5@syzkaller.appspotmail.com
Reported-by: syzbot+97254a3b10c541879a65@syzkaller.appspotmail.com
Reported-by: syzbot+dfd1fd46a1960ad9c6ec@syzkaller.appspotmail.com
Reported-by: syzbot+85e0b8d12d9ca877d806@syzkaller.appspotmail.com
Link: https://patch.msgid.link/20250617104902.146e10919be1.I85f352ca4a2dce6f556e5ff45ceaa5f3769cb5ce@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>

+25 -9
+4 -1
net/mac80211/debug.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * Portions 4 - * Copyright (C) 2022 - 2024 Intel Corporation 4 + * Copyright (C) 2022 - 2025 Intel Corporation 5 5 */ 6 6 #ifndef __MAC80211_DEBUG_H 7 7 #define __MAC80211_DEBUG_H 8 + #include <linux/once_lite.h> 8 9 #include <net/cfg80211.h> 9 10 10 11 #ifdef CONFIG_MAC80211_OCB_DEBUG ··· 153 152 else \ 154 153 _sdata_err((link)->sdata, fmt, ##__VA_ARGS__); \ 155 154 } while (0) 155 + #define link_err_once(link, fmt, ...) \ 156 + DO_ONCE_LITE(link_err, link, fmt, ##__VA_ARGS__) 156 157 #define link_id_info(sdata, link_id, fmt, ...) \ 157 158 do { \ 158 159 if (ieee80211_vif_is_mld(&sdata->vif)) \
+21 -8
net/mac80211/tx.c
··· 5 5 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> 6 6 * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> 7 7 * Copyright 2013-2014 Intel Mobile Communications GmbH 8 - * Copyright (C) 2018-2024 Intel Corporation 8 + * Copyright (C) 2018-2025 Intel Corporation 9 9 * 10 10 * Transmit and frame generation functions. 11 11 */ ··· 5016 5016 } 5017 5017 } 5018 5018 5019 - static u8 __ieee80211_beacon_update_cntdwn(struct beacon_data *beacon) 5019 + static u8 __ieee80211_beacon_update_cntdwn(struct ieee80211_link_data *link, 5020 + struct beacon_data *beacon) 5020 5021 { 5021 - beacon->cntdwn_current_counter--; 5022 + if (beacon->cntdwn_current_counter == 1) { 5023 + /* 5024 + * Channel switch handling is done by a worker thread while 5025 + * beacons get pulled from hardware timers. It's therefore 5026 + * possible that software threads are slow enough to not be 5027 + * able to complete CSA handling in a single beacon interval, 5028 + * in which case we get here. There isn't much to do about 5029 + * it, other than letting the user know that the AP isn't 5030 + * behaving correctly. 5031 + */ 5032 + link_err_once(link, 5033 + "beacon TX faster than countdown (channel/color switch) completion\n"); 5034 + return 0; 5035 + } 5022 5036 5023 - /* the counter should never reach 0 */ 5024 - WARN_ON_ONCE(!beacon->cntdwn_current_counter); 5037 + beacon->cntdwn_current_counter--; 5025 5038 5026 5039 return beacon->cntdwn_current_counter; 5027 5040 } ··· 5065 5052 if (!beacon) 5066 5053 goto unlock; 5067 5054 5068 - count = __ieee80211_beacon_update_cntdwn(beacon); 5055 + count = __ieee80211_beacon_update_cntdwn(link, beacon); 5069 5056 5070 5057 unlock: 5071 5058 rcu_read_unlock(); ··· 5463 5450 5464 5451 if (beacon->cntdwn_counter_offsets[0]) { 5465 5452 if (!is_template) 5466 - __ieee80211_beacon_update_cntdwn(beacon); 5453 + __ieee80211_beacon_update_cntdwn(link, beacon); 5467 5454 5468 5455 ieee80211_set_beacon_cntdwn(sdata, beacon, link); 5469 5456 } ··· 5495 5482 * for now we leave it consistent with overall 5496 5483 * mac80211's behavior. 5497 5484 */ 5498 - __ieee80211_beacon_update_cntdwn(beacon); 5485 + __ieee80211_beacon_update_cntdwn(link, beacon); 5499 5486 5500 5487 ieee80211_set_beacon_cntdwn(sdata, beacon, link); 5501 5488 }