]> git.baikalelectronics.ru Git - kernel.git/commit
firewire: ohci: Fix deadlock at bus reset
authorStephan Gatzka <stephan.gatzka@gmail.com>
Mon, 26 Aug 2013 18:50:05 +0000 (20:50 +0200)
committerStefan Richter <stefanr@s5r6.in-berlin.de>
Thu, 29 Aug 2013 20:35:05 +0000 (22:35 +0200)
commit736a8d9aeea81da2caef9d07fd5e2a2f179853f0
treeb8042b322264f0be3539e37a254f4f1f06b06e03
parent1439e1959f866539d6488d6b445446f683fba4a4
firewire: ohci: Fix deadlock at bus reset

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 2830aba260ff
"workqueue: make all workqueues non-reentrant".  Swapped order of
destroy_workqueue and pci_unregister_driver.]

Signed-off-by: Stephan Gatzka <stephan.gatzka@gmail.com>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
drivers/firewire/ohci.c