linux/drivers/pci/hotplug
Hans de Goede 085a9f4343 PCI: pciehp: Use down_read/write_nested(reset_lock) to fix lockdep errors
Use down_read_nested() and down_write_nested() when taking the
ctrl->reset_lock rw-sem, passing the number of PCIe hotplug controllers in
the path to the PCI root bus as lock subclass parameter.

This fixes the following false-positive lockdep report when unplugging a
Lenovo X1C8 from a Lenovo 2nd gen TB3 dock:

  pcieport 0000:06:01.0: pciehp: Slot(1): Link Down
  pcieport 0000:06:01.0: pciehp: Slot(1): Card not present
  ============================================
  WARNING: possible recursive locking detected
  5.16.0-rc2+ #621 Not tainted
  --------------------------------------------
  irq/124-pciehp/86 is trying to acquire lock:
  ffff8e5ac4299ef8 (&ctrl->reset_lock){.+.+}-{3:3}, at: pciehp_check_presence+0x23/0x80

  but task is already holding lock:
  ffff8e5ac4298af8 (&ctrl->reset_lock){.+.+}-{3:3}, at: pciehp_ist+0xf3/0x180

   other info that might help us debug this:
   Possible unsafe locking scenario:

	 CPU0
	 ----
    lock(&ctrl->reset_lock);
    lock(&ctrl->reset_lock);

   *** DEADLOCK ***

   May be due to missing lock nesting notation

  3 locks held by irq/124-pciehp/86:
   #0: ffff8e5ac4298af8 (&ctrl->reset_lock){.+.+}-{3:3}, at: pciehp_ist+0xf3/0x180
   #1: ffffffffa3b024e8 (pci_rescan_remove_lock){+.+.}-{3:3}, at: pciehp_unconfigure_device+0x31/0x110
   #2: ffff8e5ac1ee2248 (&dev->mutex){....}-{3:3}, at: device_release_driver+0x1c/0x40

  stack backtrace:
  CPU: 4 PID: 86 Comm: irq/124-pciehp Not tainted 5.16.0-rc2+ #621
  Hardware name: LENOVO 20U90SIT19/20U90SIT19, BIOS N2WET30W (1.20 ) 08/26/2021
  Call Trace:
   <TASK>
   dump_stack_lvl+0x59/0x73
   __lock_acquire.cold+0xc5/0x2c6
   lock_acquire+0xb5/0x2b0
   down_read+0x3e/0x50
   pciehp_check_presence+0x23/0x80
   pciehp_runtime_resume+0x5c/0xa0
   device_for_each_child+0x45/0x70
   pcie_port_device_runtime_resume+0x20/0x30
   pci_pm_runtime_resume+0xa7/0xc0
   __rpm_callback+0x41/0x110
   rpm_callback+0x59/0x70
   rpm_resume+0x512/0x7b0
   __pm_runtime_resume+0x4a/0x90
   __device_release_driver+0x28/0x240
   device_release_driver+0x26/0x40
   pci_stop_bus_device+0x68/0x90
   pci_stop_bus_device+0x2c/0x90
   pci_stop_and_remove_bus_device+0xe/0x20
   pciehp_unconfigure_device+0x6c/0x110
   pciehp_disable_slot+0x5b/0xe0
   pciehp_handle_presence_or_link_change+0xc3/0x2f0
   pciehp_ist+0x179/0x180

This lockdep warning is triggered because with Thunderbolt, hotplug ports
are nested. When removing multiple devices in a daisy-chain, each hotplug
port's reset_lock may be acquired recursively. It's never the same lock, so
the lockdep splat is a false positive.

Because locks at the same hierarchy level are never acquired recursively, a
per-level lockdep class is sufficient to fix the lockdep warning.

The choice to use one lockdep subclass per pcie-hotplug controller in the
path to the root-bus was made to conserve class keys because their number
is limited and the complexity grows quadratically with number of keys
according to Documentation/locking/lockdep-design.rst.

Link: https://lore.kernel.org/linux-pci/20190402021933.GA2966@mit.edu/
Link: https://lore.kernel.org/linux-pci/de684a28-9038-8fc6-27ca-3f6f2f6400d7@redhat.com/
Link: https://lore.kernel.org/r/20211217141709.379663-1-hdegoede@redhat.com
Link: https://bugzilla.kernel.org/show_bug.cgi?id=208855
Reported-by: "Theodore Ts'o" <tytso@mit.edu>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Lukas Wunner <lukas@wunner.de>
Cc: stable@vger.kernel.org
2022-01-12 06:42:51 -06:00
..
acpi_pcihp.c PCI: Fix kernel-doc errors 2021-03-11 17:37:20 -06:00
acpiphp_core.c Merge branch 'xarray' of git://git.infradead.org/users/willy/linux-dax 2018-10-28 11:35:40 -07:00
acpiphp_glue.c PCI: Correct misspelled and remove duplicated words 2021-10-08 17:14:04 -05:00
acpiphp_ibm.c PCI: hotplug: Embed hotplug_slot 2018-09-18 17:52:15 -05:00
acpiphp.h PCI: acpiphp: Fix whitespace issue 2021-04-16 14:32:18 -05:00
cpci_hotplug_core.c PCI: Remove unnecessary returns 2019-08-30 14:00:34 -05:00
cpci_hotplug_pci.c PCI: cpcihp: Declare cpci_debug in header file 2021-07-01 15:32:45 -05:00
cpci_hotplug.h PCI: cpcihp: Declare cpci_debug in header file 2021-07-01 15:32:45 -05:00
cpcihp_generic.c PCI: Add SPDX GPL-2.0+ to replace GPL v2 or later boilerplate 2018-01-28 15:49:06 -06:00
cpcihp_zt5550.c PCI: Add SPDX GPL-2.0+ to replace GPL v2 or later boilerplate 2018-01-28 15:49:06 -06:00
cpcihp_zt5550.h PCI: Add SPDX GPL-2.0+ to replace GPL v2 or later boilerplate 2018-01-28 15:49:06 -06:00
cpqphp_core.c PCI: Fix kernel-doc formatting 2021-07-06 10:37:46 -05:00
cpqphp_ctrl.c PCI: Correct misspelled and remove duplicated words 2021-10-08 17:14:04 -05:00
cpqphp_nvram.c PCI: cpqphp: Use DEFINE_SPINLOCK() for int15_lock 2021-04-14 15:24:10 -05:00
cpqphp_nvram.h PCI: Remove unnecessary returns 2019-08-30 14:00:34 -05:00
cpqphp_pci.c PCI: cpqphp: Format if-statement code block correctly 2021-10-12 20:48:44 -05:00
cpqphp_sysfs.c PCI: Add SPDX GPL-2.0+ to replace GPL v2 or later boilerplate 2018-01-28 15:49:06 -06:00
cpqphp.h PCI: cpqphp: Use <linux/io.h> instead of <asm/io.h> 2021-11-02 14:41:58 -05:00
ibmphp_core.c PCI: ibmphp: Remove commented-out functions 2021-12-10 09:55:47 -06:00
ibmphp_ebda.c PCI: ibmphp: Fix double unmap of io_mem 2021-09-02 12:02:50 -05:00
ibmphp_hpc.c PCI: ibmphp: Turn semaphores into completions or mutexes 2019-01-29 17:15:36 -06:00
ibmphp_pci.c PCI: ibmphp: Remove unneeded break 2020-11-20 11:17:55 -06:00
ibmphp_res.c treewide: Use fallthrough pseudo-keyword 2020-08-23 17:36:59 -05:00
ibmphp.h PCI: Correct misspelled and remove duplicated words 2021-10-08 17:14:04 -05:00
Kconfig treewide: replace '---help---' in Kconfig files with 'help' 2020-06-14 01:57:21 +09:00
Makefile PCI/hotplug: remove the sgi_hotplug driver 2019-08-16 11:33:56 -07:00
pci_hotplug_core.c PCI/sysfs: Use sysfs_emit() and sysfs_emit_at() in "show" functions 2021-06-03 22:14:47 -05:00
pciehp_core.c PCI: pciehp: Use down_read/write_nested(reset_lock) to fix lockdep errors 2022-01-12 06:42:51 -06:00
pciehp_ctrl.c pci-v5.10-changes 2020-10-22 12:41:00 -07:00
pciehp_hpc.c PCI: pciehp: Use down_read/write_nested(reset_lock) to fix lockdep errors 2022-01-12 06:42:51 -06:00
pciehp_pci.c PCI: pciehp: Log messages with pci_dev, not pcie_device 2019-05-09 16:45:20 -05:00
pciehp.h PCI: pciehp: Use down_read/write_nested(reset_lock) to fix lockdep errors 2022-01-12 06:42:51 -06:00
pnv_php.c PCI: Change the type of probe argument in reset functions 2021-08-18 17:32:42 -05:00
rpadlpar_core.c PCI: rpadlpar: Use for_each_child_of_node() and for_each_node_by_name() 2020-09-17 16:22:36 -05:00
rpadlpar_sysfs.c PCI/sysfs: Use sysfs_emit() and sysfs_emit_at() in "show" functions 2021-06-03 22:14:47 -05:00
rpadlpar.h PCI: Add SPDX GPL-2.0+ to replace GPL v2 or later boilerplate 2018-01-28 15:49:06 -06:00
rpaphp_core.c PCI: Use of_node_name_eq() for node name comparisons 2020-04-24 18:02:17 -05:00
rpaphp_pci.c powerpc/eeh: Make early EEH init pseries specific 2020-03-25 12:09:39 +11:00
rpaphp_slot.c PCI: rpaphp: Get/put device node reference during slot alloc/dealloc 2019-04-10 16:07:12 -05:00
rpaphp.h PCI: hotplug: Embed hotplug_slot 2018-09-18 17:52:15 -05:00
s390_pci_hpc.c s390/pci: implement reset_slot for hotplug slot 2021-11-08 14:17:49 +01:00
shpchp_core.c PCI: hotplug: Embed hotplug_slot 2018-09-18 17:52:15 -05:00
shpchp_ctrl.c pci-v5.10-changes 2020-10-22 12:41:00 -07:00
shpchp_hpc.c PCI: Correct misspelled and remove duplicated words 2021-10-08 17:14:04 -05:00
shpchp_pci.c PCI: shpchp: Make shpchp_unconfigure_device() void 2020-05-21 15:23:20 -05:00
shpchp_sysfs.c PCI/sysfs: Use sysfs_emit() and sysfs_emit_at() in "show" functions 2021-06-03 22:14:47 -05:00
shpchp.h PCI: shpchp: Make shpchp_unconfigure_device() void 2020-05-21 15:23:20 -05:00
TODO PCI: ibmphp: Remove commented-out functions 2021-12-10 09:55:47 -06:00