mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-11-15 19:25:13 +00:00
The kblockd workqueue is created with the WQ_MEM_RECLAIM flag set.
This generates a rescuer thread for that queue that will trigger when
the CPU is under heavy load and collect the uncompleted work.
In the case of mmc, this creates the possibility of a deadlock when
there are multiple partitions on the device as other blk-mq work is
also run on the same queue. For example:
- worker 0 claims the mmc host to work on partition 1
- worker 1 attempts to claim the host for partition 2 but has to wait
for worker 0 to finish
- worker 0 schedules complete_work to release the host
- rescuer thread is triggered after time-out and collects the dangling
work
- rescuer thread attempts to complete the work in order starting with
claim host
- the task to release host is now blocked by a task to claim it and
will never be called
The above results in multiple hung tasks that lead to failures to
mount partitions.
Handling complete_work on a separate workqueue avoids this by keeping
the work completion tasks separate from the other blk-mq work. This
allows the host to be released without getting blocked by other tasks
attempting to claim the host.
Signed-off-by: Zachary Hays <zhays@lexmark.com>
Fixes:
|
||
|---|---|---|
| .. | ||
| block.c | ||
| block.h | ||
| bus.c | ||
| bus.h | ||
| card.h | ||
| core.c | ||
| core.h | ||
| debugfs.c | ||
| host.c | ||
| host.h | ||
| Kconfig | ||
| Makefile | ||
| mmc.c | ||
| mmc_ops.c | ||
| mmc_ops.h | ||
| mmc_test.c | ||
| pwrseq.c | ||
| pwrseq.h | ||
| pwrseq_emmc.c | ||
| pwrseq_sd8787.c | ||
| pwrseq_simple.c | ||
| queue.c | ||
| queue.h | ||
| quirks.h | ||
| sd.c | ||
| sd.h | ||
| sd_ops.c | ||
| sd_ops.h | ||
| sdio.c | ||
| sdio_bus.c | ||
| sdio_bus.h | ||
| sdio_cis.c | ||
| sdio_cis.h | ||
| sdio_io.c | ||
| sdio_irq.c | ||
| sdio_ops.c | ||
| sdio_ops.h | ||
| sdio_uart.c | ||
| slot-gpio.c | ||
| slot-gpio.h | ||