• Stephan Gatzka's avatar
    firewire: ohci: Fix deadlock at bus reset · db9ae8fe
    Stephan Gatzka authored
    Put bus_reset_work into its own workqueue.  By doing this, forward
    progress of bus_reset_work() is guaranteed if the work is switched over
    to a rescuer thread.
    
    Switching work to a rescuer thread happens if a new worker thread could
    not be allocated in certain time (MAYDAY_INITIAL_TIMEOUT, typically 10
    ms).  This might not be possible under high memory pressure or even on a
    heavily loaded embedded system running a slow serial console.
    
    The former deadlock occured in the following situation:
    The rescuer thread ran
    fw_device_init->read_config_rom->read_rom->fw_run_transaction.
    fw_run_transaction blocked waiting for the completion object.
    This completion object would have been completed in bus_reset_work,
    but this work was never executed in the rescuer thread due to its
    strictly sequential behaviour.
    
    [Stefan R.:  Removed WQ_NON_REENTRANT flag from allocation because
    it is no longer needed in current kernels.  Add it back if you backport
    to kernels older than 3.7, i.e. one which does not contain dbf2576e
    "workqueue: make all workqueues non-reentrant".  Swapped order of
    destroy_workqueue and pci_unregister_driver.]
    Signed-off-by: default avatarStephan Gatzka <stephan.gatzka@gmail.com>
    Signed-off-by: default avatarStefan Richter <stefanr@s5r6.in-berlin.de>
    db9ae8fe
ohci.c 106 KB