• Prarit Bhargava's avatar
    PCI hotplug: acpiphp: Prevent deadlock on PCI-to-PCI bridge remove · 6af8bef1
    Prarit Bhargava authored
    I originally submitted a patch to workaround this by pushing all Ejection
    Requests and Device Checks onto the kacpi_hotplug queue.
    
    http://marc.info/?l=linux-acpi&m=131678270930105&w=2
    
    The patch is still insufficient in that Bus Checks also need to be added.
    
    Rather than add all events, including non-PCI-hotplug events, to the
    hotplug queue, mjg suggested that a better approach would be to modify
    the acpiphp driver so only acpiphp events would be added to the
    kacpi_hotplug queue.
    
    It's a longer patch, but at least we maintain the benefit of having separate
    queues in ACPI.  This, of course, is still only a workaround the problem.
    As Bjorn and mjg pointed out, we have to refactor a lot of this code to do
    the right thing but at this point it is a better to have this code working.
    
    The acpi core places all events on the kacpi_notify queue.  When the acpiphp
    driver is loaded and a PCI card with a PCI-to-PCI bridge is removed the
    following call sequence occurs:
    
    cleanup_p2p_bridge()
    	    -> cleanup_bridge()
    		    -> acpi_remove_notify_handler()
    			    -> acpi_os_wait_events_complete()
    				    -> flush_workqueue(kacpi_notify_wq)
    
    which is the queue we are currently executing on and the process will hang.
    
    Move all hotplug acpiphp events onto the kacpi_hotplug workqueue.  In
    handle_hotplug_event_bridge() and handle_hotplug_event_func() we can simply
    push the rest of the work onto the kacpi_hotplug queue and then avoid the
    deadlock.
    Signed-off-by: default avatarPrarit Bhargava <prarit@redhat.com>
    Cc: mjg@redhat.com
    Cc: bhelgaas@google.com
    Cc: linux-acpi@vger.kernel.org
    Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
    6af8bef1
acpiphp_glue.c 37.5 KB