linux/drivers
Fabio Aiuto 3a53d9ad9b staging: rtl8723bs: remove possible deadlock when disconnect (v2)
[ Upstream commit 54659ca026 ]

when turning off a connection, lockdep complains with the
following warning (a modprobe has been done but the same
happens with a disconnection from NetworkManager,
it's enough to trigger a cfg80211_disconnect call):

[  682.855867] ======================================================
[  682.855877] WARNING: possible circular locking dependency detected
[  682.855887] 5.14.0-rc6+ #16 Tainted: G         C OE
[  682.855898] ------------------------------------------------------
[  682.855906] modprobe/1770 is trying to acquire lock:
[  682.855916] ffffb6d000332b00 (&pxmitpriv->lock){+.-.}-{2:2},
		at: rtw_free_stainfo+0x52/0x4a0 [r8723bs]
[  682.856073]
               but task is already holding lock:
[  682.856081] ffffb6d0003336a8 (&pstapriv->sta_hash_lock){+.-.}-{2:2},
		at: rtw_free_assoc_resources+0x48/0x110 [r8723bs]
[  682.856207]
               which lock already depends on the new lock.

[  682.856215]
               the existing dependency chain (in reverse order) is:
[  682.856223]
               -> #1 (&pstapriv->sta_hash_lock){+.-.}-{2:2}:
[  682.856247]        _raw_spin_lock_bh+0x34/0x40
[  682.856265]        rtw_get_stainfo+0x9a/0x110 [r8723bs]
[  682.856389]        rtw_xmit_classifier+0x27/0x130 [r8723bs]
[  682.856515]        rtw_xmitframe_enqueue+0xa/0x20 [r8723bs]
[  682.856642]        rtl8723bs_hal_xmit+0x3b/0xb0 [r8723bs]
[  682.856752]        rtw_xmit+0x4ef/0x890 [r8723bs]
[  682.856879]        _rtw_xmit_entry+0xba/0x350 [r8723bs]
[  682.856981]        dev_hard_start_xmit+0xee/0x320
[  682.856999]        sch_direct_xmit+0x8c/0x330
[  682.857014]        __dev_queue_xmit+0xba5/0xf00
[  682.857030]        packet_sendmsg+0x981/0x1b80
[  682.857047]        sock_sendmsg+0x5b/0x60
[  682.857060]        __sys_sendto+0xf1/0x160
[  682.857073]        __x64_sys_sendto+0x24/0x30
[  682.857087]        do_syscall_64+0x3a/0x80
[  682.857102]        entry_SYSCALL_64_after_hwframe+0x44/0xae
[  682.857117]
               -> #0 (&pxmitpriv->lock){+.-.}-{2:2}:
[  682.857142]        __lock_acquire+0xfd9/0x1b50
[  682.857158]        lock_acquire+0xb4/0x2c0
[  682.857172]        _raw_spin_lock_bh+0x34/0x40
[  682.857185]        rtw_free_stainfo+0x52/0x4a0 [r8723bs]
[  682.857308]        rtw_free_assoc_resources+0x53/0x110 [r8723bs]
[  682.857415]        cfg80211_rtw_disconnect+0x4b/0x70 [r8723bs]
[  682.857522]        cfg80211_disconnect+0x12e/0x2f0 [cfg80211]
[  682.857759]        cfg80211_leave+0x2b/0x40 [cfg80211]
[  682.857961]        cfg80211_netdev_notifier_call+0xa9/0x560 [cfg80211]
[  682.858163]        raw_notifier_call_chain+0x41/0x50
[  682.858180]        __dev_close_many+0x62/0x100
[  682.858195]        dev_close_many+0x7d/0x120
[  682.858209]        unregister_netdevice_many+0x416/0x680
[  682.858225]        unregister_netdevice_queue+0xab/0xf0
[  682.858240]        unregister_netdev+0x18/0x20
[  682.858255]        rtw_unregister_netdevs+0x28/0x40 [r8723bs]
[  682.858360]        rtw_dev_remove+0x24/0xd0 [r8723bs]
[  682.858463]        sdio_bus_remove+0x31/0xd0 [mmc_core]
[  682.858532]        device_release_driver_internal+0xf7/0x1d0
[  682.858550]        driver_detach+0x47/0x90
[  682.858564]        bus_remove_driver+0x77/0xd0
[  682.858579]        rtw_drv_halt+0xc/0x678 [r8723bs]
[  682.858685]        __x64_sys_delete_module+0x13f/0x250
[  682.858699]        do_syscall_64+0x3a/0x80
[  682.858715]        entry_SYSCALL_64_after_hwframe+0x44/0xae
[  682.858729]
               other info that might help us debug this:

[  682.858737]  Possible unsafe locking scenario:

[  682.858744]        CPU0                    CPU1
[  682.858751]        ----                    ----
[  682.858758]   lock(&pstapriv->sta_hash_lock);
[  682.858772]                                lock(&pxmitpriv->lock);
[  682.858786]                                lock(&pstapriv->sta_hash_lock);
[  682.858799]   lock(&pxmitpriv->lock);
[  682.858812]
                *** DEADLOCK ***

[  682.858820] 5 locks held by modprobe/1770:
[  682.858831]  #0: ffff8d870697d980 (&dev->mutex){....}-{3:3},
		at: device_release_driver_internal+0x1a/0x1d0
[  682.858869]  #1: ffffffffbdbbf1c8 (rtnl_mutex){+.+.}-{3:3},
		at: unregister_netdev+0xe/0x20
[  682.858906]  #2: ffff8d87054ee5e8 (&rdev->wiphy.mtx){+.+.}-{3:3},
		at: cfg80211_netdev_notifier_call+0x9e/0x560 [cfg80211]
[  682.859131]  #3: ffff8d870f2bc8f0 (&wdev->mtx){+.+.}-{3:3},
		at: cfg80211_leave+0x20/0x40 [cfg80211]
[  682.859354]  #4: ffffb6d0003336a8 (&pstapriv->sta_hash_lock){+.-.}-{2:2},
		at: rtw_free_assoc_resources+0x48/0x110 [r8723bs]
[  682.859482]
               stack backtrace:
[  682.859491] CPU: 1 PID: 1770 Comm: modprobe Tainted: G
		C OE     5.14.0-rc6+ #16
[  682.859507] Hardware name: LENOVO 80NR/Madrid, BIOS DACN25WW 08/20/2015
[  682.859517] Call Trace:
[  682.859531]  dump_stack_lvl+0x56/0x6f
[  682.859551]  check_noncircular+0xdb/0xf0
[  682.859579]  __lock_acquire+0xfd9/0x1b50
[  682.859606]  lock_acquire+0xb4/0x2c0
[  682.859623]  ? rtw_free_stainfo+0x52/0x4a0 [r8723bs]
[  682.859752]  ? mark_held_locks+0x48/0x70
[  682.859769]  ? rtw_free_stainfo+0x4a/0x4a0 [r8723bs]
[  682.859898]  _raw_spin_lock_bh+0x34/0x40
[  682.859914]  ? rtw_free_stainfo+0x52/0x4a0 [r8723bs]
[  682.860039]  rtw_free_stainfo+0x52/0x4a0 [r8723bs]
[  682.860171]  rtw_free_assoc_resources+0x53/0x110 [r8723bs]
[  682.860286]  cfg80211_rtw_disconnect+0x4b/0x70 [r8723bs]
[  682.860397]  cfg80211_disconnect+0x12e/0x2f0 [cfg80211]
[  682.860629]  cfg80211_leave+0x2b/0x40 [cfg80211]
[  682.860836]  cfg80211_netdev_notifier_call+0xa9/0x560 [cfg80211]
[  682.861048]  ? __lock_acquire+0x4dc/0x1b50
[  682.861070]  ? lock_is_held_type+0xa8/0x110
[  682.861089]  ? lock_is_held_type+0xa8/0x110
[  682.861104]  ? find_held_lock+0x2d/0x90
[  682.861120]  ? packet_notifier+0x173/0x300
[  682.861141]  ? lock_release+0xb3/0x250
[  682.861160]  ? packet_notifier+0x192/0x300
[  682.861184]  raw_notifier_call_chain+0x41/0x50
[  682.861205]  __dev_close_many+0x62/0x100
[  682.861224]  dev_close_many+0x7d/0x120
[  682.861245]  unregister_netdevice_many+0x416/0x680
[  682.861264]  ? find_held_lock+0x2d/0x90
[  682.861284]  unregister_netdevice_queue+0xab/0xf0
[  682.861306]  unregister_netdev+0x18/0x20
[  682.861325]  rtw_unregister_netdevs+0x28/0x40 [r8723bs]
[  682.861434]  rtw_dev_remove+0x24/0xd0 [r8723bs]
[  682.861542]  sdio_bus_remove+0x31/0xd0 [mmc_core]
[  682.861615]  device_release_driver_internal+0xf7/0x1d0
[  682.861637]  driver_detach+0x47/0x90
[  682.861656]  bus_remove_driver+0x77/0xd0
[  682.861674]  rtw_drv_halt+0xc/0x678 [r8723bs]
[  682.861782]  __x64_sys_delete_module+0x13f/0x250
[  682.861801]  ? lockdep_hardirqs_on_prepare+0xf3/0x170
[  682.861817]  ? syscall_enter_from_user_mode+0x20/0x70
[  682.861836]  do_syscall_64+0x3a/0x80
[  682.861855]  entry_SYSCALL_64_after_hwframe+0x44/0xae
[  682.861873] RIP: 0033:0x7f6dbe85400b
[  682.861890] Code: 73 01 c3 48 8b 0d 6d 1e 0c 00 f7 d8 64 89
01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa
b8 b0 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 3d
1e 0c 00 f7 d8 64 89 01 48
[  682.861906] RSP: 002b:00007ffe7a82f538 EFLAGS: 00000206 ORIG_RAX: 00000000000000b0
[  682.861923] RAX: ffffffffffffffda RBX: 000055a64693bd20 RCX: 00007f6dbe85400b
[  682.861935] RDX: 0000000000000000 RSI: 0000000000000800 RDI: 000055a64693bd88
[  682.861946] RBP: 000055a64693bd20 R08: 0000000000000000 R09: 0000000000000000
[  682.861957] R10: 00007f6dbe8c7ac0 R11: 0000000000000206 R12: 000055a64693bd88
[  682.861967] R13: 0000000000000000 R14: 000055a64693bd88 R15: 00007ffe7a831848

This happens because when we enqueue a frame for
transmission we do it under xmit_priv lock, then calling
rtw_get_stainfo (needed for enqueuing) takes sta_hash_lock
and this leads to the following lock dependency:

xmit_priv->lock -> sta_hash_lock

Turning off a connection will bring to call
rtw_free_assoc_resources which will set up
the inverse dependency:

sta_hash_lock -> xmit_priv_lock

This could lead to a deadlock as lockdep complains.

Fix it by removing the xmit_priv->lock around
rtw_xmitframe_enqueue call inside rtl8723bs_hal_xmit
and put it in a smaller critical section inside
rtw_xmit_classifier, the only place where
xmit_priv data are actually accessed.

Replace spin_{lock,unlock}_bh(pxmitpriv->lock)
in other tx paths leading to rtw_xmitframe_enqueue
call with spin_{lock,unlock}_bh(psta->sleep_q.lock)
- it's not clear why accessing a sleep_q was protected
by a spinlock on xmitpriv->lock.

This way is avoided the same faulty lock nesting
order.

Extra changes in v2 by Hans de Goede:
-Lift the taking of the struct __queue.lock spinlock out of
 rtw_free_xmitframe_queue() into the callers this allows also
 protecting a bunch of related state in rtw_free_stainfo():
-Protect psta->sleepq_len on rtw_free_xmitframe_queue(&psta->sleep_q);
-Protect struct tx_servq.tx_pending and tx_servq.qcnt when
 calling rtw_free_xmitframe_queue(&tx_servq.sta_pending)
-This also allows moving the spin_lock_bh(&pxmitpriv->lock); to below
 the sleep_q free-ing code, avoiding another ABBA locking issue

CC: Larry Finger <Larry.Finger@lwfinger.net>
Co-developed-by: Hans de Goede <hdegoede@redhat.com>
Tested-on: Lenovo Ideapad MiiX 300-10IBY
Signed-off-by: Fabio Aiuto <fabioaiuto83@gmail.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20210920145502.155454-1-hdegoede@redhat.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2021-11-26 10:39:09 +01:00
..
accessibility
acpi ACPI: PMIC: Fix intel_pmic_regs_handler() read accesses 2021-11-18 14:04:26 +01:00
amba ARM: 9120/1: Revert "amba: make use of -1 IRQs warn" 2021-11-06 14:10:09 +01:00
android binder: use cred instead of task for getsecid 2021-11-18 14:03:36 +01:00
ata libata: fix checking of DMA state 2021-11-18 14:03:46 +01:00
atm
auxdisplay auxdisplay: ht16k33: Fix frame buffer device blanking 2021-11-18 14:04:24 +01:00
base driver core: Fix possible memory leak in device_link_add() 2021-11-18 14:04:16 +01:00
bcma bcma: Fix memory leak for internally-handled cores 2021-09-15 09:50:45 +02:00
block loop: Use blk_validate_block_size() to validate block size 2021-11-21 13:46:35 +01:00
bluetooth Bluetooth: btmtkuart: fix a memleak in mtk_hci_wmt_sync 2021-11-18 14:04:03 +01:00
bus bus: ti-sysc: Use context lost quirk for otg 2021-11-26 10:39:08 +01:00
cdrom
char tpm_tis_spi: Add missing SPI ID 2021-11-18 14:04:11 +01:00
clk clk: at91: sam9x60-pll: use DIV_ROUND_CLOSEST_ULL 2021-11-18 14:04:21 +01:00
clocksource clocksource/drivers/timer-ti-dm: Select TIMER_OF 2021-11-18 14:04:09 +01:00
connector
counter counter: 104-quad-8: Return error when invalid mode during ceiling_write 2021-09-15 09:50:38 +02:00
cpufreq cpufreq: schedutil: Destroy mutex before kobject_put() frees the memory 2021-10-06 15:55:46 +02:00
cpuidle cpuidle: Fix kobject memory leaks in error paths 2021-11-18 14:04:05 +01:00
crypto crypto: qat - disregard spurious PFVF interrupts 2021-11-18 14:04:06 +01:00
dax
dca
devfreq
dio
dma dmaengine: dmaengine_desc_callback_valid(): Check for callback_result 2021-11-18 14:04:24 +01:00
dma-buf dma-buf: WARN on dmabuf release with pending attachments 2021-11-18 14:03:52 +01:00
edac EDAC/amd64: Handle three rank interleaving mode 2021-11-18 14:04:06 +01:00
eisa
extcon
firewire
firmware firmware: qcom_scm: Fix error retval in __qcom_scm_is_call_available() 2021-11-18 14:04:20 +01:00
fpga fpga: machxo2-spi: Fix missing error code in machxo2_write_complete() 2021-09-30 10:11:04 +02:00
fsi
gnss
gpio gpio: mlxbf2.c: Add check for bgpio_init failure 2021-11-18 14:03:42 +01:00
gpu drm/sun4i: Fix macros in sun8i_csc.h 2021-11-18 14:04:32 +01:00
greybus
hid HID: u2fzero: properly handle timeouts in usb_submit_urb 2021-11-18 14:04:21 +01:00
hsi
hv hyperv/vmbus: include linux/bitops.h 2021-11-18 14:03:42 +01:00
hwmon hwmon: (pmbus/lm25066) Let compiler determine outer dimension of lm25066_coeff 2021-11-18 14:04:07 +01:00
hwspinlock
hwtracing coresight: cti: Correct the parameter for pm_runtime_put 2021-11-18 14:03:51 +01:00
i2c i2c: xlr: Fix a resource leak in the error handling path of 'xlr_i2c_probe()' 2021-11-18 14:04:25 +01:00
i3c
ide
idle
iio iio: adis: do not disabe IRQs in 'adis_init()' 2021-11-18 14:04:19 +01:00
infiniband RDMA/bnxt_re: Check if the vlan is valid before reporting 2021-11-26 10:39:08 +01:00
input Input: i8042 - Add quirk for Fujitsu Lifebook T725 2021-11-18 14:03:36 +01:00
interconnect treewide: Change list_sort to use const pointers 2021-09-30 10:11:04 +02:00
iommu iommu/amd: Relocate GAMSup check to early_enable_iommus 2021-09-26 14:08:59 +02:00
ipack ipack: ipoctal: fix module reference leak 2021-10-06 15:56:01 +02:00
irqchip irqchip/sifive-plic: Fixup EOI failed when masked 2021-11-18 14:04:29 +01:00
isdn mISDN: Fix return values of the probe function 2021-11-18 14:03:41 +01:00
leds leds: trigger: audio: Add an activate callback to ensure the initial brightness is set 2021-09-15 09:50:36 +02:00
lightnvm
macintosh
mailbox soc: mediatek: cmdq: add address shift in jump 2021-09-18 13:40:16 +02:00
mcb mcb: fix error handling in mcb_alloc_bus() 2021-09-30 10:11:00 +02:00
md md: update superblock after changing rdev flags in state_store 2021-11-18 14:03:57 +01:00
media media: ir_toy: assignment to be16 should be of correct type 2021-11-18 14:04:08 +01:00
memory memory: fsl_ifc: fix leak of irq and nand_irq in fsl_ifc_ctrl_probe 2021-11-18 14:04:16 +01:00
memstick memstick: jmb38x_ms: use appropriate free function in jmb38x_ms_alloc_host() 2021-11-18 14:04:07 +01:00
message
mfd mfd: dln2: Add cell for initializing DLN2 ADC 2021-11-18 14:04:30 +01:00
misc misc: fastrpc: Add missing lock before accessing find_vma() 2021-10-20 11:45:01 +02:00
mmc mmc: moxart: Fix null pointer dereference on pointer host 2021-11-18 14:04:32 +01:00
most most: fix control-message timeouts 2021-11-18 14:03:51 +01:00
mtd mtd: rawnand: au1550nd: Keep the driver compatible with on-die ECC engines 2021-11-18 14:04:31 +01:00
mux
net net: stmmac: dwmac-rk: fix unbalanced pm_runtime_enable warnings 2021-11-21 13:46:36 +01:00
nfc nfc: pn533: Fix double free when pn533_fill_fragment_skbs() fails 2021-11-18 14:04:27 +01:00
ntb NTB: perf: Fix an error code in perf_setup_inbuf() 2021-09-22 12:28:02 +02:00
nubus
nvdimm libnvdimm/pmem: Fix crash triggered when I/O in-flight during unbind 2021-09-18 13:40:36 +02:00
nvme nvme-rdma: fix error code in nvme_rdma_setup_ctrl 2021-11-18 14:04:09 +01:00
nvmem nvmem: Fix shift-out-of-bound (UBSAN) with byte size cells 2021-10-20 11:45:01 +02:00
of of: unittest: fix EXPECT text for gpio hog errors 2021-11-18 14:04:13 +01:00
opp opp: Fix return in _opp_add_static_v2() 2021-11-18 14:04:22 +01:00
oprofile
parisc parisc: Move pci_dev_is_behind_card_dino to where it is used 2021-09-26 14:08:59 +02:00
parport parport: remove non-zero check on count 2021-09-18 13:40:34 +02:00
pci PCI: Add MSI masking quirk for Nvidia ION AHCI 2021-11-21 13:46:37 +01:00
pcmcia pcmcia: i82092: fix a null pointer dereference bug 2021-08-12 13:22:16 +02:00
perf
phy phy: qcom-snps: Correct the FSEL_MASK 2021-11-18 14:04:20 +01:00
pinctrl pinctrl: equilibrium: Fix function addition in multiple groups 2021-11-18 14:04:20 +01:00
platform platform/x86: thinkpad_acpi: Fix bitwise vs. logical warning 2021-11-18 14:04:08 +01:00
pnp
power power: supply: bq27xxx: Fix kernel crash on IRQ handler register error 2021-11-18 14:04:21 +01:00
powercap
pps
ps3
ptp ptp_pch: Load module automatically if ID matches 2021-10-13 10:04:27 +02:00
pwm pwm: stm32-lp: Don't modify HW state in .remove() callback 2021-09-26 14:09:01 +02:00
rapidio
ras
regulator regulator: s5m8767: do not use reset value as DVS voltage if GPIO DVS is disabled 2021-11-18 14:03:45 +01:00
remoteproc remoteproc: Fix a memory leak in an error handling path in 'rproc_handle_vdev()' 2021-11-18 14:04:23 +01:00
reset reset: socfpga: add empty driver allowing consumers to probe 2021-11-18 14:03:42 +01:00
rpmsg
rtc rtc: rv3032: fix error handling in rv3032_clkout_set_rate() 2021-11-18 14:04:23 +01:00
s390 s390/cio: make ccw_device_dma_* more robust 2021-11-18 14:04:30 +01:00
sbus
scsi scsi: lpfc: Fix list_add() corruption in lpfc_drain_txq() 2021-11-26 10:39:08 +01:00
sfi
sh
siox
slimbus slimbus: ngd: reset dma setup during runtime pm 2021-08-26 08:35:55 -04:00
soc soc/tegra: pmc: Fix imbalanced clock disabling in error code path 2021-11-18 14:04:33 +01:00
soundwire soundwire: debugfs: use controller id and link_id for debugfs 2021-11-18 14:04:16 +01:00
spi spi: spi-rpc-if: Check return value of rpcif_sw_init() 2021-11-18 14:04:11 +01:00
spmi
ssb
staging staging: rtl8723bs: remove possible deadlock when disconnect (v2) 2021-11-26 10:39:09 +01:00
target scsi: target: Fix the pgr/alua_support_store functions 2021-09-30 10:11:03 +02:00
tc
tee tee: optee: Fix missing devices unregister during optee_remove 2021-10-20 11:45:02 +02:00
thermal thermal: Fix NULL pointer dereferences in of_thermal_ functions 2021-11-21 13:46:37 +01:00
thunderbolt thunderbolt: Fix port linking by checking all adapters 2021-09-18 13:40:27 +02:00
tty serial: xilinx_uartps: Fix race condition causing stuck TX 2021-11-18 14:04:20 +01:00
uio
usb usb: typec: tipd: Remove WARN_ON in tps6598x_block_read 2021-11-26 10:39:09 +01:00
vdpa vdpa/mlx5: Avoid destroying MR on empty iotlb 2021-08-26 08:35:42 -04:00
vfio vfio: Use config not menuconfig for VFIO_NOIOMMU 2021-09-18 13:40:12 +02:00
vhost vhost-vdpa: Fix the wrong input in config_cb 2021-10-20 11:45:04 +02:00
video video: backlight: Drop maximum brightness override for brightness zero 2021-11-18 14:04:30 +01:00
virt
virtio virtio_ring: check desc == NULL when using indirect with packed 2021-11-18 14:04:21 +01:00
visorbus
vlynq
vme
w1
watchdog ar7: fix kernel builds for compiler test 2021-11-18 14:04:24 +01:00
xen xen-pciback: Fix return in pm_ctrl_init() 2021-11-18 14:04:25 +01:00
zorro
Kconfig
Makefile