···32503250 device_lock(&dev->dev);32513251}3252325232533253+/* Return 1 on successful lock, 0 on contention */32543254+static int pci_dev_trylock(struct pci_dev *dev)32553255+{32563256+ if (pci_cfg_access_trylock(dev)) {32573257+ if (device_trylock(&dev->dev))32583258+ return 1;32593259+ pci_cfg_access_unlock(dev);32603260+ }32613261+32623262+ return 0;32633263+}32643264+32533265static void pci_dev_unlock(struct pci_dev *dev)32543266{32553267 device_unlock(&dev->dev);···34053393}34063394EXPORT_SYMBOL_GPL(pci_reset_function);3407339533963396+/**33973397+ * pci_try_reset_function - quiesce and reset a PCI device function33983398+ * @dev: PCI device to reset33993399+ *34003400+ * Same as above, except return -EAGAIN if unable to lock device.34013401+ */34023402+int pci_try_reset_function(struct pci_dev *dev)34033403+{34043404+ int rc;34053405+34063406+ rc = pci_dev_reset(dev, 1);34073407+ if (rc)34083408+ return rc;34093409+34103410+ pci_dev_save_and_disable(dev);34113411+34123412+ if (pci_dev_trylock(dev)) {34133413+ rc = __pci_dev_reset(dev, 0);34143414+ pci_dev_unlock(dev);34153415+ } else34163416+ rc = -EAGAIN;34173417+34183418+ pci_dev_restore(dev);34193419+34203420+ return rc;34213421+}34223422+EXPORT_SYMBOL_GPL(pci_try_reset_function);34233423+34083424/* Lock devices from the top of the tree down */34093425static void pci_bus_lock(struct pci_bus *bus)34103426{···34553415 pci_bus_unlock(dev->subordinate);34563416 pci_dev_unlock(dev);34573417 }34183418+}34193419+34203420+/* Return 1 on successful lock, 0 on contention */34213421+static int pci_bus_trylock(struct pci_bus *bus)34223422+{34233423+ struct pci_dev *dev;34243424+34253425+ list_for_each_entry(dev, &bus->devices, bus_list) {34263426+ if (!pci_dev_trylock(dev))34273427+ goto unlock;34283428+ if (dev->subordinate) {34293429+ if (!pci_bus_trylock(dev->subordinate)) {34303430+ pci_dev_unlock(dev);34313431+ goto unlock;34323432+ }34333433+ }34343434+ }34353435+ return 1;34363436+34373437+unlock:34383438+ list_for_each_entry_continue_reverse(dev, &bus->devices, bus_list) {34393439+ if (dev->subordinate)34403440+ pci_bus_unlock(dev->subordinate);34413441+ pci_dev_unlock(dev);34423442+ }34433443+ return 0;34583444}3459344534603446/* Lock devices from the top of the tree down */···35093443 pci_bus_unlock(dev->subordinate);35103444 pci_dev_unlock(dev);35113445 }34463446+}34473447+34483448+/* Return 1 on successful lock, 0 on contention */34493449+static int pci_slot_trylock(struct pci_slot *slot)34503450+{34513451+ struct pci_dev *dev;34523452+34533453+ list_for_each_entry(dev, &slot->bus->devices, bus_list) {34543454+ if (!dev->slot || dev->slot != slot)34553455+ continue;34563456+ if (!pci_dev_trylock(dev))34573457+ goto unlock;34583458+ if (dev->subordinate) {34593459+ if (!pci_bus_trylock(dev->subordinate)) {34603460+ pci_dev_unlock(dev);34613461+ goto unlock;34623462+ }34633463+ }34643464+ }34653465+ return 1;34663466+34673467+unlock:34683468+ list_for_each_entry_continue_reverse(dev,34693469+ &slot->bus->devices, bus_list) {34703470+ if (!dev->slot || dev->slot != slot)34713471+ continue;34723472+ if (dev->subordinate)34733473+ pci_bus_unlock(dev->subordinate);34743474+ pci_dev_unlock(dev);34753475+ }34763476+ return 0;35123477}3513347835143479/* Save and disable devices from the top of the tree down */···36653568}36663569EXPORT_SYMBOL_GPL(pci_reset_slot);3667357035713571+/**35723572+ * pci_try_reset_slot - Try to reset a PCI slot35733573+ * @slot: PCI slot to reset35743574+ *35753575+ * Same as above except return -EAGAIN if the slot cannot be locked35763576+ */35773577+int pci_try_reset_slot(struct pci_slot *slot)35783578+{35793579+ int rc;35803580+35813581+ rc = pci_slot_reset(slot, 1);35823582+ if (rc)35833583+ return rc;35843584+35853585+ pci_slot_save_and_disable(slot);35863586+35873587+ if (pci_slot_trylock(slot)) {35883588+ might_sleep();35893589+ rc = pci_reset_hotplug_slot(slot->hotplug, 0);35903590+ pci_slot_unlock(slot);35913591+ } else35923592+ rc = -EAGAIN;35933593+35943594+ pci_slot_restore(slot);35953595+35963596+ return rc;35973597+}35983598+EXPORT_SYMBOL_GPL(pci_try_reset_slot);35993599+36683600static int pci_bus_reset(struct pci_bus *bus, int probe)36693601{36703602 if (!bus->self)···37513625 return rc;37523626}37533627EXPORT_SYMBOL_GPL(pci_reset_bus);36283628+36293629+/**36303630+ * pci_try_reset_bus - Try to reset a PCI bus36313631+ * @bus: top level PCI bus to reset36323632+ *36333633+ * Same as above except return -EAGAIN if the bus cannot be locked36343634+ */36353635+int pci_try_reset_bus(struct pci_bus *bus)36363636+{36373637+ int rc;36383638+36393639+ rc = pci_bus_reset(bus, 1);36403640+ if (rc)36413641+ return rc;36423642+36433643+ pci_bus_save_and_disable(bus);36443644+36453645+ if (pci_bus_trylock(bus)) {36463646+ might_sleep();36473647+ pci_reset_bridge_secondary_bus(bus->self);36483648+ pci_bus_unlock(bus);36493649+ } else36503650+ rc = -EAGAIN;36513651+36523652+ pci_bus_restore(bus);36533653+36543654+ return rc;36553655+}36563656+EXPORT_SYMBOL_GPL(pci_try_reset_bus);3754365737553658/**37563659 * pcix_get_max_mmrbc - get PCI-X maximum designed memory read byte count
+9-20
drivers/vfio/pci/vfio_pci.c
···139139 pci_write_config_word(pdev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE);140140141141 /*142142- * Careful, device_lock may already be held. This is the case if143143- * a driver unbind is blocked. Try to get the locks ourselves to144144- * prevent a deadlock.142142+ * Try to reset the device. The success of this is dependent on143143+ * being able to lock the device, which is not always possible.145144 */146145 if (vdev->reset_works) {147147- bool reset_done = false;148148-149149- if (pci_cfg_access_trylock(pdev)) {150150- if (device_trylock(&pdev->dev)) {151151- __pci_reset_function_locked(pdev);152152- reset_done = true;153153- device_unlock(&pdev->dev);154154- }155155- pci_cfg_access_unlock(pdev);156156- }157157-158158- if (!reset_done)159159- pr_warn("%s: Unable to acquire locks for reset of %s\n",160160- __func__, dev_name(&pdev->dev));146146+ int ret = pci_try_reset_function(pdev);147147+ if (ret)148148+ pr_warn("%s: Failed to reset device %s (%d)\n",149149+ __func__, dev_name(&pdev->dev), ret);161150 }162151163152 pci_restore_state(pdev);···503514504515 } else if (cmd == VFIO_DEVICE_RESET) {505516 return vdev->reset_works ?506506- pci_reset_function(vdev->pdev) : -EINVAL;517517+ pci_try_reset_function(vdev->pdev) : -EINVAL;507518508519 } else if (cmd == VFIO_DEVICE_GET_PCI_HOT_RESET_INFO) {509520 struct vfio_pci_hot_reset_info hdr;···673684 &info, slot);674685 if (!ret)675686 /* User has access, do the reset */676676- ret = slot ? pci_reset_slot(vdev->pdev->slot) :677677- pci_reset_bus(vdev->pdev->bus);687687+ ret = slot ? pci_try_reset_slot(vdev->pdev->slot) :688688+ pci_try_reset_bus(vdev->pdev->bus);678689679690hot_reset_release:680691 for (i--; i >= 0; i--)