]> git.ipfire.org Git - thirdparty/kernel/stable.git/commit
mmc: block: handle complete_work on separate workqueue
authorZachary Hays <zhays@lexmark.com>
Thu, 7 Feb 2019 15:03:08 +0000 (10:03 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 20 Feb 2019 09:29:11 +0000 (10:29 +0100)
commit1fdf7b8b061251324af0e53046605c478024f95f
tree6ffeac1f01cb54075f92a7136c67d8d73f053037
parentcb384113e6146db1c951abeb75852b77972c570f
mmc: block: handle complete_work on separate workqueue

commit dcf6e2e38a1c7ccbc535de5e1d9b14998847499d upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/mmc/core/block.c
include/linux/mmc/card.h