aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@redhat.com>2013-12-16 17:14:31 -0500
committerBjorn Helgaas <bhelgaas@google.com>2014-01-14 18:34:44 -0500
commit61cf16d8bd38c3dc52033ea75d5b1f8368514a17 (patch)
treeba64244d5bb7cf59fcaf43b0784a938da146ce74
parenta870614a5371f8e36676e9bb2e089f4121976135 (diff)
PCI: Add pci_try_reset_function(), pci_try_reset_slot(), pci_try_reset_bus()
When doing a function/slot/bus reset PCI grabs the device_lock for each device to block things like suspend and driver probes, but call paths exist where this lock may already be held. This creates an opportunity for deadlock. For instance, vfio allows userspace to issue resets so long as it owns the device(s). If a driver unbind .remove callback races with userspace issuing a reset, we have a deadlock as userspace gets stuck waiting on device_lock while another thread has device_lock and waits for .remove to complete. To resolve this, we can make a version of the reset interfaces which use trylock. With this, we can safely attempt a reset and return error to userspace if there is contention. [bhelgaas: the deadlock happens when A (userspace) has a file descriptor for the device, and B waits in this path: driver_detach device_lock # take device_lock __device_release_driver pci_device_remove # pci_bus_type.remove vfio_pci_remove # pci_driver .remove vfio_del_group_dev wait_event(vfio.release_q, !vfio_dev_present) # wait (holding device_lock) Now B is stuck until A gives up the file descriptor. If A tries to acquire device_lock for any reason, we deadlock because A is waiting for B to release the lock, and B is waiting for A to release the file descriptor.] Signed-off-by: Alex Williamson <alex.williamson@redhat.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-rw-r--r--drivers/pci/pci.c155
-rw-r--r--include/linux/pci.h3
2 files changed, 158 insertions, 0 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 1cbd590cf1d1..8386367814ee 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -3250,6 +3250,18 @@ static void pci_dev_lock(struct pci_dev *dev)
3250 device_lock(&dev->dev); 3250 device_lock(&dev->dev);
3251} 3251}
3252 3252
3253/* Return 1 on successful lock, 0 on contention */
3254static int pci_dev_trylock(struct pci_dev *dev)
3255{
3256 if (pci_cfg_access_trylock(dev)) {
3257 if (device_trylock(&dev->dev))
3258 return 1;
3259 pci_cfg_access_unlock(dev);
3260 }
3261
3262 return 0;
3263}
3264
3253static void pci_dev_unlock(struct pci_dev *dev) 3265static void pci_dev_unlock(struct pci_dev *dev)
3254{ 3266{
3255 device_unlock(&dev->dev); 3267 device_unlock(&dev->dev);
@@ -3393,6 +3405,34 @@ int pci_reset_function(struct pci_dev *dev)
3393} 3405}
3394EXPORT_SYMBOL_GPL(pci_reset_function); 3406EXPORT_SYMBOL_GPL(pci_reset_function);
3395 3407
3408/**
3409 * pci_try_reset_function - quiesce and reset a PCI device function
3410 * @dev: PCI device to reset
3411 *
3412 * Same as above, except return -EAGAIN if unable to lock device.
3413 */
3414int pci_try_reset_function(struct pci_dev *dev)
3415{
3416 int rc;
3417
3418 rc = pci_dev_reset(dev, 1);
3419 if (rc)
3420 return rc;
3421
3422 pci_dev_save_and_disable(dev);
3423
3424 if (pci_dev_trylock(dev)) {
3425 rc = __pci_dev_reset(dev, 0);
3426 pci_dev_unlock(dev);
3427 } else
3428 rc = -EAGAIN;
3429
3430 pci_dev_restore(dev);
3431
3432 return rc;
3433}
3434EXPORT_SYMBOL_GPL(pci_try_reset_function);
3435
3396/* Lock devices from the top of the tree down */ 3436/* Lock devices from the top of the tree down */
3397static void pci_bus_lock(struct pci_bus *bus) 3437static void pci_bus_lock(struct pci_bus *bus)
3398{ 3438{
@@ -3417,6 +3457,32 @@ static void pci_bus_unlock(struct pci_bus *bus)
3417 } 3457 }
3418} 3458}
3419 3459
3460/* Return 1 on successful lock, 0 on contention */
3461static int pci_bus_trylock(struct pci_bus *bus)
3462{
3463 struct pci_dev *dev;
3464
3465 list_for_each_entry(dev, &bus->devices, bus_list) {
3466 if (!pci_dev_trylock(dev))
3467 goto unlock;
3468 if (dev->subordinate) {
3469 if (!pci_bus_trylock(dev->subordinate)) {
3470 pci_dev_unlock(dev);
3471 goto unlock;
3472 }
3473 }
3474 }
3475 return 1;
3476
3477unlock:
3478 list_for_each_entry_continue_reverse(dev, &bus->devices, bus_list) {
3479 if (dev->subordinate)
3480 pci_bus_unlock(dev->subordinate);
3481 pci_dev_unlock(dev);
3482 }
3483 return 0;
3484}
3485
3420/* Lock devices from the top of the tree down */ 3486/* Lock devices from the top of the tree down */
3421static void pci_slot_lock(struct pci_slot *slot) 3487static void pci_slot_lock(struct pci_slot *slot)
3422{ 3488{
@@ -3445,6 +3511,37 @@ static void pci_slot_unlock(struct pci_slot *slot)
3445 } 3511 }
3446} 3512}
3447 3513
3514/* Return 1 on successful lock, 0 on contention */
3515static int pci_slot_trylock(struct pci_slot *slot)
3516{
3517 struct pci_dev *dev;
3518
3519 list_for_each_entry(dev, &slot->bus->devices, bus_list) {
3520 if (!dev->slot || dev->slot != slot)
3521 continue;
3522 if (!pci_dev_trylock(dev))
3523 goto unlock;
3524 if (dev->subordinate) {
3525 if (!pci_bus_trylock(dev->subordinate)) {
3526 pci_dev_unlock(dev);
3527 goto unlock;
3528 }
3529 }
3530 }
3531 return 1;
3532
3533unlock:
3534 list_for_each_entry_continue_reverse(dev,
3535 &slot->bus->devices, bus_list) {
3536 if (!dev->slot || dev->slot != slot)
3537 continue;
3538 if (dev->subordinate)
3539 pci_bus_unlock(dev->subordinate);
3540 pci_dev_unlock(dev);
3541 }
3542 return 0;
3543}
3544
3448/* Save and disable devices from the top of the tree down */ 3545/* Save and disable devices from the top of the tree down */
3449static void pci_bus_save_and_disable(struct pci_bus *bus) 3546static void pci_bus_save_and_disable(struct pci_bus *bus)
3450{ 3547{
@@ -3568,6 +3665,35 @@ int pci_reset_slot(struct pci_slot *slot)
3568} 3665}
3569EXPORT_SYMBOL_GPL(pci_reset_slot); 3666EXPORT_SYMBOL_GPL(pci_reset_slot);
3570 3667
3668/**
3669 * pci_try_reset_slot - Try to reset a PCI slot
3670 * @slot: PCI slot to reset
3671 *
3672 * Same as above except return -EAGAIN if the slot cannot be locked
3673 */
3674int pci_try_reset_slot(struct pci_slot *slot)
3675{
3676 int rc;
3677
3678 rc = pci_slot_reset(slot, 1);
3679 if (rc)
3680 return rc;
3681
3682 pci_slot_save_and_disable(slot);
3683
3684 if (pci_slot_trylock(slot)) {
3685 might_sleep();
3686 rc = pci_reset_hotplug_slot(slot->hotplug, 0);
3687 pci_slot_unlock(slot);
3688 } else
3689 rc = -EAGAIN;
3690
3691 pci_slot_restore(slot);
3692
3693 return rc;
3694}
3695EXPORT_SYMBOL_GPL(pci_try_reset_slot);
3696
3571static int pci_bus_reset(struct pci_bus *bus, int probe) 3697static int pci_bus_reset(struct pci_bus *bus, int probe)
3572{ 3698{
3573 if (!bus->self) 3699 if (!bus->self)
@@ -3627,6 +3753,35 @@ int pci_reset_bus(struct pci_bus *bus)
3627EXPORT_SYMBOL_GPL(pci_reset_bus); 3753EXPORT_SYMBOL_GPL(pci_reset_bus);
3628 3754
3629/** 3755/**
3756 * pci_try_reset_bus - Try to reset a PCI bus
3757 * @bus: top level PCI bus to reset
3758 *
3759 * Same as above except return -EAGAIN if the bus cannot be locked
3760 */
3761int pci_try_reset_bus(struct pci_bus *bus)
3762{
3763 int rc;
3764
3765 rc = pci_bus_reset(bus, 1);
3766 if (rc)
3767 return rc;
3768
3769 pci_bus_save_and_disable(bus);
3770
3771 if (pci_bus_trylock(bus)) {
3772 might_sleep();
3773 pci_reset_bridge_secondary_bus(bus->self);
3774 pci_bus_unlock(bus);
3775 } else
3776 rc = -EAGAIN;
3777
3778 pci_bus_restore(bus);
3779
3780 return rc;
3781}
3782EXPORT_SYMBOL_GPL(pci_try_reset_bus);
3783
3784/**
3630 * pcix_get_max_mmrbc - get PCI-X maximum designed memory read byte count 3785 * pcix_get_max_mmrbc - get PCI-X maximum designed memory read byte count
3631 * @dev: PCI device to query 3786 * @dev: PCI device to query
3632 * 3787 *
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 9e3ec8b951b7..d21be0343865 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -948,10 +948,13 @@ int pcie_get_minimum_link(struct pci_dev *dev, enum pci_bus_speed *speed,
948int __pci_reset_function(struct pci_dev *dev); 948int __pci_reset_function(struct pci_dev *dev);
949int __pci_reset_function_locked(struct pci_dev *dev); 949int __pci_reset_function_locked(struct pci_dev *dev);
950int pci_reset_function(struct pci_dev *dev); 950int pci_reset_function(struct pci_dev *dev);
951int pci_try_reset_function(struct pci_dev *dev);
951int pci_probe_reset_slot(struct pci_slot *slot); 952int pci_probe_reset_slot(struct pci_slot *slot);
952int pci_reset_slot(struct pci_slot *slot); 953int pci_reset_slot(struct pci_slot *slot);
954int pci_try_reset_slot(struct pci_slot *slot);
953int pci_probe_reset_bus(struct pci_bus *bus); 955int pci_probe_reset_bus(struct pci_bus *bus);
954int pci_reset_bus(struct pci_bus *bus); 956int pci_reset_bus(struct pci_bus *bus);
957int pci_try_reset_bus(struct pci_bus *bus);
955void pci_reset_bridge_secondary_bus(struct pci_dev *dev); 958void pci_reset_bridge_secondary_bus(struct pci_dev *dev);
956void pci_update_resource(struct pci_dev *dev, int resno); 959void pci_update_resource(struct pci_dev *dev, int resno);
957int __must_check pci_assign_resource(struct pci_dev *dev, int i); 960int __must_check pci_assign_resource(struct pci_dev *dev, int i);