lkml.org 
[lkml]   [2018]   [Mar]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.9 060/241] PCI: hv: Properly handle PCI bus remove
    Date
    4.9-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Long Li <longli@microsoft.com>


    [ Upstream commit d3a78d8bf759d8848339dcc367c4c1678b57a08b ]

    hv_pci_devices_present() is called in hv_pci_remove() when we remove a PCI
    device from the host, e.g., by disabling SR-IOV on a device. In
    hv_pci_remove(), the bus is already removed before the call, so we don't
    need to rescan the bus in the workqueue scheduled from
    hv_pci_devices_present().

    By introducing bus state hv_pcibus_removed, we can avoid this situation.

    Reported-by: Xiaofeng Wang <xiaofwan@redhat.com>
    Signed-off-by: Long Li <longli@microsoft.com>
    Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
    Acked-by: K. Y. Srinivasan <kys@microsoft.com>
    Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/pci/host/pci-hyperv.c | 20 +++++++++++++++++---
    1 file changed, 17 insertions(+), 3 deletions(-)

    --- a/drivers/pci/host/pci-hyperv.c
    +++ b/drivers/pci/host/pci-hyperv.c
    @@ -351,6 +351,7 @@ enum hv_pcibus_state {
    hv_pcibus_init = 0,
    hv_pcibus_probed,
    hv_pcibus_installed,
    + hv_pcibus_removed,
    hv_pcibus_maximum
    };

    @@ -1489,13 +1490,24 @@ static void pci_devices_present_work(str
    put_pcichild(hpdev, hv_pcidev_ref_initial);
    }

    - /* Tell the core to rescan bus because there may have been changes. */
    - if (hbus->state == hv_pcibus_installed) {
    + switch(hbus->state) {
    + case hv_pcibus_installed:
    + /*
    + * Tell the core to rescan bus
    + * because there may have been changes.
    + */
    pci_lock_rescan_remove();
    pci_scan_child_bus(hbus->pci_bus);
    pci_unlock_rescan_remove();
    - } else {
    + break;
    +
    + case hv_pcibus_init:
    + case hv_pcibus_probed:
    survey_child_resources(hbus);
    + break;
    +
    + default:
    + break;
    }

    up(&hbus->enum_sem);
    @@ -2170,6 +2182,7 @@ static int hv_pci_probe(struct hv_device
    hbus = kzalloc(sizeof(*hbus), GFP_KERNEL);
    if (!hbus)
    return -ENOMEM;
    + hbus->state = hv_pcibus_init;

    /*
    * The PCI bus "domain" is what is called "segment" in ACPI and
    @@ -2312,6 +2325,7 @@ static int hv_pci_remove(struct hv_devic
    pci_stop_root_bus(hbus->pci_bus);
    pci_remove_root_bus(hbus->pci_bus);
    pci_unlock_rescan_remove();
    + hbus->state = hv_pcibus_removed;
    }

    ret = hv_send_resources_released(hdev);

    \
     
     \ /
      Last update: 2018-03-19 20:47    [W:4.212 / U:0.180 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site