-
- Downloads
PCI: Fix is_added/is_busmaster race condition
When a PCI device is detected, pdev->is_added is set to 1 and proc and sysfs entries are created. When the device is removed, pdev->is_added is checked for one and then device is detached with clearing of proc and sys entries and at end, pdev->is_added is set to 0. is_added and is_busmaster are bit fields in pci_dev structure sharing same memory location. A strange issue was observed with multiple removal and rescan of a PCIe NVMe device using sysfs commands where is_added flag was observed as zero instead of one while removing device and proc,sys entries are not cleared. This causes issue in later device addition with warning message "proc_dir_entry" already registered. Debugging revealed a race condition between the PCI core setting the is_added bit in pci_bus_add_device() and the NVMe driver reset work-queue setting the is_busmaster bit in pci_set_master(). As these fields are not handled atomically, that clears the is_added bit. Move the is_added bit to a separate private flag variable and use atomic functions to set and retrieve the device addition state. This avoids the race because is_added no longer shares a memory location with is_busmaster. Link: https://bugzilla.kernel.org/show_bug.cgi?id=200283 Signed-off-by:Hari Vyas <hari.vyas@broadcom.com> Signed-off-by:
Bjorn Helgaas <bhelgaas@google.com> Reviewed-by:
Lukas Wunner <lukas@wunner.de> Acked-by:
Michael Ellerman <mpe@ellerman.id.au>
Showing
- arch/powerpc/kernel/pci-common.c 3 additions, 1 deletionarch/powerpc/kernel/pci-common.c
- arch/powerpc/platforms/powernv/pci-ioda.c 2 additions, 1 deletionarch/powerpc/platforms/powernv/pci-ioda.c
- arch/powerpc/platforms/pseries/setup.c 2 additions, 1 deletionarch/powerpc/platforms/pseries/setup.c
- drivers/pci/bus.c 3 additions, 3 deletionsdrivers/pci/bus.c
- drivers/pci/hotplug/acpiphp_glue.c 1 addition, 1 deletiondrivers/pci/hotplug/acpiphp_glue.c
- drivers/pci/pci.h 11 additions, 0 deletionsdrivers/pci/pci.h
- drivers/pci/probe.c 2 additions, 2 deletionsdrivers/pci/probe.c
- drivers/pci/remove.c 3 additions, 2 deletionsdrivers/pci/remove.c
- include/linux/pci.h 0 additions, 1 deletioninclude/linux/pci.h
Loading
Please register or sign in to comment