aboutsummaryrefslogtreecommitdiff
path: root/tools/perf/scripts/python/bin/stackcollapse-report
diff options
context:
space:
mode:
authorKrzysztof Wilczyński <kwilczynski@kernel.org>2026-06-11 15:05:43 +0000
committerBjorn Helgaas <bhelgaas@google.com>2026-06-23 14:46:45 -0500
commit8857f6578b001bcf5f53c8c6a3936647f05291a8 (patch)
treeca827298514c3adcca1ec36a94044ccd9a66fef0 /tools/perf/scripts/python/bin/stackcollapse-report
parent254f49634ee16a731174d2ae34bc50bd5f45e731 (diff)
PCI/proc: Fix race between pci_proc_init() and pci_bus_add_device()
pci_proc_attach_device() creates procfs entries for PCI devices and is called from pci_bus_add_device(). It lazily creates the per-bus procfs directory (bus->procdir) via proc_mkdir() on first use, and returns early if proc_initialized is not yet set. On x86 with ACPI, PCI enumeration occurs at subsys_initcall, before pci_proc_init() sets proc_initialized at device_initcall. The for_each_pci_dev() loop in pci_proc_init() then creates procfs entries for these already-enumerated devices, but runs without holding pci_rescan_remove_lock. On ARM64 with devicetree, PCI host bridges probe at device_initcall. With async probing enabled, pci_bus_add_device() can run concurrently with pci_proc_init(), and both may call pci_proc_attach_device() for the same device or for different devices on the same bus. As pci_host_probe() holds pci_rescan_remove_lock while pci_proc_init() does not, there is no serialisation between the two paths. When two threads concurrently call pci_proc_attach_device() for devices on the same bus, both observe bus->procdir as NULL and both call proc_mkdir(). The proc filesystem serialises directory creation internally, so only one caller succeeds. The other results in a warning like: proc_dir_entry '000c:00/00.0' already registered The caller receives NULL (duplicate entry) and unconditionally stores it to bus->procdir, corrupting the valid pointer set by the first caller. Serialise access to proc_initialized, proc_bus_pci_dir, bus->procdir and dev->procent with a new mutex local to drivers/pci/proc.c, and store the created entries to bus->procdir and dev->procent only on success, so a failed creation can never overwrite a valid pointer. Additionally, wrap the for_each_pci_dev() loop in pci_proc_init() with pci_lock_rescan_remove() to serialise against concurrent PCI bus operations, add an early return in pci_proc_attach_device() when dev->procent is already set to make the function idempotent, and clear bus->procdir in pci_proc_detach_bus() to prevent use of a dangling pointer after proc_remove(). Reported-by: Shuan He <heshuan@bytedance.com> Closes: https://lore.kernel.org/linux-pci/20250702155112.40124-2-heshuan@bytedance.com/ Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Link: https://lore.kernel.org/r/20260611150543.511422-1-kwilczynski@kernel.org
Diffstat (limited to 'tools/perf/scripts/python/bin/stackcollapse-report')
0 files changed, 0 insertions, 0 deletions