lkml.org 
[lkml]   [2014]   [Jan]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[Update][PATCH 8/9] powerpc / eeh_driver: Use global PCI rescan-remove locking
    Date
    From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
    Subject: powerpc / eeh_driver: Use global PCI rescan-remove locking

    Race conditions are theoretically possible between the PCI device
    addition and removal in the PPC64 PCI error recovery driver and
    the generic PCI bus rescan and device removal that can be triggered
    via sysfs.

    To avoid those race conditions make PPC64 PCI error recovery driver
    use global PCI rescan-remove locking around PCI device addition and
    removal.

    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
    ---

    The previous version had wrong function names in the last hunk, sorry about
    that.

    Rafael

    ---
    arch/powerpc/kernel/eeh_driver.c | 19 ++++++++++++++++---
    1 file changed, 16 insertions(+), 3 deletions(-)

    Index: linux-pm/arch/powerpc/kernel/eeh_driver.c
    ===================================================================
    --- linux-pm.orig/arch/powerpc/kernel/eeh_driver.c
    +++ linux-pm/arch/powerpc/kernel/eeh_driver.c
    @@ -369,7 +369,9 @@ static void *eeh_rmv_device(void *data,
    edev->mode |= EEH_DEV_DISCONNECTED;
    (*removed)++;

    + pci_lock_rescan_remove();
    pci_stop_and_remove_bus_device(dev);
    + pci_unlock_rescan_remove();

    return NULL;
    }
    @@ -416,10 +418,13 @@ static int eeh_reset_device(struct eeh_p
    * into pcibios_add_pci_devices().
    */
    eeh_pe_state_mark(pe, EEH_PE_KEEP);
    - if (bus)
    + if (bus) {
    + pci_lock_rescan_remove();
    pcibios_remove_pci_devices(bus);
    - else if (frozen_bus)
    + pci_unlock_rescan_remove();
    + } else if (frozen_bus) {
    eeh_pe_dev_traverse(pe, eeh_rmv_device, &removed);
    + }

    /* Reset the pci controller. (Asserts RST#; resets config space).
    * Reconfigure bridges and devices. Don't try to bring the system
    @@ -429,6 +434,8 @@ static int eeh_reset_device(struct eeh_p
    if (rc)
    return rc;

    + pci_lock_rescan_remove();
    +
    /* Restore PE */
    eeh_ops->configure_bridge(pe);
    eeh_pe_restore_bars(pe);
    @@ -462,6 +469,7 @@ static int eeh_reset_device(struct eeh_p
    pe->tstamp = tstamp;
    pe->freeze_count = cnt;

    + pci_unlock_rescan_remove();
    return 0;
    }

    @@ -618,8 +626,11 @@ perm_error:
    eeh_pe_dev_traverse(pe, eeh_report_failure, NULL);

    /* Shut down the device drivers for good. */
    - if (frozen_bus)
    + if (frozen_bus) {
    + pci_lock_rescan_remove();
    pcibios_remove_pci_devices(frozen_bus);
    + pci_unlock_rescan_remove();
    + }
    }

    static void eeh_handle_special_event(void)
    @@ -692,6 +703,7 @@ static void eeh_handle_special_event(voi
    if (rc == 2 || rc == 1)
    eeh_handle_normal_event(pe);
    else {
    + pci_lock_rescan_remove();
    list_for_each_entry_safe(hose, tmp,
    &hose_list, list_node) {
    phb_pe = eeh_phb_pe_get(hose);
    @@ -703,6 +715,7 @@ static void eeh_handle_special_event(voi
    eeh_pe_dev_traverse(pe, eeh_report_failure, NULL);
    pcibios_remove_pci_devices(bus);
    }
    + pci_unlock_rescan_remove();
    }
    }



    \
     
     \ /
      Last update: 2014-01-15 15:01    [W:3.070 / U:0.356 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site