Patch "PCI: hv: Add pci_destroy_slot() in pci_devices_present_work(), if necessary" has been added to the 4.14-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    PCI: hv: Add pci_destroy_slot() in pci_devices_present_work(), if necessary

to the 4.14-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     pci-hv-add-pci_destroy_slot-in-pci_devices_present_w.patch
and it can be found in the queue-4.14 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit df1a1c65fc7b1b9c9a5341973dd8cd02039368d0
Author: Dexuan Cui <decui@xxxxxxxxxxxxx>
Date:   Wed May 15 16:06:22 2019 -0700

    PCI: hv: Add pci_destroy_slot() in pci_devices_present_work(), if necessary
    
    [ Upstream commit 340d455699400f2c2c0f9b3f703ade3085cdb501 ]
    
    When we hot-remove a device, usually the host sends us a PCI_EJECT message,
    and a PCI_BUS_RELATIONS message with bus_rel->device_count == 0.
    
    When we execute the quick hot-add/hot-remove test, the host may not send
    us the PCI_EJECT message if the guest has not fully finished the
    initialization by sending the PCI_RESOURCES_ASSIGNED* message to the
    host, so it's potentially unsafe to only depend on the
    pci_destroy_slot() in hv_eject_device_work() because the code path
    
    create_root_hv_pci_bus()
     -> hv_pci_assign_slots()
    
    is not called in this case. Note: in this case, the host still sends the
    guest a PCI_BUS_RELATIONS message with bus_rel->device_count == 0.
    
    In the quick hot-add/hot-remove test, we can have such a race before
    the code path
    
    pci_devices_present_work()
     -> new_pcichild_device()
    
    adds the new device into the hbus->children list, we may have already
    received the PCI_EJECT message, and since the tasklet handler
    
    hv_pci_onchannelcallback()
    
    may fail to find the "hpdev" by calling
    
    get_pcichild_wslot(hbus, dev_message->wslot.slot)
    
    hv_pci_eject_device() is not called; Later, by continuing execution
    
    create_root_hv_pci_bus()
     -> hv_pci_assign_slots()
    
    creates the slot and the PCI_BUS_RELATIONS message with
    bus_rel->device_count == 0 removes the device from hbus->children, and
    we end up being unable to remove the slot in
    
    hv_pci_remove()
     -> hv_pci_remove_slots()
    
    Remove the slot in pci_devices_present_work() when the device
    is removed to address this race.
    
    pci_devices_present_work() and hv_eject_device_work() run in the
    singled-threaded hbus->wq, so there is not a double-remove issue for the
    slot.
    
    We cannot offload hv_pci_eject_device() from hv_pci_onchannelcallback()
    to the workqueue, because we need the hv_pci_onchannelcallback()
    synchronously call hv_pci_eject_device() to poll the channel
    ringbuffer to work around the "hangs in hv_compose_msi_msg()" issue
    fixed in commit de0aa7b2f97d ("PCI: hv: Fix 2 hang issues in
    hv_compose_msi_msg()")
    
    Fixes: a15f2c08c708 ("PCI: hv: support reporting serial number as slot information")
    Signed-off-by: Dexuan Cui <decui@xxxxxxxxxxxxx>
    [lorenzo.pieralisi@xxxxxxx: rewritten commit log]
    Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@xxxxxxx>
    Reviewed-by: Stephen Hemminger <stephen@xxxxxxxxxxxxxxxxxx>
    Reviewed-by:  Michael Kelley <mikelley@xxxxxxxxxxxxx>
    Cc: stable@xxxxxxxxxxxxxxx
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c
index a5825bbcded72..f591de23f3d35 100644
--- a/drivers/pci/host/pci-hyperv.c
+++ b/drivers/pci/host/pci-hyperv.c
@@ -1824,6 +1824,10 @@ static void pci_devices_present_work(struct work_struct *work)
 		hpdev = list_first_entry(&removed, struct hv_pci_dev,
 					 list_entry);
 		list_del(&hpdev->list_entry);
+
+		if (hpdev->pci_slot)
+			pci_destroy_slot(hpdev->pci_slot);
+
 		put_pcichild(hpdev, hv_pcidev_ref_initial);
 	}
 



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux