Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mmc: core: Further fix thread wake-up

Commit e0097cf5f2f1 ("mmc: queue: Fix queue thread wake-up") did not go far
enough. mmc_wait_for_data_req_done() still contains some problems and can
be further simplified. First it should not touch
context_info->is_waiting_last_req because that is a wake-up control used by
the owner of the context. Secondly, it should always return when one of its
wake-up conditions is met because, again, that is contolled by the owner of
the context.

While the current block driver does not have an issue, these problems were
exposed during testing of the Software Command Queue patches.

Fixes: e0097cf5f2f1 ("mmc: queue: Fix queue thread wake-up")
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Tested-by: Harjani Ritesh <riteshh@codeaurora.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

authored by

Adrian Hunter and committed by
Ulf Hansson
15520111 84ec048b

+5 -7
+5 -7
drivers/mmc/core/core.c
··· 496 496 * Returns enum mmc_blk_status after checking errors. 497 497 */ 498 498 static enum mmc_blk_status mmc_wait_for_data_req_done(struct mmc_host *host, 499 - struct mmc_request *mrq, 500 - struct mmc_async_req *next_req) 499 + struct mmc_request *mrq) 501 500 { 502 501 struct mmc_command *cmd; 503 502 struct mmc_context_info *context_info = &host->context_info; ··· 506 507 wait_event_interruptible(context_info->wait, 507 508 (context_info->is_done_rcv || 508 509 context_info->is_new_req)); 509 - context_info->is_waiting_last_req = false; 510 + 510 511 if (context_info->is_done_rcv) { 511 512 context_info->is_done_rcv = false; 512 513 cmd = mrq->cmd; ··· 526 527 __mmc_start_request(host, mrq); 527 528 continue; /* wait for done/new event again */ 528 529 } 529 - } else if (context_info->is_new_req) { 530 - if (!next_req) 531 - return MMC_BLK_NEW_REQUEST; 532 530 } 531 + 532 + return MMC_BLK_NEW_REQUEST; 533 533 } 534 534 mmc_retune_release(host); 535 535 return status; ··· 658 660 mmc_pre_req(host, areq->mrq); 659 661 660 662 if (host->areq) { 661 - status = mmc_wait_for_data_req_done(host, host->areq->mrq, areq); 663 + status = mmc_wait_for_data_req_done(host, host->areq->mrq); 662 664 if (status == MMC_BLK_NEW_REQUEST) { 663 665 if (ret_stat) 664 666 *ret_stat = status;