xen/pciback: Don't deadlock when unbinding.
[deliverable/linux.git] / drivers / xen / xen-pciback / passthrough.c
index 828dddc360df5463e0ca2997da9b546bd1716081..f16a30e2a1100f810f22baf720ca40e5c660c0f8 100644 (file)
@@ -69,7 +69,7 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev,
 }
 
 static void __xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev,
-                                       struct pci_dev *dev)
+                                       struct pci_dev *dev, bool lock)
 {
        struct passthrough_dev_data *dev_data = pdev->pci_dev_data;
        struct pci_dev_entry *dev_entry, *t;
@@ -87,8 +87,13 @@ static void __xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev,
 
        mutex_unlock(&dev_data->lock);
 
-       if (found_dev)
+       if (found_dev) {
+               if (lock)
+                       device_lock(&found_dev->dev);
                pcistub_put_pci_dev(found_dev);
+               if (lock)
+                       device_unlock(&found_dev->dev);
+       }
 }
 
 static int __xen_pcibk_init_devices(struct xen_pcibk_device *pdev)
@@ -156,8 +161,11 @@ static void __xen_pcibk_release_devices(struct xen_pcibk_device *pdev)
        struct pci_dev_entry *dev_entry, *t;
 
        list_for_each_entry_safe(dev_entry, t, &dev_data->dev_list, list) {
+               struct pci_dev *dev = dev_entry->dev;
                list_del(&dev_entry->list);
-               pcistub_put_pci_dev(dev_entry->dev);
+               device_lock(&dev->dev);
+               pcistub_put_pci_dev(dev);
+               device_unlock(&dev->dev);
                kfree(dev_entry);
        }
 
This page took 0.059119 seconds and 5 git commands to generate.