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/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>