summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorZachary Hays <zhays@lexmark.com>2019-02-07 16:03:08 +0100
committerUlf Hansson <ulf.hansson@linaro.org>2019-02-08 12:24:17 +0100
commitdcf6e2e38a1c7ccbc535de5e1d9b14998847499d (patch)
tree6b54c5ee87b59511e819c1582a4d3f79aeb70025 /include
parentmmc: sunxi: Filter out unsupported modes declared in the device tree (diff)
downloadlinux-dcf6e2e38a1c7ccbc535de5e1d9b14998847499d.tar.xz
linux-dcf6e2e38a1c7ccbc535de5e1d9b14998847499d.zip
mmc: block: handle complete_work on separate workqueue
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: 81196976ed94 ("mmc: block: Add blk-mq support") Cc: <stable@vger.kernel.org> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'include')
-rw-r--r--include/linux/mmc/card.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index de7377815b6b..8ef330027b13 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -308,6 +308,7 @@ struct mmc_card {
unsigned int nr_parts;
unsigned int bouncesz; /* Bounce buffer size */
+ struct workqueue_struct *complete_wq; /* Private workqueue */
};
static inline bool mmc_large_sector(struct mmc_card *card)