linux/drivers/pci/controller
Jiwei Sun ee98649645 PCI: vmd: Create domain symlink before pci_bus_add_devices()
[ Upstream commit f24c9bfcd4 ]

The vmd driver creates a "domain" symlink in sysfs for each VMD bridge.
Previously this symlink was created after pci_bus_add_devices() added
devices below the VMD bridge and emitted udev events to announce them to
userspace.

This led to a race between userspace consumers of the udev events and the
kernel creation of the symlink.  One such consumer is mdadm, which
assembles block devices into a RAID array, and for devices below a VMD
bridge, mdadm depends on the "domain" symlink.

If mdadm loses the race, it may be unable to assemble a RAID array, which
may cause a boot failure or other issues, with complaints like this:

  (udev-worker)[2149]: nvme1n1: '/sbin/mdadm -I /dev/nvme1n1'(err) 'mdadm: Unable to get real path for '/sys/bus/pci/drivers/vmd/0000:c7:00.5/domain/device''
  (udev-worker)[2149]: nvme1n1: '/sbin/mdadm -I /dev/nvme1n1'(err) 'mdadm: /dev/nvme1n1 is not attached to Intel(R) RAID controller.'
  (udev-worker)[2149]: nvme1n1: '/sbin/mdadm -I /dev/nvme1n1'(err) 'mdadm: No OROM/EFI properties for /dev/nvme1n1'
  (udev-worker)[2149]: nvme1n1: '/sbin/mdadm -I /dev/nvme1n1'(err) 'mdadm: no RAID superblock on /dev/nvme1n1.'
  (udev-worker)[2149]: nvme1n1: Process '/sbin/mdadm -I /dev/nvme1n1' failed with exit code 1.

This symptom prevents the OS from booting successfully.

After a NVMe disk is probed/added by the nvme driver, udevd invokes mdadm
to detect if there is a mdraid associated with this NVMe disk, and mdadm
determines if a NVMe device is connected to a particular VMD domain by
checking the "domain" symlink. For example:

  Thread A                   Thread B             Thread mdadm
  vmd_enable_domain
    pci_bus_add_devices
      __driver_probe_device
       ...
       work_on_cpu
         schedule_work_on
         : wakeup Thread B
                             nvme_probe
                             : wakeup scan_work
                               to scan nvme disk
                               and add nvme disk
                               then wakeup udevd
                                                  : udevd executes
                                                    mdadm command
         flush_work                               main
         : wait for nvme_probe done                ...
      __driver_probe_device                        find_driver_devices
      : probe next nvme device                     : 1) Detect domain symlink
      ...                                            2) Find domain symlink
      ...                                               from vmd sysfs
      ...                                            3) Domain symlink not
      ...                                               created yet; failed
    sysfs_create_link
    : create domain symlink

Create the VMD "domain" symlink before invoking pci_bus_add_devices() to
avoid this race.

Suggested-by: Adrian Huang <ahuang12@lenovo.com>
Link: https://lore.kernel.org/linux-pci/20240605124844.24293-1-sjiwei@163.com
Signed-off-by: Jiwei Sun <sunjw10@lenovo.com>
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
[bhelgaas: commit log]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Nirmal Patel <nirmal.patel@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
History 2024-12-27 13:52:51 +01:00
..
cadence PCI: cadence: Fix Gen2 Link Retraining process 2023-07-19 16:21:34 +02:00
dwc PCI: keystone: Add link up check to ks_pcie_other_map_bus() 2024-12-14 19:54:15 +01:00
mobiveil PCI: Add defines for normal and subtractive PCI bridges 2022-02-17 15:29:35 -06:00
Kconfig arm64: bcmbca: Make BCM4908 drivers depend on ARCH_BCMBCA 2022-08-15 09:55:34 -07:00
Makefile Merge branch 'pci/host/mt7621' 2021-11-05 11:28:51 -05:00
pci-aardvark.c Merge branch 'remotes/lorenzo/pci/bridge-emul' 2022-10-05 17:32:55 -05:00
pci-ftpci100.c PCI: ftpci100: Release the clock resources 2023-07-19 16:21:35 +02:00
pci-host-common.c PCI: Use preserve_config in place of pci_flags 2024-12-27 13:52:51 +01:00
pci-host-generic.c PCI: Unify ECAM constants in native PCI Express drivers 2020-12-10 14:55:49 -06:00
pci-hyperv-intf.c PCI: hv: Add a Hyper-V PCI interface driver for software backchannel interface 2019-08-22 00:25:12 -07:00
pci-hyperv.c PCI: hv: Return zero, not garbage, when reading PCI_INTERRUPT_PIN 2024-08-03 08:49:37 +02:00
pci-ixp4xx.c ARM: ixp4xx: fix building both pci drivers 2021-08-12 23:10:09 +02:00
pci-loongson.c PCI: loongson: Enable MSI in LS7A Root Complex 2024-08-03 08:49:37 +02:00
pci-mvebu.c PCI: mvebu: Use FIELD_PREP() with Link Width 2023-11-28 17:06:59 +00:00
pci-rcar-gen2.c PCI: rcar-gen2: Add RZ/N1 SOC family compatible string 2022-06-23 17:37:05 -05:00
pci-tegra.c Revert "PCI: tegra: Use PCI_CONF1_EXT_ADDRESS() macro" 2022-10-17 12:11:09 -05:00
pci-thunder-ecam.c PCI: thunder: Drop error data fabrication when config read fails 2021-11-18 13:39:32 -06:00
pci-thunder-pem.c PCI: thunder: Drop error data fabrication when config read fails 2021-11-18 13:39:32 -06:00
pci-v3-semi.c PCI: v3-semi: Remove unneeded break 2020-10-20 10:59:55 -05:00
pci-versatile.c PCI: versatile: Remove redundant variable retval 2022-04-28 10:46:37 +01:00
pci-xgene-msi.c PCI: xgene-msi: Use bitmap_zalloc() when applicable 2021-11-29 17:29:15 +00:00
pci-xgene.c PCI: Drop of_match_ptr() to avoid unused variables 2022-07-06 14:34:09 -05:00
pcie-altera-msi.c PCI: Bulk conversion to generic_handle_domain_irq() 2021-08-02 11:53:05 -05:00
pcie-altera.c Merge branch 'pci/driver-cleanup' 2022-01-13 09:57:53 -06:00
pcie-apple.c PCI: apple: Initialize pcie->nvecs before use 2023-09-13 09:42:45 +02:00
pcie-brcmstb.c PCI: brcmstb: Rename .map_bus() functions to end with 'map_bus' 2022-07-27 11:53:12 -05:00
pcie-hisi-error.c PCI: hip: Add handling of HiSilicon HIP PCIe controller errors 2020-09-16 10:30:42 +01:00
pcie-iproc-bcma.c PCI: Add defines for normal and subtractive PCI bridges 2022-02-17 15:29:35 -06:00
pcie-iproc-msi.c PCI: iproc: Use bitmap API to allocate bitmaps 2022-07-05 15:02:56 -05:00
pcie-iproc-platform.c PCI: iproc: Rename iproc_pcie_pltfm_ to iproc_pltfm_pcie_ 2022-01-03 15:01:53 -06:00
pcie-iproc.c PCI: iproc: Set all 24 bits of PCI class code 2022-02-17 15:30:01 -06:00
pcie-iproc.h PCI: Fix kernel-doc formatting 2021-07-06 10:37:46 -05:00
pcie-mediatek-gen3.c PCI: mediatek-gen3: Fix translation window size calculation 2024-01-25 15:27:48 -08:00
pcie-mediatek.c PCI: mediatek: Clear interrupt status before dispatching handler 2024-01-25 15:27:44 -08:00
pcie-microchip-host.c PCI: microchip: Correct the DED and SEC interrupt bit offsets 2023-09-13 09:42:46 +02:00
pcie-mt7621.c PCI: mt7621: Delay phy ports initialization 2023-03-10 09:33:35 +01:00
pcie-rcar-ep.c PCI: rcar-ep: Remove unneeded includes 2021-10-08 09:41:38 -05:00
pcie-rcar-host.c PCI: rcar: Demote WARN() to dev_warn_ratelimited() in rcar_pcie_wakeup() 2024-08-03 08:49:17 +02:00
pcie-rcar.c PCI: rcar: Fix calculating mask for PCIEPAMR register 2020-05-11 11:29:48 +01:00
pcie-rcar.h PCI: rcar: Add L1 link state fix into data abort hook 2021-08-16 14:51:30 +01:00
pcie-rockchip-ep.c PCI: rockchip-ep: Fix address translation unit programming 2024-12-14 19:54:16 +01:00
pcie-rockchip-host.c PCI: Convert to new *_PM_OPS macros 2022-07-27 11:56:17 -05:00
pcie-rockchip.c PCI: rockchip: Use GPIOD_OUT_LOW flag while requesting ep_gpio 2024-08-03 08:49:37 +02:00
pcie-rockchip.h PCI: rockchip-ep: Fix address translation unit programming 2024-12-14 19:54:16 +01:00
pcie-xilinx-cpm.c PCI: xilinx-cpm: Add support for Versal CPM5 Root Port 2022-07-22 14:21:06 -05:00
pcie-xilinx-nwl.c PCI: xilinx-nwl: Fix off-by-one in INTx IRQ handler 2024-10-17 15:21:15 +02:00
pcie-xilinx.c PCI: xilinx: Rename xilinx_pcie_port to xilinx_pcie 2022-01-03 15:05:28 -06:00
vmd.c PCI: vmd: Create domain symlink before pci_bus_add_devices() 2024-12-27 13:52:51 +01:00