wifi: mac80211: Convert color collision detection to wiphy work
BugLink: https://bugs.launchpad.net/bugs/2101915 [ Upstream commit 4cc6f3e5e5765abad9c091989970d67d8c1d2204 ] Call to ieee80211_color_collision_detection_work() needs wiphy lock to be held (see lockdep assert in cfg80211_bss_color_notify()). Not locking wiphy causes the following lockdep error: WARNING: CPU: 2 PID: 42 at net/wireless/nl80211.c:19505 cfg80211_bss_color_notify+0x1a4/0x25c Modules linked in: CPU: 2 PID: 42 Comm: kworker/u8:3 Tainted: G W 6.4.0-02327-g36c6cb260481 #1048 Hardware name: Workqueue: phy1 ieee80211_color_collision_detection_work pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : cfg80211_bss_color_notify+0x1a4/0x25c lr : cfg80211_bss_color_notify+0x1a0/0x25c sp : ffff000002947d00 x29: ffff000002947d00 x28: ffff800008e1a000 x27: ffff000002bd4705 x26: ffff00000d034000 x25: ffff80000903cf40 x24: 0000000000000000 x23: ffff00000cb70720 x22: 0000000000800000 x21: ffff800008dfb008 x20: 000000000000008d x19: ffff00000d035fa8 x18: 0000000000000010 x17: 0000000000000001 x16: 000003564b1ce96a x15: 000d69696d057970 x14: 000000000000003b x13: 0000000000000001 x12: 0000000000040000 x11: 0000000000000001 x10: ffff80000978f9c0 x9 : ffff0000028d3174 x8 : ffff800008e30000 x7 : 0000000000000000 x6 : 0000000000000028 x5 : 000000000002f498 x4 : ffff00000d034a80 x3 : 0000000000800000 x2 : ffff800016143000 x1 : 0000000000000000 x0 : 0000000000000000 Call trace: cfg80211_bss_color_notify+0x1a4/0x25c ieee80211_color_collision_detection_work+0x20/0x118 process_one_work+0x294/0x554 worker_thread+0x70/0x440 kthread+0xf4/0xf8 ret_from_fork+0x10/0x20 irq event stamp: 77372 hardirqs last enabled at (77371): [<ffff800008a346fc>] _raw_spin_unlock_irq+0x2c/0x4c hardirqs last disabled at (77372): [<ffff800008a28754>] el1_dbg+0x20/0x48 softirqs last enabled at (77350): [<ffff8000089e120c>] batadv_send_outstanding_bcast_packet+0xb8/0x120 softirqs last disabled at (77348): [<ffff8000089e11d4>] batadv_send_outstanding_bcast_packet+0x80/0x120 The wiphy lock cannot be taken directly from color collision detection delayed work (ieee80211_color_collision_detection_work()) because this work is cancel_delayed_work_sync() under this wiphy lock causing a potential deadlock( see [0] for details). To fix that ieee80211_color_collision_detection_work() could be converted to a wiphy work and cancel_delayed_work_sync() can be simply replaced by wiphy_delayed_work_cancel() serving the same purpose under wiphy lock. This could potentially fix [1]. [0]: https://lore.kernel.org/linux-wireless/D4A40Q44OAY2.W3SIF6UEPBUN@freebox.fr/ [1]: https://lore.kernel.org/lkml/000000000000612f290618eee3e5@google.com/ Reported-by: Nicolas Escande <nescande@freebox.fr> Signed-off-by: Remi Pommarel <repk@triplefau.lt> Link: https://patch.msgid.link/20240924192805.13859-3-repk@triplefau.lt Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org> [koichiroden: adjusted context due to missing commits: 7cd445635562 ("wifi: mac80211: cancel color change finalize work when link is stopped") 414e736c3db0 ("wifi: mac80211: handle color change per link") 1a96bb4e8a79 ("wifi: mac80211: start and finalize channel switch on link basis")] Signed-off-by: Koichiro Den <koichiro.den@canonical.com> Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
This commit is contained in:
committed by
Stefan Bader
parent
63b89396e5
commit
e21817b227
+9
-8
@@ -4728,12 +4728,12 @@ void ieee80211_color_change_finalize_work(struct wiphy *wiphy,
|
||||
ieee80211_color_change_finalize(sdata);
|
||||
}
|
||||
|
||||
void ieee80211_color_collision_detection_work(struct work_struct *work)
|
||||
void ieee80211_color_collision_detection_work(struct wiphy *wiphy,
|
||||
struct wiphy_work *work)
|
||||
{
|
||||
struct delayed_work *delayed_work = to_delayed_work(work);
|
||||
struct ieee80211_link_data *link =
|
||||
container_of(delayed_work, struct ieee80211_link_data,
|
||||
color_collision_detect_work);
|
||||
container_of(work, struct ieee80211_link_data,
|
||||
color_collision_detect_work.work);
|
||||
struct ieee80211_sub_if_data *sdata = link->sdata;
|
||||
|
||||
cfg80211_obss_color_collision_notify(sdata->dev, link->color_bitmap);
|
||||
@@ -4758,16 +4758,17 @@ ieee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
|
||||
if (sdata->vif.bss_conf.color_change_active || sdata->vif.bss_conf.csa_active)
|
||||
return;
|
||||
|
||||
if (delayed_work_pending(&link->color_collision_detect_work))
|
||||
if (wiphy_delayed_work_pending(sdata->local->hw.wiphy,
|
||||
&link->color_collision_detect_work))
|
||||
return;
|
||||
|
||||
link->color_bitmap = color_bitmap;
|
||||
/* queue the color collision detection event every 500 ms in order to
|
||||
* avoid sending too much netlink messages to userspace.
|
||||
*/
|
||||
ieee80211_queue_delayed_work(&sdata->local->hw,
|
||||
&link->color_collision_detect_work,
|
||||
msecs_to_jiffies(500));
|
||||
wiphy_delayed_work_queue(sdata->local->hw.wiphy,
|
||||
&link->color_collision_detect_work,
|
||||
msecs_to_jiffies(500));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ieee80211_obss_color_collision_notify);
|
||||
|
||||
|
||||
@@ -1020,7 +1020,7 @@ struct ieee80211_link_data {
|
||||
struct cfg80211_chan_def csa_chandef;
|
||||
|
||||
struct wiphy_work color_change_finalize_work;
|
||||
struct delayed_work color_collision_detect_work;
|
||||
struct wiphy_delayed_work color_collision_detect_work;
|
||||
u64 color_bitmap;
|
||||
|
||||
/* context reservation -- protected with wiphy mutex */
|
||||
@@ -1957,7 +1957,8 @@ int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
|
||||
/* color change handling */
|
||||
void ieee80211_color_change_finalize_work(struct wiphy *wiphy,
|
||||
struct wiphy_work *work);
|
||||
void ieee80211_color_collision_detection_work(struct work_struct *work);
|
||||
void ieee80211_color_collision_detection_work(struct wiphy *wiphy,
|
||||
struct wiphy_work *work);
|
||||
|
||||
/* interface handling */
|
||||
#define MAC80211_SUPPORTED_FEATURES_TX (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \
|
||||
|
||||
+4
-3
@@ -41,8 +41,8 @@ void ieee80211_link_init(struct ieee80211_sub_if_data *sdata,
|
||||
ieee80211_csa_finalize_work);
|
||||
wiphy_work_init(&link->color_change_finalize_work,
|
||||
ieee80211_color_change_finalize_work);
|
||||
INIT_DELAYED_WORK(&link->color_collision_detect_work,
|
||||
ieee80211_color_collision_detection_work);
|
||||
wiphy_delayed_work_init(&link->color_collision_detect_work,
|
||||
ieee80211_color_collision_detection_work);
|
||||
INIT_LIST_HEAD(&link->assigned_chanctx_list);
|
||||
INIT_LIST_HEAD(&link->reserved_chanctx_list);
|
||||
wiphy_delayed_work_init(&link->dfs_cac_timer_work,
|
||||
@@ -72,7 +72,8 @@ void ieee80211_link_stop(struct ieee80211_link_data *link)
|
||||
if (link->sdata->vif.type == NL80211_IFTYPE_STATION)
|
||||
ieee80211_mgd_stop_link(link);
|
||||
|
||||
cancel_delayed_work_sync(&link->color_collision_detect_work);
|
||||
wiphy_delayed_work_cancel(link->sdata->local->hw.wiphy,
|
||||
&link->color_collision_detect_work);
|
||||
ieee80211_link_release_channel(link);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user