Message ID | 20141202150514.GC27869@laptop.dumpdata.com (mailing list archive) |
---|---|
State | New, archived |
Delegated to: | Bjorn Helgaas |
Headers | show |
>>> Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> 12/02/14 4:05 PM >>> >On Tue, Dec 02, 2014 at 10:10:11AM +0000, Jan Beulich wrote: >> >>> On 21.11.14 at 23:17, <konrad.wilk@oracle.com> wrote: >> > Konrad Rzeszutek Wilk (7): >> > xen/pciback: Don't deadlock when unbinding. >> > driver core: Provide an wrapper around the mutex to do lockdep warnings >> > xen/pciback: Include the domain id if removing the device whilst still in use >> > xen/pciback: Print out the domain owning the device. >> > xen/pciback: Remove tons of dereferences >> > PCI: Expose pci_load_saved_state for public consumption. >> > xen/pciback: Restore configuration space when detaching from a guest. >> >> So my "xen-pciback: drop SR-IOV VFs when PF driver unloads" isn't >> among them, nor is there any alternative. What's the status of that >> patch (or the problem that prompted its creation)? > >Oh, I've it in my queue. Um, here is what I did to it - I hadn't >yet tested it - hence the reason it is not on that list. Yeah, if you like it better that way, it looks okay to me now. Jan -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index eb8b58e..ff27efa 100644 --- a/drivers/xen/xen-pciback/pci_stub.c +++ b/drivers/xen/xen-pciback/pci_stub.c @@ -1518,6 +1518,53 @@ parse_error: fs_initcall(pcistub_init); #endif +#ifdef CONFIG_PCI_IOV +static struct pcistub_device *find_vfs(const struct pci_dev *pdev) +{ + struct pcistub_device *psdev = NULL; + unsigned long flags; + bool found = false; + + spin_lock_irqsave(&pcistub_devices_lock, flags); + list_for_each_entry(psdev, &pcistub_devices, dev_list) { + if (!psdev->pdev && psdev->dev != pdev + && pci_physfn(psdev->dev) == pdev) { + found = true; + break; + } + } + spin_unlock_irqrestore(&pcistub_devices_lock, flags); + if (found) + return psdev; + return NULL; +} + +static int pci_stub_notifier(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct device *dev = data; + const struct pci_dev *pdev = to_pci_dev(dev); + + if (action != BUS_NOTIFY_UNBIND_DRIVER) + return NOTIFY_DONE; + + if (!pdev->is_physfn) + return NOTIFY_DONE; + + for (;;) { + struct pcistub_device *psdev = find_vfs(pdev); + if (!psdev) + break; + device_release_driver(&psdev->dev->dev); + } + return NOTIFY_DONE; +} + +static struct notifier_block pci_stub_nb = { + .notifier_call = pci_stub_notifier, +}; +#endif + static int __init xen_pcibk_init(void) { int err; @@ -1539,12 +1586,19 @@ static int __init xen_pcibk_init(void) err = xen_pcibk_xenbus_register(); if (err) pcistub_exit(); +#ifdef CONFIG_PCI_IOV + else + bus_register_notifier(&pci_bus_type, &pci_stub_nb); +#endif return err; } static void __exit xen_pcibk_cleanup(void) { +#ifdef CONFIG_PCI_IOV + bus_unregister_notifier(&pci_bus_type, &pci_stub_nb); +#endif xen_pcibk_xenbus_unregister(); pcistub_exit(); }