|
|
@@ -0,0 +1,148 @@
|
|
|
+From: Remi Pommarel <[email protected]>
|
|
|
+Date: Tue, 24 Sep 2024 21:28:05 +0200
|
|
|
+Subject: [PATCH] wifi: mac80211: Convert color collision detection to wiphy
|
|
|
+ work
|
|
|
+
|
|
|
+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/[email protected]/
|
|
|
+[1]: https://lore.kernel.org/lkml/[email protected]/
|
|
|
+
|
|
|
+Reported-by: Nicolas Escande <[email protected]>
|
|
|
+Signed-off-by: Remi Pommarel <[email protected]>
|
|
|
+Link: https://patch.msgid.link/[email protected]
|
|
|
+Signed-off-by: Johannes Berg <[email protected]>
|
|
|
+---
|
|
|
+
|
|
|
+--- a/net/mac80211/cfg.c
|
|
|
++++ b/net/mac80211/cfg.c
|
|
|
+@@ -4836,12 +4836,12 @@ void ieee80211_color_change_finalize_wor
|
|
|
+ ieee80211_color_change_finalize(link);
|
|
|
+ }
|
|
|
+
|
|
|
+-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,
|
|
|
+@@ -4894,7 +4894,8 @@ ieee80211_obss_color_collision_notify(st
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+- if (delayed_work_pending(&link->color_collision_detect_work)) {
|
|
|
++ if (wiphy_delayed_work_pending(sdata->local->hw.wiphy,
|
|
|
++ &link->color_collision_detect_work)) {
|
|
|
+ rcu_read_unlock();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+@@ -4903,9 +4904,9 @@ ieee80211_obss_color_collision_notify(st
|
|
|
+ /* 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));
|
|
|
+
|
|
|
+ rcu_read_unlock();
|
|
|
+ }
|
|
|
+--- a/net/mac80211/ieee80211_i.h
|
|
|
++++ b/net/mac80211/ieee80211_i.h
|
|
|
+@@ -1056,7 +1056,7 @@ struct ieee80211_link_data {
|
|
|
+ } csa;
|
|
|
+
|
|
|
+ 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 */
|
|
|
+@@ -2010,7 +2010,8 @@ int ieee80211_channel_switch(struct wiph
|
|
|
+ /* 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 | \
|
|
|
+--- a/net/mac80211/link.c
|
|
|
++++ b/net/mac80211/link.c
|
|
|
+@@ -41,8 +41,8 @@ void ieee80211_link_init(struct ieee8021
|
|
|
+ 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 ieee8021
|
|
|
+ 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);
|
|
|
+ wiphy_work_cancel(link->sdata->local->hw.wiphy,
|
|
|
+ &link->color_change_finalize_work);
|
|
|
+ wiphy_work_cancel(link->sdata->local->hw.wiphy,
|