From 72800360fdd782eda3489e555adf3b6b3abc064a Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Mon, 30 Mar 2009 10:50:19 -0600 Subject: PCI: pci_slot: grab refcount on slot's bus If a logical hot unplug (remove) is performed on a physical PCI slot's parent bridge, and then pci_slot is unloaded, we will encounter an oops: [] kobject_release+0x9a/0x290 [] ? kobject_release+0x0/0x290 [] kref_put+0x37/0x80 [] kobject_put+0x27/0x60 [] ? pci_destroy_slot+0x3c/0xc0 [] pci_destroy_slot+0x45/0xc0 [] acpi_pci_slot_remove+0x5c/0x91 [pci_slot] [] acpi_pci_unregister_driver+0x4b/0x62 [] acpi_pci_slot_exit+0x10/0x12 [pci_slot] [] sys_delete_module+0x161/0x250 We need to grab a reference to the parent PCI bus, which will pin the bus and prevent it from being released until pci_slot is unloaded. Cc: lenb@kernel.org Reviewed-by: Kenji Kaneshige Tested-by: Kenji Kaneshige Reported-by: Kenji Kaneshige Signed-off-by: Alex Chiang Signed-off-by: Jesse Barnes --- drivers/acpi/pci_slot.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/pci_slot.c b/drivers/acpi/pci_slot.c index cd1f4467be7..12158e0d009 100644 --- a/drivers/acpi/pci_slot.c +++ b/drivers/acpi/pci_slot.c @@ -164,6 +164,8 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) list_add(&slot->list, &slot_list); mutex_unlock(&slot_list_lock); + get_device(&pci_bus->dev); + dbg("pci_slot: %p, pci_bus: %x, device: %d, name: %s\n", pci_slot, pci_bus->number, device, name); @@ -310,12 +312,15 @@ static void acpi_pci_slot_remove(acpi_handle handle) { struct acpi_pci_slot *slot, *tmp; + struct pci_bus *pbus; mutex_lock(&slot_list_lock); list_for_each_entry_safe(slot, tmp, &slot_list, list) { if (slot->root_handle == handle) { list_del(&slot->list); + pbus = slot->pci_slot->bus; pci_destroy_slot(slot->pci_slot); + put_device(&pbus->dev); kfree(slot); } } -- cgit v1.2.3