@@ -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)
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@hisilicon.com> --- drivers/pci/pci.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)