linux/drivers/pci/hotplug
Ian Abbott 5c796ae7a7 PCI: Fix fakephp deadlock
If the fakephp driver is used to emulate removal of a PCI device by
writing text string "0" to the "power" sysfs attribute file, this causes
its parent directory and its contents (including the "power" file) to be
deleted before the write operation returns.  Unfortunately, it ends up
in a deadlock waiting for itself to complete.

The deadlock is as follows: sysfs_write_file calls flush_write_buffer
which calls sysfs_get_active_two before calling power_write_file in
pci_hotplug_core.c via the sysfs store operation. The power_write_file
function calls disable_slot in fakephp.c via the slot operation.  The
disable_slot function calls remove_slot which calls pci_hp_deregister
(back in pci_hotplug_core.c) which calls fs_remove_slot which calls
sysfs_remove_file to remove the "power" file. The sysfs_remove_file
function calls sysfs_hash_and_remove which calls sysfs_addrm_finish
which calls sysfs_deactivate. The sysfs_deactivate function sees that
something has an active reference on the sysfs_dirent (from the
previous call to sysfs_get_active_two back up the call stack somewhere)
so waits for the active reference to go away, which is of course
impossible.

The problem has been present since 2.6.21.

This patch breaks the deadlock by queuing work queue items on a single-
threaded work queue to remove a slot from sysfs, and to rescan the PCI
buses.  There is also some protection against disabling a slot that is
already being removed.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Cc: Kristen Accardi <kristen.c.accardi@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2008-02-01 15:04:30 -08:00
..
acpi_pcihp.c PCI Hotplug: move pci_hotplug.h to include/linux/ 2006-10-18 11:36:12 -07:00
acpiphp_core.c pci hotplug: kernel-doc fixes 2007-11-28 14:35:26 -08:00
acpiphp_glue.c PCI Hotplug: acpiphp: remove unneeded acpi_get_name function call 2008-02-01 15:04:24 -08:00
acpiphp_ibm.c kset: convert pci hotplug to use kset_create_and_add 2008-01-24 20:40:14 -08:00
acpiphp.h PCI: hotplug: acpiphp: Remove unused variable from acpiphp 2008-02-01 15:04:20 -08:00
cpci_hotplug_core.c PCI: cpci_hotplug: Convert to use the kthread API 2007-07-11 16:02:11 -07:00
cpci_hotplug_pci.c PCI: ROUND_UP macro cleanup in drivers/pci 2007-07-11 16:02:11 -07:00
cpci_hotplug.h [PATCH] PCI Hotplug: CPCI update 2005-05-17 14:31:11 -07:00
cpcihp_generic.c cpcihp_generic: prevent loading without "bridge" parameter 2006-10-18 11:36:12 -07:00
cpcihp_zt5550.c PCI: ZT5550 CPCI Hotplug driver fix 2007-05-02 19:02:40 -07:00
cpcihp_zt5550.h
cpqphp_core.c pci hotplug: kernel-doc fixes 2007-11-28 14:35:26 -08:00
cpqphp_ctrl.c pci hotplug: kernel-doc fixes 2007-11-28 14:35:26 -08:00
cpqphp_nvram.c [PATCH] getting rid of all casts of k[cmz]alloc() calls 2006-12-13 09:05:58 -08:00
cpqphp_nvram.h
cpqphp_pci.c i386: move pci 2007-10-11 11:16:36 +02:00
cpqphp_sysfs.c [PATCH] mark struct file_operations const 5 2007-02-12 09:48:45 -08:00
cpqphp.h PCI Hotplug: move pci_hotplug.h to include/linux/ 2006-10-18 11:36:12 -07:00
fakephp.c PCI: Fix fakephp deadlock 2008-02-01 15:04:30 -08:00
ibmphp_core.c PCI: hotplug: Switch to pci_get_bus_and_slot 2008-02-01 15:04:19 -08:00
ibmphp_ebda.c [PATCH] remove many unneeded #includes of sched.h 2007-02-14 08:09:54 -08:00
ibmphp_hpc.c pci: hotplug: ibmphp: convert to kthread 2007-10-12 15:03:15 -07:00
ibmphp_pci.c PCI: ibmphp_pci.c: fix NULL dereference 2006-12-01 14:37:00 -08:00
ibmphp_res.c [PATCH] ibmphp: remove TRUE and FALSE 2006-03-23 14:35:17 -08:00
ibmphp.h PCI Hotplug: move pci_hotplug.h to include/linux/ 2006-10-18 11:36:12 -07:00
Kconfig PCI: hotplug: remove Experimental 2008-02-01 15:04:19 -08:00
Makefile PCI: hotplug: Link fakephp last 2008-02-01 15:04:20 -08:00
pci_hotplug_core.c PCI: Add missing "space" in printk messages 2008-02-01 15:04:22 -08:00
pciehp_core.c PCI Hotplug: pciehp: remove needless members from struct controller 2008-02-01 15:04:24 -08:00
pciehp_ctrl.c pciehp: wait for 1000ms before LED operation after power off 2008-02-01 15:04:28 -08:00
pciehp_hpc.c pciehp: workaround against Bad DLLP during power off 2008-02-01 15:04:28 -08:00
pciehp_pci.c pciehp: block new requests from the device before power off 2008-02-01 15:04:28 -08:00
pciehp.h PCI Hotplug: pciehp: remove needless members from struct controller 2008-02-01 15:04:24 -08:00
pcihp_skeleton.c PCI Hotplug: move pci_hotplug.h to include/linux/ 2006-10-18 11:36:12 -07:00
rpadlpar_core.c [POWERPC] Merge PCI resource fixups 2007-12-20 16:18:09 +11:00
rpadlpar_sysfs.c Kobject: convert drivers/* from kobject_unregister() to kobject_put() 2008-01-24 20:40:40 -08:00
rpadlpar.h
rpaphp_core.c pci hotplug: kernel-doc fixes 2007-11-28 14:35:26 -08:00
rpaphp_pci.c pci hotplug: fix rpaphp directory naming 2008-02-01 15:04:22 -08:00
rpaphp_slot.c pci hotplug: fix rpaphp directory naming 2008-02-01 15:04:22 -08:00
rpaphp.h pci hotplug: fix rpaphp directory naming 2008-02-01 15:04:22 -08:00
sgi_hotplug.c [IA64] Fix warnings resulting from type-checking in dev_dbg() 2007-05-10 09:39:41 -07:00
shpchp_core.c PCI: fix multiple definition of `queue_pushbutton_work' 2007-05-02 19:02:34 -07:00
shpchp_ctrl.c pci hotplug: kernel-doc fixes 2007-11-28 14:35:26 -08:00
shpchp_hpc.c PCI: Spelling fixes 2008-02-01 15:04:26 -08:00
shpchp_pci.c [PATCH] acpi_pcihp: Add support for _HPX 2006-06-19 14:13:22 -07:00
shpchp_sysfs.c SHPCHP: fix __must_check warnings 2006-09-26 17:43:53 -07:00
shpchp.h PCI: fix multiple definition of `queue_pushbutton_work' 2007-05-02 19:02:34 -07:00