PCI: hv: Fix sleep while in non-sleep context when removing child devices from the bus
Subsystems (4)
PATCH v2 1/1 PCI: hv: Fix sleep while in non-sleep context when removing child devices from the bus
From: Long Li <[email protected]>
In hv_pci_bus_exit, the code is holding a spinlock while calling pci_destroy_slot(), which takes a mutex.
This is not safe for spinlock. Fix this by moving the children to be deleted to a list on the stack, and removing them after spinlock is released.
---
Changes in v2:
Made patch title more specific on what the patch does. Added link to the original bug report.
Changed to list_for_each_entry_safe for iterating the removed list.
drivers/pci/controller/pci-hyperv.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
drivers/pci/controller/pci-hyperv.c +10 -3
@@ -3229,9 +3229,17 @@ static int hv_pci_bus_exit(struct hv_device *hdev, bool keep_devs)return 0 ;if (!keep_devs) { -/* Delete any children which might still exist. */ +struct list_head removed; + +/* Move all present children to the list on stack */ +INIT_LIST_HEAD (&removed);spin_lock_irqsave (&hbus->device_list_lock, flags); -list_for_each_entry_safe (hpdev, tmp, &hbus->children, list_entry) { +list_for_each_entry_safe (hpdev, tmp, &hbus->children, list_entry) +list_move_tail (&hpdev->list_entry, &removed); +spin_unlock_irqrestore (&hbus->device_list_lock, flags); + +/* Remove all children in the list */ +list_for_each_entry_safe (hpdev, tmp, &removed, list_entry) {list_del (&hpdev->list_entry);if (hpdev->pci_slot)pci_destroy_slot (hpdev->pci_slot);
@@ -3239,7 +3247,6 @@ static int hv_pci_bus_exit(struct hv_device *hdev, bool keep_devs)put_pcichild (hpdev);put_pcichild (hpdev); } -spin_unlock_irqrestore (&hbus->device_list_lock, flags); } ret =hv_send_resources_released (hdev);
Signature · 1 line
2.25.1
Quoted 11 lines · On Mon, Aug 30, 2021 at 04:13:27PM -0700, [email protected] wrote:
From: Long Li <[email protected]>
In
hv_pci_bus_exit, the code is holding a spinlock while callingpci_destroy_slot(), which takes a mutex.This is not safe for spinlock. Fix this by moving the children to be deleted to a list on the stack, and removing them after spinlock is released.
Fixes 94d22763207a ("PCI: hv: Fix a race condition when removing the device")
Quoted 13 lines
Cc "K. Y. Srinivasan" <[email protected]>Cc Haiyang Zhang <[email protected]>Cc Stephen Hemminger <[email protected]>Cc Wei Liu <[email protected]>Cc Dexuan Cui <[email protected]>Cc Lorenzo Pieralisi <[email protected]>Cc Rob Herring <[email protected]>Cc "Krzysztof Wilczyński" <[email protected]>Cc Bjorn Helgaas <[email protected]>Cc Michael Kelley <[email protected]>Reported-by Dan Carpenter <[email protected]>Signed-off-by Long Li <[email protected]>
Quoted 26 lines · Wei Liu
Quoted 11 lines · On Mon, Aug 30, 2021 at 04:13:27PM -0700, [email protected] wrote:
From: Long Li <[email protected]>
In
hv_pci_bus_exit, the code is holding a spinlock while callingpci_destroy_slot(), which takes a mutex.This is not safe for spinlock. Fix this by moving the children to be deleted to a list on the stack, and removing them after spinlock is released.
Fixes 94d22763207a ("PCI: hv: Fix a race condition when removing the device")Quoted 13 lines
Cc "K. Y. Srinivasan" <[email protected]>Cc Haiyang Zhang <[email protected]>Cc Stephen Hemminger <[email protected]>Cc Wei Liu <[email protected]>Cc Dexuan Cui <[email protected]>Cc Lorenzo Pieralisi <[email protected]>Cc Rob Herring <[email protected]>Cc "Krzysztof Wilczyński" <[email protected]>Cc Bjorn Helgaas <[email protected]>Cc Michael Kelley <[email protected]>Reported-by Dan Carpenter <[email protected]>Signed-off-by Long Li <[email protected]>
Quoted 1 line
Reviewed-by Wei Liu <[email protected]>
Applied to hyperv-fixes.