From 6cc74e75a0d07d4f1b94e7d4becfac0d9d0a0648 Mon Sep 17 00:00:00 2001 From: Vijay Viswanath Date: Wed, 13 Sep 2017 17:08:43 +0530 Subject: [PATCH] mmc: block: Unhalt the command queue before releasing mmc host In the IOCTL path, the command queue is halted before servicing the ioctl requests. Once the ioctl request is serviced, the ioctl context releases mmc host and then unhalts the controller. This can cause race conditions where mmc driver would end up in a bad state. If another context B, which wants to send a legacy command, comes up between the time ioctl releases the host and unhalts the controller. Then the context B will see that cmdq is already halted and will prepare a legacy command. Once context B sends the legacy command, the ioctl context may unhalt the cmdq. This will mask the legacy interrupts and context B will never receive interrupts for the command it sent. To prevent this, unhalt the controller before the ioctl context releases the host. Change-Id: I65d3b4a709813549e7e5d48d94065a753164f9d0 Signed-off-by: Vijay Viswanath --- drivers/mmc/card/block.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index d39b4056c169..eeacaae49222 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1224,16 +1224,16 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, ioc_err = __mmc_blk_ioctl_cmd(card, md, idata); - mmc_put_card(card); - - err = mmc_blk_ioctl_copy_to_user(ic_ptr, idata); - if (mmc_card_cmdq(card)) { if (mmc_cmdq_halt(card->host, false)) pr_err("%s: %s: cmdq unhalt failed\n", mmc_hostname(card->host), __func__); } + mmc_put_card(card); + + err = mmc_blk_ioctl_copy_to_user(ic_ptr, idata); + cmd_done: mmc_blk_put(md); cmd_err: