[PATCH v5 01/23] PCI: Fix race condition in pci_enable/disable_device()
Bjorn Helgaas
helgaas at kernel.org
Sat Sep 28 07:59:19 AEST 2019
On Fri, Aug 16, 2019 at 07:50:39PM +0300, Sergey Miroshnichenko wrote:
> This is a yet another approach to fix an old [1-2] concurrency issue, when:
> - two or more devices are being hot-added into a bridge which was
> initially empty;
> - a bridge with two or more devices is being hot-added;
> - during boot, if BIOS/bootloader/firmware doesn't pre-enable bridges.
>
> The problem is that a bridge is reported as enabled before the MEM/IO bits
> are actually written to the PCI_COMMAND register, so another driver thread
> starts memory requests through the not-yet-enabled bridge:
>
> CPU0 CPU1
>
> pci_enable_device_mem() pci_enable_device_mem()
> pci_enable_bridge() pci_enable_bridge()
> pci_is_enabled()
> return false;
> atomic_inc_return(enable_cnt)
> Start actual enabling the bridge
> ... pci_is_enabled()
> ... return true;
> ... Start memory requests <-- FAIL
> ...
> Set the PCI_COMMAND_MEMORY bit <-- Must wait for this
>
> Protect the pci_enable/disable_device() and pci_enable_bridge(), which is
> similar to the previous solution from commit 40f11adc7cd9 ("PCI: Avoid race
> while enabling upstream bridges"), but adding a per-device mutexes and
> preventing the dev->enable_cnt from from incrementing early.
This isn't directly related to the movable BARs functionality; is it
here because you see the problem more frequently when moving BARs?
More information about the Linuxppc-dev
mailing list