In pci_dev_lock(), we hold pci_lock for configuration access first, then is device_lock. But in sriov enable routine, we hold device_lock first and pci_lock subsequently. The inconsistent lock order will have potential deadlock problem. In pci_dev_lock(): pci_dev_lock() pci_cfg_access_lock() device_lock() When adding VF by sysfs: sriov_numvfs_store() device_lock() ... sriov_enable() pci_cfg_access_lock() Adjust the lock order in pci_dev_lock(), pci_dev_trylock() and pci_dev_unlock() to avoid potential deadlock condition. Signed-off-by: Yicong Yang <yangyicong@xxxxxxxxxxxxx> --- drivers/pci/pci.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e87196c..78c99ef 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -4876,18 +4876,19 @@ static int pci_dev_reset_slot_function(struct pci_dev *dev, int probe) static void pci_dev_lock(struct pci_dev *dev) { - pci_cfg_access_lock(dev); /* block PM suspend, driver probe, etc. */ device_lock(&dev->dev); + + pci_cfg_access_lock(dev); } /* Return 1 on successful lock, 0 on contention */ static int pci_dev_trylock(struct pci_dev *dev) { - if (pci_cfg_access_trylock(dev)) { - if (device_trylock(&dev->dev)) + if (device_trylock(&dev->dev)) { + if (pci_cfg_access_trylock(dev)) return 1; - pci_cfg_access_unlock(dev); + device_unlock(&dev->dev); } return 0; @@ -4895,8 +4896,8 @@ static int pci_dev_trylock(struct pci_dev *dev) static void pci_dev_unlock(struct pci_dev *dev) { - device_unlock(&dev->dev); pci_cfg_access_unlock(dev); + device_unlock(&dev->dev); } static void pci_dev_save_and_disable(struct pci_dev *dev) -- 2.8.1