mirror-linux/arch
Benjamin Block 4cb92fa763 s390/pci: Fix cyclic dead-lock in zpci_zdev_put() and zpci_scan_devices()
When triggering PCI device recovery by writing into the SysFS attribute
`recover` of a Physical Function with existing child SR-IOV Virtual
Functions, lockdep is reporting a possible deadlock between three
threads:

         Thread (A)             Thread (B)             Thread (C)
             |                      |                      |
      recover_store()      zpci_scan_devices()    zpci_scan_devices()
lock(pci_rescan_remove_lock)        |                      |
             |                      |                      |
             |                      |            zpci_bus_scan_busses()
             |                      |             lock(zbus_list_lock)
             |              zpci_add_device()              |
             |          lock(zpci_add_remove_lock)         |
             |                      |                      ┴
             |                      |             zpci_bus_scan_bus()
             |                      |         lock(pci_rescan_remove_lock)
             ┴                      |
      zpci_zdev_put()               |
 lock(zpci_add_remove_lock)         |
                                    ┴
                              zpci_bus_get()
                           lock(zbus_list_lock)

In zpci_bus_scan_busses() the `zbus_list_lock` is taken for the whole
duration of the function, which also includes taking
`pci_rescan_remove_lock`, among other things. But `zbus_list_lock` only
really needs to protect the modification of the global registration
`zbus_list`, it can be dropped while the functions within the list
iteration run; this way we break the cycle above.

Break up zpci_bus_scan_busses() into an "iterator" zpci_bus_get_next()
that iterates over `zbus_list` element by element, and acquires and
releases `zbus_list_lock` as necessary, but never keep holding it.
References to `zpci_bus` objects are also acquired and released.

The reference counting on `zpci_bus` objects is also changed so that all
put() and get() operations are done under the protection of
`zbus_list_lock`, and if the operation results in a modification of
`zpci_bus_list`, this modification is done in the same critical section
(apart the very first initialization). This way objects are never seen
on the list that are about to be released and/or half-initialized.

Fixes: 14c87ba812 ("s390/pci: separate zbus registration from scanning")
Suggested-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com>
Reviewed-by: Gerd Bayer <gbayer@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
2025-12-14 11:03:58 +01:00
..
alpha alpha updates for v6.19 2025-12-11 08:01:52 +09:00
arc
arm sound fixes for 6.19-rc1 2025-12-13 16:09:10 +12:00
arm64 crypto: arm64/ghash - Fix incorrect output from ghash-neon 2025-12-10 09:46:26 -08:00
csky csky 6.19 Release Notes 2025-12-10 12:17:29 +09:00
hexagon This update includes the following changes: 2025-12-03 11:28:38 -08:00
loongarch LoongArch changes for v6.19 2025-12-13 05:44:03 +12:00
m68k Networking changes for 6.19. 2025-12-03 17:24:33 -08:00
microblaze
mips sound fixes for 6.19-rc1 2025-12-13 16:09:10 +12:00
nios2 arch/nios2: replace "__auto_type" and adjacent equivalent with "auto" 2025-12-08 15:32:15 -08:00
openrisc
parisc TTY/Serial changes for 6.19-rc1 2025-12-06 18:38:19 -08:00
powerpc Patch series in this pull request: 2025-12-13 20:35:41 +12:00
riscv lib/crypto: riscv: Depend on RISCV_EFFICIENT_VECTOR_UNALIGNED_ACCESS 2025-12-09 15:10:21 -08:00
s390 s390/pci: Fix cyclic dead-lock in zpci_zdev_put() and zpci_scan_devices() 2025-12-14 11:03:58 +01:00
sh sound fixes for 6.19-rc1 2025-12-13 16:09:10 +12:00
sparc dma-mapping updates for Linux 6.19: 2025-12-06 09:25:05 -08:00
um Address various objtool scalability bugs/inefficiencies exposed by 2025-12-06 11:56:51 -08:00
x86 Misc fixes: 2025-12-14 06:10:35 +12:00
xtensa TTY/Serial changes for 6.19-rc1 2025-12-06 18:38:19 -08:00
.gitignore
Kconfig