From patchwork Thu Feb 9 15:33:48 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 93752 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp112195qgi; Thu, 9 Feb 2017 09:32:32 -0800 (PST) X-Received: by 10.98.62.153 with SMTP id y25mr5009843pfj.162.1486661552304; Thu, 09 Feb 2017 09:32:32 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l9si3457591plk.76.2017.02.09.09.32.32; Thu, 09 Feb 2017 09:32:32 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-mmc-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932466AbdBIRcN (ORCPT + 5 others); Thu, 9 Feb 2017 12:32:13 -0500 Received: from mail-lf0-f52.google.com ([209.85.215.52]:35104 "EHLO mail-lf0-f52.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754343AbdBIRcL (ORCPT ); Thu, 9 Feb 2017 12:32:11 -0500 Received: by mail-lf0-f52.google.com with SMTP id n124so6629843lfd.2 for ; Thu, 09 Feb 2017 09:32:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=yBj/RX3s/9Y2Y+Vve3S0fDZgFW5S2nqVcsZ/8X7wZkM=; b=Ul/BN0vsgKgsV0MNBnhg5Xy6T/2QYA0+Zz5w+b1ZDXCLtqxPXpR7YbU+uRwT9AUj11 R4zcZ7qXgqGJN08Azcw7KLYJF2wKDNO58ARbsy83D8GZ5Xuyn0Ugx/w3dV1lwKX4aMSX UPgiIVoOaWYLxom3q7neamluJL0ZLOhuhNOQY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=yBj/RX3s/9Y2Y+Vve3S0fDZgFW5S2nqVcsZ/8X7wZkM=; b=nub/vFN1dk9/Rinyp5qITrSjKAoYQzp9URJz7VAFUTS9ZV195sqfE57qSCXGWbfZaB ZDGYyvkwQBuNxl2t5KRl7Syp8hWLgF9LSn49unoSRxYO+X39gFuPPf/anHj0ofU0W23D Pu1NwQBxC7gJJzcl9DjRxWYi/Qheo2i0L4L/6edH3t055qPa1Ix0DdEJb1OP8Gkb4f/J MiQcLmKJs/rZpBTwKFXsJNc2AZiFlqwc28sH8enHLVfcEZOVa3nccD77OZuibIZQaczK 2iewCAJoAPwATLppR82K5SMTLzNS5fwT16NkgJvIqNVvOLOikJ2pfgsddRxpSGjs2fNY mc5A== X-Gm-Message-State: AMke39lxi9OUh8qSS046bISNhbuPh8a6490y7T6lY7gSB6BcP9QPUK+6cXuD/sG8U6tXnrBh X-Received: by 10.46.20.14 with SMTP id u14mr1403048ljd.30.1486654467651; Thu, 09 Feb 2017 07:34:27 -0800 (PST) Received: from gnarp.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id e86sm3670614lji.32.2017.02.09.07.34.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 09 Feb 2017 07:34:26 -0800 (PST) From: Linus Walleij To: linux-mmc@vger.kernel.org, Ulf Hansson , Adrian Hunter , Paolo Valente Cc: Chunyan Zhang , Baolin Wang , linux-block@vger.kernel.org, Jens Axboe , Christoph Hellwig , Arnd Bergmann , Linus Walleij Subject: [PATCH 01/16] mmc: core: move some code in mmc_start_areq() Date: Thu, 9 Feb 2017 16:33:48 +0100 Message-Id: <20170209153403.9730-2-linus.walleij@linaro.org> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170209153403.9730-1-linus.walleij@linaro.org> References: <20170209153403.9730-1-linus.walleij@linaro.org> Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org "previous" is a better name for the variable storing the previous asynchronous request, better than the opaque name "data" atleast. We see that we assign the return status to the returned variable on all code paths, so we might as well just do that immediately after calling mmc_finalize_areq(). Signed-off-by: Linus Walleij --- drivers/mmc/core/core.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Reviewed-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 41b4cd01fccc..53065d1cebf7 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -683,7 +683,7 @@ struct mmc_async_req *mmc_start_areq(struct mmc_host *host, { enum mmc_blk_status status; int start_err = 0; - struct mmc_async_req *data = host->areq; + struct mmc_async_req *previous = host->areq; /* Prepare a new request */ if (areq) @@ -691,13 +691,12 @@ struct mmc_async_req *mmc_start_areq(struct mmc_host *host, /* Finalize previous request */ status = mmc_finalize_areq(host); + if (ret_stat) + *ret_stat = status; /* The previous request is still going on... */ - if (status == MMC_BLK_NEW_REQUEST) { - if (ret_stat) - *ret_stat = status; + if (status == MMC_BLK_NEW_REQUEST) return NULL; - } /* Fine so far, start the new request! */ if (status == MMC_BLK_SUCCESS && areq) @@ -716,9 +715,7 @@ struct mmc_async_req *mmc_start_areq(struct mmc_host *host, else host->areq = areq; - if (ret_stat) - *ret_stat = status; - return data; + return previous; } EXPORT_SYMBOL(mmc_start_areq); From patchwork Thu Feb 9 15:33:49 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 93732 Delivered-To: patch@linaro.org Received: by 10.182.3.34 with SMTP id 2csp94380obz; Thu, 9 Feb 2017 08:04:10 -0800 (PST) X-Received: by 10.99.99.193 with SMTP id x184mr4919670pgb.226.1486656250008; Thu, 09 Feb 2017 08:04:10 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a3si10423738pgd.21.2017.02.09.08.04.09; Thu, 09 Feb 2017 08:04:10 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-mmc-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753236AbdBIQDy (ORCPT + 5 others); Thu, 9 Feb 2017 11:03:54 -0500 Received: from mail-lf0-f49.google.com ([209.85.215.49]:35993 "EHLO mail-lf0-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753215AbdBIQC3 (ORCPT ); Thu, 9 Feb 2017 11:02:29 -0500 Received: by mail-lf0-f49.google.com with SMTP id z134so4986455lff.3 for ; Thu, 09 Feb 2017 08:01:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=zpo1FToSBpBvfHHhnkf81Tj6PC2sUnNwEoAoOM32ODQ=; b=Rvdq/jG7XrmbNFUc0efzL8jHldvcn4J2QyzHPynsHIqzuR4qcOMtOd4ZtxYDjDgdPA OnvlpWgs1XwgI15jGnR/0Y9FK3A7qEN8kajblnuYERxMvPVQxsx7qyzHmnOd/rHjKAlP Zm2d+PVaA5gyRCIbeQu6eOOu0rkwU5CIgyXmo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=zpo1FToSBpBvfHHhnkf81Tj6PC2sUnNwEoAoOM32ODQ=; b=UUtF5jWW3BJHQ4zwvT8Zlr3sW/+fm+afpYSo0cz8hgyQTTMe6dW1HMWDZPCHsjyqkl E5+UF3CeluzPbO23hbf9QuuUN90vRrQOu5JNbvtL/O7nfV+0Me3VeKkH7LnzL59GDJOA z5GcNmTMc9JGqEV8e8tB7zdbsJApvkS3nHvQsRfWzTO89e+MN/iGYOrtFtHq0lRtKkrT 0yalqg3/v/rx/XPBEwvc/kdWfH1Z3a26C22mmnvdamGN0ciaYP10ZCissuyQgv7q9vZP UKWqoIYvAraXI4WZ6uz3Iv6iblnct5xk+ANkG/kwgnsULd/wDyGE00F3l4sbp9oaIoUe m0rA== X-Gm-Message-State: AMke39majtAOzR2VUmJ0u9BiH+fIJobe2/wa1rLjtLSuzqzD3qDFWs2Arh/uXsQjxiV7crHU X-Received: by 10.46.7.25 with SMTP id 25mr1463461ljh.41.1486654473926; Thu, 09 Feb 2017 07:34:33 -0800 (PST) Received: from gnarp.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id e86sm3670614lji.32.2017.02.09.07.34.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 09 Feb 2017 07:34:32 -0800 (PST) From: Linus Walleij To: linux-mmc@vger.kernel.org, Ulf Hansson , Adrian Hunter , Paolo Valente Cc: Chunyan Zhang , Baolin Wang , linux-block@vger.kernel.org, Jens Axboe , Christoph Hellwig , Arnd Bergmann , Linus Walleij Subject: [PATCH 02/16] mmc: core: refactor asynchronous request finalization Date: Thu, 9 Feb 2017 16:33:49 +0100 Message-Id: <20170209153403.9730-3-linus.walleij@linaro.org> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170209153403.9730-1-linus.walleij@linaro.org> References: <20170209153403.9730-1-linus.walleij@linaro.org> Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org mmc_wait_for_data_req_done() is called in exactly one place, and having it spread out is making things hard to oversee. Factor this function into mmc_finalize_areq(). Signed-off-by: Linus Walleij --- drivers/mmc/core/core.c | 86 +++++++++++++++++++------------------------------ 1 file changed, 33 insertions(+), 53 deletions(-) -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Reviewed-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 53065d1cebf7..b2e7a6dfcbf0 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -485,56 +485,6 @@ static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq) return err; } -/* - * mmc_wait_for_data_req_done() - wait for request completed - * @host: MMC host to prepare the command. - * @mrq: MMC request to wait for - * - * Blocks MMC context till host controller will ack end of data request - * execution or new request notification arrives from the block layer. - * Handles command retries. - * - * Returns enum mmc_blk_status after checking errors. - */ -static enum mmc_blk_status mmc_wait_for_data_req_done(struct mmc_host *host, - struct mmc_request *mrq) -{ - struct mmc_command *cmd; - struct mmc_context_info *context_info = &host->context_info; - enum mmc_blk_status status; - - while (1) { - wait_event_interruptible(context_info->wait, - (context_info->is_done_rcv || - context_info->is_new_req)); - - if (context_info->is_done_rcv) { - context_info->is_done_rcv = false; - cmd = mrq->cmd; - - if (!cmd->error || !cmd->retries || - mmc_card_removed(host->card)) { - status = host->areq->err_check(host->card, - host->areq); - break; /* return status */ - } else { - mmc_retune_recheck(host); - pr_info("%s: req failed (CMD%u): %d, retrying...\n", - mmc_hostname(host), - cmd->opcode, cmd->error); - cmd->retries--; - cmd->error = 0; - __mmc_start_request(host, mrq); - continue; /* wait for done/new event again */ - } - } - - return MMC_BLK_NEW_REQUEST; - } - mmc_retune_release(host); - return status; -} - void mmc_wait_for_req_done(struct mmc_host *host, struct mmc_request *mrq) { struct mmc_command *cmd; @@ -639,14 +589,44 @@ static void mmc_post_req(struct mmc_host *host, struct mmc_request *mrq, */ static enum mmc_blk_status mmc_finalize_areq(struct mmc_host *host) { + struct mmc_context_info *context_info = &host->context_info; enum mmc_blk_status status; if (!host->areq) return MMC_BLK_SUCCESS; - status = mmc_wait_for_data_req_done(host, host->areq->mrq); - if (status == MMC_BLK_NEW_REQUEST) - return status; + while (1) { + wait_event_interruptible(context_info->wait, + (context_info->is_done_rcv || + context_info->is_new_req)); + + if (context_info->is_done_rcv) { + struct mmc_command *cmd; + + context_info->is_done_rcv = false; + cmd = host->areq->mrq->cmd; + + if (!cmd->error || !cmd->retries || + mmc_card_removed(host->card)) { + status = host->areq->err_check(host->card, + host->areq); + break; /* return status */ + } else { + mmc_retune_recheck(host); + pr_info("%s: req failed (CMD%u): %d, retrying...\n", + mmc_hostname(host), + cmd->opcode, cmd->error); + cmd->retries--; + cmd->error = 0; + __mmc_start_request(host, host->areq->mrq); + continue; /* wait for done/new event again */ + } + } + + return MMC_BLK_NEW_REQUEST; + } + + mmc_retune_release(host); /* * Check BKOPS urgency for each R1 response From patchwork Thu Feb 9 15:33:50 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 93730 Delivered-To: patch@linaro.org Received: by 10.182.3.34 with SMTP id 2csp83559obz; Thu, 9 Feb 2017 07:41:05 -0800 (PST) X-Received: by 10.99.48.68 with SMTP id w65mr4690743pgw.107.1486654865372; Thu, 09 Feb 2017 07:41:05 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c7si10324262pgn.352.2017.02.09.07.41.05; Thu, 09 Feb 2017 07:41:05 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-mmc-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751318AbdBIPlE (ORCPT + 5 others); Thu, 9 Feb 2017 10:41:04 -0500 Received: from mail-lf0-f45.google.com ([209.85.215.45]:33511 "EHLO mail-lf0-f45.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751226AbdBIPlD (ORCPT ); Thu, 9 Feb 2017 10:41:03 -0500 Received: by mail-lf0-f45.google.com with SMTP id x1so4693142lff.0 for ; Thu, 09 Feb 2017 07:41:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=qz73lq1NQDQPVN270XPQxljELWQtHmR+4hg3oEAsqRQ=; b=Tkm7LkyQ24TZPHz5qij2GXX/sKE3RgvwiFP+OjbyWaAgtVOSH6nw+M5iuvHNIBO+fz 2musbu+jeC8T064Yc8+XCSqxdoK8lyKhgzag9L1fpw0xON3FXtYXm/66I1RrnaaLTQ5Z F8Ba2ngZxsnYlR1NDXdnQzAuXRGk0IxMHB7Ag= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=qz73lq1NQDQPVN270XPQxljELWQtHmR+4hg3oEAsqRQ=; b=CWEPyLV8SwKalEiIuc3ZesRZK5lI0kE5Cru5xB7j6l6u0X97lv5BV6NPS3epddLxQo OGrbFLHEYx772qinYVFhQAVoYGEYWs3SRnAVrCif5tHvp0IHeT1AsltzChyazjzfKDnF tWVCE3nu1dIr8hbnpFIKQfZiKroHac5J8w6LreLMBDj4R471Yh/A5hJ1EN51chc2u9Pn Ytxl3Q9Y4RxluAXewEED8qkRAywhlXKZh0IJ3yjBUCTOCieL5/bh855CCIAkAPYWba0f EIl3OKFTbvCS8rXFAYKciq96wO0UkKTdK5ERopo42cWz18YLqC5C/qXcdkJn2OGZBrhP orXQ== X-Gm-Message-State: AMke39lkKUNfLHgIQQkEoSYCN8MT2wOnvubOifkqE9NDLxNrIi0iU7LZ2nQkq5pgn0D8M9Lb X-Received: by 10.25.199.66 with SMTP id x63mr1441861lff.161.1486654480398; Thu, 09 Feb 2017 07:34:40 -0800 (PST) Received: from gnarp.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id e86sm3670614lji.32.2017.02.09.07.34.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 09 Feb 2017 07:34:39 -0800 (PST) From: Linus Walleij To: linux-mmc@vger.kernel.org, Ulf Hansson , Adrian Hunter , Paolo Valente Cc: Chunyan Zhang , Baolin Wang , linux-block@vger.kernel.org, Jens Axboe , Christoph Hellwig , Arnd Bergmann , Linus Walleij Subject: [PATCH 03/16] mmc: core: refactor mmc_request_done() Date: Thu, 9 Feb 2017 16:33:50 +0100 Message-Id: <20170209153403.9730-4-linus.walleij@linaro.org> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170209153403.9730-1-linus.walleij@linaro.org> References: <20170209153403.9730-1-linus.walleij@linaro.org> Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org We have this construction: if (a && b && !c) finalize; else block; finalize; Which is equivalent by boolean logic to: if (!a || !b || c) block; finalize; Which is simpler code. Signed-off-by: Linus Walleij --- drivers/mmc/core/core.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Reviewed-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index b2e7a6dfcbf0..8dbed198750f 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -172,14 +172,16 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) trace_mmc_request_done(host, mrq); - if (err && cmd->retries && !mmc_card_removed(host->card)) { - /* - * Request starter must handle retries - see - * mmc_wait_for_req_done(). - */ - if (mrq->done) - mrq->done(mrq); - } else { + /* + * We list various conditions for the command to be considered + * properly done: + * + * - There was no error, OK fine then + * - We are not doing some kind of retry + * - The card was removed (...so just complete everything no matter + * if there are errors or retries) + */ + if (!err || !cmd->retries || mmc_card_removed(host->card)) { mmc_should_fail_request(host, mrq); if (!host->ongoing_mrq) @@ -211,10 +213,13 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) mrq->stop->resp[0], mrq->stop->resp[1], mrq->stop->resp[2], mrq->stop->resp[3]); } - - if (mrq->done) - mrq->done(mrq); } + /* + * Request starter must handle retries - see + * mmc_wait_for_req_done(). + */ + if (mrq->done) + mrq->done(mrq); } EXPORT_SYMBOL(mmc_request_done); From patchwork Thu Feb 9 15:33:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 93734 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp88113qgi; Thu, 9 Feb 2017 08:39:28 -0800 (PST) X-Received: by 10.98.13.18 with SMTP id v18mr4738506pfi.62.1486658368127; Thu, 09 Feb 2017 08:39:28 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j191si10522470pgd.132.2017.02.09.08.39.27; Thu, 09 Feb 2017 08:39:28 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-mmc-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752700AbdBIQj0 (ORCPT + 5 others); Thu, 9 Feb 2017 11:39:26 -0500 Received: from mail-lf0-f45.google.com ([209.85.215.45]:34917 "EHLO mail-lf0-f45.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752929AbdBIQjZ (ORCPT ); Thu, 9 Feb 2017 11:39:25 -0500 Received: by mail-lf0-f45.google.com with SMTP id n124so5685133lfd.2 for ; Thu, 09 Feb 2017 08:37:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=XW7KvRqBWr3hFy8GfNhHyJ9vA/FQrqihEf8e/iVI+bU=; b=YiSIkY4i3YEIeA+702FdsV1xU3abrDFE4icC/VD6YMjbQB4b6RnDLsnaKgn6ZiQkb8 Pmy7+J3X5LQELchaXX4UluHc29B+sCBqRMp/pIifrkoazBmcn9dSo2f3Xn+DmXCuDS/P p6Bx2waTJNCZ5wQWbDe5B2DCcJuXGIKtvPnWU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=XW7KvRqBWr3hFy8GfNhHyJ9vA/FQrqihEf8e/iVI+bU=; b=PcYPo+3YcmdUE/2HRa8wT0IPjUpYXXzvzNFRmbj+vakLvY7O0Oi4pJf7U12bM9NzXX r8ghf+7MyhVsZB7hA4HhbCC0fS/0dLgVkJsRkdaE28GjS3bxpcWi8pJyEnETKnVt2VGK SOezvf+qjP2ZjzIJkc0mzUhAP2udLoU8JU/I2w5kdaxUJ3npvgzlkimgDNP1ycNhbTrP BFrTR/52pioKiVFD/R3FF5PeblYUnqZTWFl2MH7laT9mXy/9+gsaN8gQMmzqd2UFqf/u U4AlUNZbpMcstmk3QD7v6k4ZHFNutcVWJ/zuWD5AUkDWAi7S4MRkOaUZ/LQsNM4GjCLT IgGA== X-Gm-Message-State: AMke39kJ5aJcoYrdiIJmtZrsNpib6+Fie2vZBkbt5yxOLiYYJhvOSeDB4RUAJTT77FJduUUh X-Received: by 10.25.4.9 with SMTP id 9mr1267455lfe.45.1486654486292; Thu, 09 Feb 2017 07:34:46 -0800 (PST) Received: from gnarp.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id e86sm3670614lji.32.2017.02.09.07.34.44 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 09 Feb 2017 07:34:45 -0800 (PST) From: Linus Walleij To: linux-mmc@vger.kernel.org, Ulf Hansson , Adrian Hunter , Paolo Valente Cc: Chunyan Zhang , Baolin Wang , linux-block@vger.kernel.org, Jens Axboe , Christoph Hellwig , Arnd Bergmann , Linus Walleij Subject: [PATCH 04/16] mmc: core: move the asynchronous post-processing Date: Thu, 9 Feb 2017 16:33:51 +0100 Message-Id: <20170209153403.9730-5-linus.walleij@linaro.org> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170209153403.9730-1-linus.walleij@linaro.org> References: <20170209153403.9730-1-linus.walleij@linaro.org> Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org This moves the asynchronous post-processing of a request over to the finalization function. The patch has a slight semantic change: Both places will be in the code path for if (host->areq) and in the same sequence, but before this patch, the next request was started before performing post-processing. The effect is that whereas before, the post- and preprocessing happened after starting the next request, now the preprocessing will happen after the request is done and before the next has started which would cut half of the pre/post optimizations out. The idea is to later move the finalization to a worker started by mmc_request_done() and introduce a completion where the code now has a TODO comment so that we can push in a new request as soon as the host has completed the previous one. Signed-off-by: Linus Walleij --- drivers/mmc/core/core.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 8dbed198750f..0972c649ea7a 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -643,6 +643,9 @@ static enum mmc_blk_status mmc_finalize_areq(struct mmc_host *host) mmc_start_bkops(host->card, true); } + /* Successfully postprocess the old request at this point */ + mmc_post_req(host, host->areq->mrq, 0); + return status; } @@ -687,10 +690,6 @@ struct mmc_async_req *mmc_start_areq(struct mmc_host *host, if (status == MMC_BLK_SUCCESS && areq) start_err = __mmc_start_data_req(host, areq->mrq); - /* Postprocess the old request at this point */ - if (host->areq) - mmc_post_req(host, host->areq->mrq, 0); - /* Cancel a prepared request if it was not started. */ if ((status != MMC_BLK_SUCCESS || start_err) && areq) mmc_post_req(host, areq->mrq, -EINVAL); From patchwork Thu Feb 9 15:33:52 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 93719 Delivered-To: patch@linaro.org Received: by 10.182.3.34 with SMTP id 2csp81245obz; Thu, 9 Feb 2017 07:36:23 -0800 (PST) X-Received: by 10.98.211.8 with SMTP id q8mr4356619pfg.164.1486654583234; Thu, 09 Feb 2017 07:36:23 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p1si10315679pga.393.2017.02.09.07.36.23; Thu, 09 Feb 2017 07:36:23 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-mmc-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753929AbdBIPgK (ORCPT + 5 others); Thu, 9 Feb 2017 10:36:10 -0500 Received: from mail-lf0-f52.google.com ([209.85.215.52]:33873 "EHLO mail-lf0-f52.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752162AbdBIPgI (ORCPT ); Thu, 9 Feb 2017 10:36:08 -0500 Received: by mail-lf0-f52.google.com with SMTP id v186so4542444lfa.1 for ; Thu, 09 Feb 2017 07:34:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Mu/ARdi/IpU+hzF3TBvWTiggjuulaAkuB4VzBddZvoE=; b=NE0SCJI7mbFCa+DVwLZOy1KzL80Ih5bmRJQELqkycdP20FWaY9bcZBTE45CoCseEOd TFuK90ijwn6A8tV6RaK6YXFbBIJIMxPy2FdegGDQIrxQMiIXc4sjMOnlLFseB5u5Ya4I pwrQ3F3C+E7TP4AAsVFh4VYeuILxONx73C5VA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Mu/ARdi/IpU+hzF3TBvWTiggjuulaAkuB4VzBddZvoE=; b=loGj+xK+mNQ76YGxmQC15Bb9biNSS7Vj+gWhyiry8nmRNKm9kyChsKJQ6T7S0iBhvq oXRZvjSUawKfADp1A9ifLs0P/hRg9CasPVTMr2Dc6ZeDBuaeNcAt89hXW87XZPklZH2D Wmdl1yEXCEvQcNt334jjOttG2oaUH7ror76/CLColRjfkOTPIQFxxKNDAawpn8EF6XXU cldoMKRgVa6hUmynCoTJMqSKhJN6Oh23vCF61tCMLwspGLk0jOg8p3z3iNhfrTfa1zbs HaN2qBgA7lIsAv6o8vuyO7FxlnDl9S/2UgU+ryl/2v6jAWoLCLFllZziNkjPrp1Y3UQ8 QavA== X-Gm-Message-State: AMke39lFd1rk1NQwAMcRUZFtNSnJeL2pcUm23JO9snfCmfn9o7Jm0JxD1RxbCjJkb/BFLp9j X-Received: by 10.25.65.15 with SMTP id o15mr1182943lfa.14.1486654492060; Thu, 09 Feb 2017 07:34:52 -0800 (PST) Received: from gnarp.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id e86sm3670614lji.32.2017.02.09.07.34.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 09 Feb 2017 07:34:50 -0800 (PST) From: Linus Walleij To: linux-mmc@vger.kernel.org, Ulf Hansson , Adrian Hunter , Paolo Valente Cc: Chunyan Zhang , Baolin Wang , linux-block@vger.kernel.org, Jens Axboe , Christoph Hellwig , Arnd Bergmann , Linus Walleij Subject: [PATCH 05/16] mmc: core: add a kthread for completing requests Date: Thu, 9 Feb 2017 16:33:52 +0100 Message-Id: <20170209153403.9730-6-linus.walleij@linaro.org> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170209153403.9730-1-linus.walleij@linaro.org> References: <20170209153403.9730-1-linus.walleij@linaro.org> Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org As we want to complete requests autonomously from feeding the host with new requests, we create a worker thread to deal with this specifically in response to the callback from a host driver. This patch just adds the worker, later patches will make use of it. Signed-off-by: Linus Walleij --- drivers/mmc/core/core.c | 6 ++++++ drivers/mmc/core/host.c | 2 +- include/linux/mmc/host.h | 5 +++++ 3 files changed, 12 insertions(+), 1 deletion(-) -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Reviewed-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 0972c649ea7a..663799240635 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -2794,6 +2794,10 @@ void mmc_start_host(struct mmc_host *host) host->f_init = max(freqs[0], host->f_min); host->rescan_disable = 0; host->ios.power_mode = MMC_POWER_UNDEFINED; + /* Worker for completing requests */ + host->req_done_worker_task = kthread_run(kthread_worker_fn, + &host->req_done_worker, + "mmc%d-reqdone", host->index); if (!(host->caps2 & MMC_CAP2_NO_PRESCAN_POWERUP)) { mmc_claim_host(host); @@ -2818,6 +2822,8 @@ void mmc_stop_host(struct mmc_host *host) host->rescan_disable = 1; cancel_delayed_work_sync(&host->detect); + kthread_flush_worker(&host->req_done_worker); + kthread_stop(host->req_done_worker_task); /* clear pm flags now and let card drivers set them as needed */ host->pm_flags = 0; diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 98f25ffb4258..d33e2b260bf3 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -388,7 +388,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) init_waitqueue_head(&host->wq); INIT_DELAYED_WORK(&host->detect, mmc_rescan); setup_timer(&host->retune_timer, mmc_retune_timer, (unsigned long)host); - + kthread_init_worker(&host->req_done_worker); /* * By default, hosts do not support SGIO or large requests. * They have to set these according to their abilities. diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 97699d55b2ae..b04f8cd51c82 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -375,6 +376,10 @@ struct mmc_host { struct mmc_async_req *areq; /* active async req */ struct mmc_context_info context_info; /* async synchronization info */ + /* finalization work thread, handles finalizing requests */ + struct kthread_worker req_done_worker; + struct task_struct *req_done_worker_task; + /* Ongoing data transfer that allows commands during transfer */ struct mmc_request *ongoing_mrq; From patchwork Thu Feb 9 15:33:53 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 93731 Delivered-To: patch@linaro.org Received: by 10.182.3.34 with SMTP id 2csp83650obz; Thu, 9 Feb 2017 07:41:13 -0800 (PST) X-Received: by 10.98.192.72 with SMTP id x69mr4424514pff.129.1486654873816; Thu, 09 Feb 2017 07:41:13 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c7si10324262pgn.352.2017.02.09.07.41.13; Thu, 09 Feb 2017 07:41:13 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-mmc-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751226AbdBIPlM (ORCPT + 5 others); Thu, 9 Feb 2017 10:41:12 -0500 Received: from mail-lf0-f41.google.com ([209.85.215.41]:34295 "EHLO mail-lf0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751829AbdBIPlM (ORCPT ); Thu, 9 Feb 2017 10:41:12 -0500 Received: by mail-lf0-f41.google.com with SMTP id v186so4657690lfa.1 for ; Thu, 09 Feb 2017 07:41:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=+ji8c0xOuruyO0fLDwcS0ms4RqFCsXpbSP9FKq4pmIY=; b=NG8GCr/g4gkEPabOmV/zvK3afoGecuih9Np3mjdGzfiGql2+6XO8dJtr1eEujR3sgv ojB7aYF6X/0kdNXzplt1cabhmMvLZ51I2mdb1dk5lVoww2tM9gAiLgJEqVKl7dkkTRyY m4sxbXnUJgblBhKN2oyzfNu/u1s5Z3BECkZto= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=+ji8c0xOuruyO0fLDwcS0ms4RqFCsXpbSP9FKq4pmIY=; b=evbuHRtN7gaUAi5iJGbe5Zyme8MRF+sf02is8prBe7UVBtzlxuwFmkTMb3DYzHwu1K M6INx1OmxsL3+yNCrB7DFRrBd2OHBmdBwYLIjpzxP+J93bEGF72lKlwx+/m/Yo92KHei S3kn/g17WBWirjYOG9/YmCONdozRVvaXsT+i6+WxsoP3Ks+zhT10Ltc80GJVo9EcY8Oc StOLrya79p0olvTcq6ZgWXyijnmZhHWaS5DkbwmNcsjkD2vkjupwoHh0iLz20c+yXS2t D9tE4+JTib5Rq34dcDiAQKI/tUz8RfWle5jmWKEWzQy5lbiila3yvAmZGipQTsf9efny CUvA== X-Gm-Message-State: AMke39nwFUYtyDdmQCVbU6JsQYE/PUAmYqwWORZoTpPJEWexVAuBsoLr3Xexz3CYBPGK4nTb X-Received: by 10.25.203.87 with SMTP id b84mr1263845lfg.158.1486654497858; Thu, 09 Feb 2017 07:34:57 -0800 (PST) Received: from gnarp.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id e86sm3670614lji.32.2017.02.09.07.34.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 09 Feb 2017 07:34:56 -0800 (PST) From: Linus Walleij To: linux-mmc@vger.kernel.org, Ulf Hansson , Adrian Hunter , Paolo Valente Cc: Chunyan Zhang , Baolin Wang , linux-block@vger.kernel.org, Jens Axboe , Christoph Hellwig , Arnd Bergmann , Linus Walleij Subject: [PATCH 06/16] mmc: core: replace waitqueue with worker Date: Thu, 9 Feb 2017 16:33:53 +0100 Message-Id: <20170209153403.9730-7-linus.walleij@linaro.org> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170209153403.9730-1-linus.walleij@linaro.org> References: <20170209153403.9730-1-linus.walleij@linaro.org> Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org The waitqueue in the host context is there to signal back from mmc_request_done() through mmc_wait_data_done() that the hardware is done with a command, and when the wait is over, the core will typically submit the next asynchronous request that is pending just waiting for the hardware to be available. This is in the way for letting the mmc_request_done() trigger the report up to the block layer that a block request is finished. Re-jig this as a first step, remvoving the waitqueue and introducing a work that will run after a completed asynchronous request, finalizing that request, including retransmissions, and eventually reporting back with a completion and a status code to the asynchronous issue method. This had the upside that we can remove the MMC_BLK_NEW_REQUEST status code and the "new_request" state in the request queue that is only there to make the state machine spin out the first time we send a request. Introduce a workqueue in the host for handling just this, and then a work and completion in the asynchronous request to deal with this mechanism. This is a central change that let us do many other changes since we have broken the submit and complete code paths in two, and we can potentially remove the NULL flushing of the asynchronous pipeline and report block requests as finished directly from the worker. Signed-off-by: Linus Walleij --- drivers/mmc/core/block.c | 7 ++-- drivers/mmc/core/core.c | 84 +++++++++++++++++++++++------------------------- drivers/mmc/core/queue.c | 6 ---- drivers/mmc/core/queue.h | 1 - include/linux/mmc/core.h | 3 +- include/linux/mmc/host.h | 7 ++-- 6 files changed, 51 insertions(+), 57 deletions(-) -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Reviewed-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index c49c90dba839..c459d80c66bf 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -1562,6 +1562,8 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, mqrq->areq.mrq = &brq->mrq; mqrq->areq.err_check = mmc_blk_err_check; + mqrq->areq.host = card->host; + kthread_init_work(&mqrq->areq.finalization_work, mmc_finalize_areq); mmc_queue_bounce_pre(mqrq); } @@ -1672,8 +1674,6 @@ static void mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *new_req) * and there is nothing more to do until it is * complete. */ - if (status == MMC_BLK_NEW_REQUEST) - mq->new_request = true; return; } @@ -1811,7 +1811,6 @@ void mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) goto out; } - mq->new_request = false; if (req && req_op(req) == REQ_OP_DISCARD) { /* complete ongoing async transfer before issuing discard */ if (card->host->areq) @@ -1832,7 +1831,7 @@ void mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) } out: - if ((!req && !mq->new_request) || req_is_special) + if (!req || req_is_special) /* * Release host when there are no more requests * and after special request(discard, flush) is done. diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 663799240635..8ecf61e51662 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -415,10 +415,13 @@ EXPORT_SYMBOL(mmc_start_bkops); */ static void mmc_wait_data_done(struct mmc_request *mrq) { - struct mmc_context_info *context_info = &mrq->host->context_info; + struct mmc_host *host = mrq->host; + struct mmc_context_info *context_info = &host->context_info; + struct mmc_async_req *areq = host->areq; context_info->is_done_rcv = true; - wake_up_interruptible(&context_info->wait); + /* Schedule a work to deal with finalizing this request */ + kthread_queue_work(&host->req_done_worker, &areq->finalization_work); } static void mmc_wait_done(struct mmc_request *mrq) @@ -592,43 +595,34 @@ static void mmc_post_req(struct mmc_host *host, struct mmc_request *mrq, * will return MMC_BLK_SUCCESS if no request was * going on. */ -static enum mmc_blk_status mmc_finalize_areq(struct mmc_host *host) +void mmc_finalize_areq(struct kthread_work *work) { + struct mmc_async_req *areq = + container_of(work, struct mmc_async_req, finalization_work); + struct mmc_host *host = areq->host; struct mmc_context_info *context_info = &host->context_info; - enum mmc_blk_status status; - - if (!host->areq) - return MMC_BLK_SUCCESS; - - while (1) { - wait_event_interruptible(context_info->wait, - (context_info->is_done_rcv || - context_info->is_new_req)); + enum mmc_blk_status status = MMC_BLK_SUCCESS; - if (context_info->is_done_rcv) { - struct mmc_command *cmd; + if (context_info->is_done_rcv) { + struct mmc_command *cmd; - context_info->is_done_rcv = false; - cmd = host->areq->mrq->cmd; + context_info->is_done_rcv = false; + cmd = areq->mrq->cmd; - if (!cmd->error || !cmd->retries || - mmc_card_removed(host->card)) { - status = host->areq->err_check(host->card, - host->areq); - break; /* return status */ - } else { - mmc_retune_recheck(host); - pr_info("%s: req failed (CMD%u): %d, retrying...\n", - mmc_hostname(host), - cmd->opcode, cmd->error); - cmd->retries--; - cmd->error = 0; - __mmc_start_request(host, host->areq->mrq); - continue; /* wait for done/new event again */ - } + if (!cmd->error || !cmd->retries || + mmc_card_removed(host->card)) { + status = areq->err_check(host->card, + areq); + } else { + mmc_retune_recheck(host); + pr_info("%s: req failed (CMD%u): %d, retrying...\n", + mmc_hostname(host), + cmd->opcode, cmd->error); + cmd->retries--; + cmd->error = 0; + __mmc_start_request(host, areq->mrq); + return; /* wait for done/new event again */ } - - return MMC_BLK_NEW_REQUEST; } mmc_retune_release(host); @@ -644,10 +638,12 @@ static enum mmc_blk_status mmc_finalize_areq(struct mmc_host *host) } /* Successfully postprocess the old request at this point */ - mmc_post_req(host, host->areq->mrq, 0); + mmc_post_req(host, areq->mrq, 0); - return status; + areq->finalization_status = status; + complete(&areq->complete); } +EXPORT_SYMBOL(mmc_finalize_areq); /** * mmc_start_areq - start an asynchronous request @@ -677,18 +673,21 @@ struct mmc_async_req *mmc_start_areq(struct mmc_host *host, if (areq) mmc_pre_req(host, areq->mrq); - /* Finalize previous request */ - status = mmc_finalize_areq(host); + /* Finalize previous request, if there is one */ + if (previous) { + wait_for_completion(&previous->complete); + status = previous->finalization_status; + } else { + status = MMC_BLK_SUCCESS; + } if (ret_stat) *ret_stat = status; - /* The previous request is still going on... */ - if (status == MMC_BLK_NEW_REQUEST) - return NULL; - /* Fine so far, start the new request! */ - if (status == MMC_BLK_SUCCESS && areq) + if (status == MMC_BLK_SUCCESS && areq) { + init_completion(&areq->complete); start_err = __mmc_start_data_req(host, areq->mrq); + } /* Cancel a prepared request if it was not started. */ if ((status != MMC_BLK_SUCCESS || start_err) && areq) @@ -2996,7 +2995,6 @@ void mmc_init_context_info(struct mmc_host *host) host->context_info.is_new_req = false; host->context_info.is_done_rcv = false; host->context_info.is_waiting_last_req = false; - init_waitqueue_head(&host->context_info.wait); } static int __init mmc_init(void) diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c index 5cb369c2664b..73250ed8f093 100644 --- a/drivers/mmc/core/queue.c +++ b/drivers/mmc/core/queue.c @@ -86,11 +86,6 @@ static int mmc_queue_thread(void *d) set_current_state(TASK_RUNNING); mmc_blk_issue_rq(mq, req); cond_resched(); - if (mq->new_request) { - mq->new_request = false; - continue; /* fetch again */ - } - /* * Current request becomes previous request * and vice versa. @@ -143,7 +138,6 @@ static void mmc_request_fn(struct request_queue *q) if (cntx->is_waiting_last_req) { cntx->is_new_req = true; - wake_up_interruptible(&cntx->wait); } if (mq->asleep) diff --git a/drivers/mmc/core/queue.h b/drivers/mmc/core/queue.h index e298f100101b..39d8e710287e 100644 --- a/drivers/mmc/core/queue.h +++ b/drivers/mmc/core/queue.h @@ -40,7 +40,6 @@ struct mmc_queue { struct mmc_card *card; struct task_struct *thread; struct semaphore thread_sem; - bool new_request; bool suspended; bool asleep; struct mmc_blk_data *blkdata; diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index a0c63ea28796..5db0fb722c37 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -9,6 +9,7 @@ #define LINUX_MMC_CORE_H #include +#include #include struct mmc_data; @@ -23,7 +24,6 @@ enum mmc_blk_status { MMC_BLK_DATA_ERR, MMC_BLK_ECC_ERR, MMC_BLK_NOMEDIUM, - MMC_BLK_NEW_REQUEST, }; struct mmc_command { @@ -158,6 +158,7 @@ struct mmc_request { struct mmc_card; struct mmc_async_req; +void mmc_finalize_areq(struct kthread_work *work); struct mmc_async_req *mmc_start_areq(struct mmc_host *host, struct mmc_async_req *areq, enum mmc_blk_status *ret_stat); diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index b04f8cd51c82..c5f61f2f2310 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -169,6 +170,10 @@ struct mmc_async_req { * Returns 0 if success otherwise non zero. */ enum mmc_blk_status (*err_check)(struct mmc_card *, struct mmc_async_req *); + struct kthread_work finalization_work; + enum mmc_blk_status finalization_status; + struct completion complete; + struct mmc_host *host; }; /** @@ -192,13 +197,11 @@ struct mmc_slot { * @is_done_rcv wake up reason was done request * @is_new_req wake up reason was new request * @is_waiting_last_req mmc context waiting for single running request - * @wait wait queue */ struct mmc_context_info { bool is_done_rcv; bool is_new_req; bool is_waiting_last_req; - wait_queue_head_t wait; }; struct regulator; From patchwork Thu Feb 9 15:33:54 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 93723 Delivered-To: patch@linaro.org Received: by 10.182.3.34 with SMTP id 2csp81272obz; Thu, 9 Feb 2017 07:36:26 -0800 (PST) X-Received: by 10.99.112.6 with SMTP id l6mr4647850pgc.33.1486654586096; Thu, 09 Feb 2017 07:36:26 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p1si10315679pga.393.2017.02.09.07.36.25; Thu, 09 Feb 2017 07:36:26 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-mmc-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752464AbdBIPgO (ORCPT + 5 others); Thu, 9 Feb 2017 10:36:14 -0500 Received: from mail-lf0-f46.google.com ([209.85.215.46]:36831 "EHLO mail-lf0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752957AbdBIPgI (ORCPT ); Thu, 9 Feb 2017 10:36:08 -0500 Received: by mail-lf0-f46.google.com with SMTP id z134so4498453lff.3 for ; Thu, 09 Feb 2017 07:35:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=JxkPNTaKmWf0vTJfB44NRFuomWpqWZy0ZnKSU/LpDxk=; b=C1NLPCYKr5Ui0fuIF4jYHAfn/jr1I5dg0qxZ+Qv6u8rTmYJCkHIZfcu/85C+siApPF xGs1hMJTB6JxNuSdDRRAiLBng/iwxwJfubadH1jS/BTS30RLFYCmno9dXLiU/494UR/u GAw+Rv+yANOmg8S+n3WEXdbJDNRfx79c2JJrY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=JxkPNTaKmWf0vTJfB44NRFuomWpqWZy0ZnKSU/LpDxk=; b=mwyVZaiR4MMZGaoot3q2Ct++BZL372xkK7YYZ804eEEpw1HF0PSB58ggGJ9tFfTZbW 0+nRdzu2m8oBV7PHxd/dvoHSmdLpeJIjAa+jhH+BNLF11S+E3Mmnd9vuedkDKJC/UDNT 0hSDH6i360IeEYAcW+1YoAkkzo6wc1wlsWxJSvSSkaOeaMRpTAykU6p0XbBlPm57QBOg 749/4aYw82hHQ5y73YYg1/F97UTmthEeIt2lBARYWv3ykrvRBe0FJV4KdnNVXYyKy975 1kRN02cevC5uXm80EBn7hoToyt+UPqbD4lG99MTr8ZTLo3lSEtgNcaoDppumdBJAZwU/ JUwA== X-Gm-Message-State: AMke39me6K1pExxRSqhgpU2ICqOGCzUFXJ2x6ViN6NDQZ+dxrJPIc3ffgWpoltsjoyvlKqEl X-Received: by 10.46.84.78 with SMTP id y14mr1406719ljd.63.1486654502656; Thu, 09 Feb 2017 07:35:02 -0800 (PST) Received: from gnarp.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id e86sm3670614lji.32.2017.02.09.07.35.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 09 Feb 2017 07:35:01 -0800 (PST) From: Linus Walleij To: linux-mmc@vger.kernel.org, Ulf Hansson , Adrian Hunter , Paolo Valente Cc: Chunyan Zhang , Baolin Wang , linux-block@vger.kernel.org, Jens Axboe , Christoph Hellwig , Arnd Bergmann , Linus Walleij Subject: [PATCH 07/16] mmc: core: do away with is_done_rcv Date: Thu, 9 Feb 2017 16:33:54 +0100 Message-Id: <20170209153403.9730-8-linus.walleij@linaro.org> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170209153403.9730-1-linus.walleij@linaro.org> References: <20170209153403.9730-1-linus.walleij@linaro.org> Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org The "is_done_rcv" in the context info for the host is no longer needed: it is clear from context (ha!) that as long as we are waiting for the asynchronous request to come to completion, we are not done receiving data, and when the finalization work has run and completed the completion, we are indeed done. Signed-off-by: Linus Walleij --- drivers/mmc/core/core.c | 40 ++++++++++++++++------------------------ include/linux/mmc/host.h | 2 -- 2 files changed, 16 insertions(+), 26 deletions(-) -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Reviewed-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 8ecf61e51662..fcb40ade9b82 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -416,10 +416,8 @@ EXPORT_SYMBOL(mmc_start_bkops); static void mmc_wait_data_done(struct mmc_request *mrq) { struct mmc_host *host = mrq->host; - struct mmc_context_info *context_info = &host->context_info; struct mmc_async_req *areq = host->areq; - context_info->is_done_rcv = true; /* Schedule a work to deal with finalizing this request */ kthread_queue_work(&host->req_done_worker, &areq->finalization_work); } @@ -551,7 +549,7 @@ EXPORT_SYMBOL(mmc_wait_for_req_done); bool mmc_is_req_done(struct mmc_host *host, struct mmc_request *mrq) { if (host->areq) - return host->context_info.is_done_rcv; + return completion_done(&host->areq->complete); else return completion_done(&mrq->completion); } @@ -600,29 +598,24 @@ void mmc_finalize_areq(struct kthread_work *work) struct mmc_async_req *areq = container_of(work, struct mmc_async_req, finalization_work); struct mmc_host *host = areq->host; - struct mmc_context_info *context_info = &host->context_info; enum mmc_blk_status status = MMC_BLK_SUCCESS; + struct mmc_command *cmd; - if (context_info->is_done_rcv) { - struct mmc_command *cmd; - - context_info->is_done_rcv = false; - cmd = areq->mrq->cmd; + cmd = areq->mrq->cmd; - if (!cmd->error || !cmd->retries || - mmc_card_removed(host->card)) { - status = areq->err_check(host->card, - areq); - } else { - mmc_retune_recheck(host); - pr_info("%s: req failed (CMD%u): %d, retrying...\n", - mmc_hostname(host), - cmd->opcode, cmd->error); - cmd->retries--; - cmd->error = 0; - __mmc_start_request(host, areq->mrq); - return; /* wait for done/new event again */ - } + if (!cmd->error || !cmd->retries || + mmc_card_removed(host->card)) { + status = areq->err_check(host->card, + areq); + } else { + mmc_retune_recheck(host); + pr_info("%s: req failed (CMD%u): %d, retrying...\n", + mmc_hostname(host), + cmd->opcode, cmd->error); + cmd->retries--; + cmd->error = 0; + __mmc_start_request(host, areq->mrq); + return; /* wait for done/new event again */ } mmc_retune_release(host); @@ -2993,7 +2986,6 @@ void mmc_unregister_pm_notifier(struct mmc_host *host) void mmc_init_context_info(struct mmc_host *host) { host->context_info.is_new_req = false; - host->context_info.is_done_rcv = false; host->context_info.is_waiting_last_req = false; } diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index c5f61f2f2310..cbb40682024a 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -194,12 +194,10 @@ struct mmc_slot { /** * mmc_context_info - synchronization details for mmc context - * @is_done_rcv wake up reason was done request * @is_new_req wake up reason was new request * @is_waiting_last_req mmc context waiting for single running request */ struct mmc_context_info { - bool is_done_rcv; bool is_new_req; bool is_waiting_last_req; }; From patchwork Thu Feb 9 15:33:55 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 93720 Delivered-To: patch@linaro.org Received: by 10.182.3.34 with SMTP id 2csp81254obz; Thu, 9 Feb 2017 07:36:24 -0800 (PST) X-Received: by 10.84.129.3 with SMTP id 3mr4928502plb.153.1486654584015; Thu, 09 Feb 2017 07:36:24 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p1si10315679pga.393.2017.02.09.07.36.23; Thu, 09 Feb 2017 07:36:24 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-mmc-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752954AbdBIPgQ (ORCPT + 5 others); Thu, 9 Feb 2017 10:36:16 -0500 Received: from mail-lf0-f43.google.com ([209.85.215.43]:36860 "EHLO mail-lf0-f43.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753920AbdBIPgI (ORCPT ); Thu, 9 Feb 2017 10:36:08 -0500 Received: by mail-lf0-f43.google.com with SMTP id z134so4499843lff.3 for ; Thu, 09 Feb 2017 07:35:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=iz4KMC/d9NZUEsp3w+X1dhR5CGyVn8pJb3DutyhS2T4=; b=j9/M747JmBKsu1htjr61Jtmda/bOMPnyLt10ksv8tuZlguqqJex4VqHHGgkAret1jA Ge9Hlw9TAnkbaX3SoMQQiBEChjPWFmdHXfWJJw9ceQR9SCDIVpJGGZG8G3P2rZophMIF PYjD2/sZDxi4bRkBcM/5gdzobjO8BG95xzZD0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=iz4KMC/d9NZUEsp3w+X1dhR5CGyVn8pJb3DutyhS2T4=; b=iDoTrXhmR/i3Y5Oat1ai+Jr2lafbr6yU5R51bvof72FLPSbdGCn+d6zWkkOeh0m/k4 iiJoPhzEzR7OHc5FOMtjz2bMpEXWSl3uV+SC/2l/WQPkGcbLEWA6WmaPEebTBzlOhIKL OaGEHqLG/XepfSOFa6QNyyhDJUgTo0MJmaKrnuVh0dhx/Qp2x6OtNO+f9Te5cmD23tsX 8vm6ZHzYjw8q3bkRSClgS2v79Ca2cmJoY5PptxXnx7Qo/75kj2tARbG7ESBGUS5RPCsH WIJHMesry5YVPxP1iUYImxFqVgmPJKdr9a2e3KBaS5B/jeXTQfp3AzEVjDxguNc9BUwt PdBQ== X-Gm-Message-State: AMke39mm3TtsU251ndNuiNMFRnTTAyZ2gyX3jW86csiwgmQ0kGTPm957PlwF1p7d+zbWPGcg X-Received: by 10.25.200.14 with SMTP id y14mr1328251lff.98.1486654507119; Thu, 09 Feb 2017 07:35:07 -0800 (PST) Received: from gnarp.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id e86sm3670614lji.32.2017.02.09.07.35.05 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 09 Feb 2017 07:35:05 -0800 (PST) From: Linus Walleij To: linux-mmc@vger.kernel.org, Ulf Hansson , Adrian Hunter , Paolo Valente Cc: Chunyan Zhang , Baolin Wang , linux-block@vger.kernel.org, Jens Axboe , Christoph Hellwig , Arnd Bergmann , Linus Walleij Subject: [PATCH 08/16] mmc: core: do away with is_new_req Date: Thu, 9 Feb 2017 16:33:55 +0100 Message-Id: <20170209153403.9730-9-linus.walleij@linaro.org> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170209153403.9730-1-linus.walleij@linaro.org> References: <20170209153403.9730-1-linus.walleij@linaro.org> Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org The host context member "is_new_req" is only assigned values, never checked. Delete it. Signed-off-by: Linus Walleij --- drivers/mmc/core/core.c | 1 - drivers/mmc/core/queue.c | 5 ----- include/linux/mmc/host.h | 2 -- 3 files changed, 8 deletions(-) -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Reviewed-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index fcb40ade9b82..933a4d1f20d5 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -2985,7 +2985,6 @@ void mmc_unregister_pm_notifier(struct mmc_host *host) */ void mmc_init_context_info(struct mmc_host *host) { - host->context_info.is_new_req = false; host->context_info.is_waiting_last_req = false; } diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c index 73250ed8f093..63927ffd6825 100644 --- a/drivers/mmc/core/queue.c +++ b/drivers/mmc/core/queue.c @@ -66,7 +66,6 @@ static int mmc_queue_thread(void *d) req = blk_fetch_request(q); mq->asleep = false; cntx->is_waiting_last_req = false; - cntx->is_new_req = false; if (!req) { /* * Dispatch queue is empty so set flags for @@ -136,10 +135,6 @@ static void mmc_request_fn(struct request_queue *q) cntx = &mq->card->host->context_info; - if (cntx->is_waiting_last_req) { - cntx->is_new_req = true; - } - if (mq->asleep) wake_up_process(mq->thread); } diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index cbb40682024a..970d7f9b1eba 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -194,11 +194,9 @@ struct mmc_slot { /** * mmc_context_info - synchronization details for mmc context - * @is_new_req wake up reason was new request * @is_waiting_last_req mmc context waiting for single running request */ struct mmc_context_info { - bool is_new_req; bool is_waiting_last_req; }; From patchwork Thu Feb 9 15:33:56 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 93721 Delivered-To: patch@linaro.org Received: by 10.182.3.34 with SMTP id 2csp81256obz; Thu, 9 Feb 2017 07:36:24 -0800 (PST) X-Received: by 10.84.142.101 with SMTP id 92mr4952744plw.66.1486654584284; Thu, 09 Feb 2017 07:36:24 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p1si10315679pga.393.2017.02.09.07.36.24; Thu, 09 Feb 2017 07:36:24 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-mmc-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753920AbdBIPgR (ORCPT + 5 others); Thu, 9 Feb 2017 10:36:17 -0500 Received: from mail-lf0-f48.google.com ([209.85.215.48]:35866 "EHLO mail-lf0-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752976AbdBIPgI (ORCPT ); Thu, 9 Feb 2017 10:36:08 -0500 Received: by mail-lf0-f48.google.com with SMTP id z134so4501189lff.3 for ; Thu, 09 Feb 2017 07:35:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=npCRU42dkx1AZadVlBLWrFeHcs+g7NhTe46w4kLrtjU=; b=IsA3EFpLPjz7hixrUrxiqFNXWgZnCT6lXaICdq/yPjiT4FJdu/rtH7v61HrzYCIKo8 O33ePVfA1ut//DAl7Tg3U3dom0dPdOyVdnpsME5lp0/OAWDUkY6bx8sbinsNBZYyxzIR DuUNvJ6dlVEsulJMnxtMvQo8CrKM/pZi2+P6M= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=npCRU42dkx1AZadVlBLWrFeHcs+g7NhTe46w4kLrtjU=; b=JNoC8YBvVMe5vveBUP9agNpGxKZjNGwLU6M6rKL+AofIlKLryIxroW6nYI+N8gbNfL lGyzwkQxUNvFKkYZUnvrnix1gjQ2qK5JHXaHF7dOOJaGMvm7y4ZtU6K+t2vo7W63mIWj zKXyFc9UvEGk2VtAGRmjWxhP8A4gVIC41QJOTRh78V9zyLngOL/hcXNkMqbEzsNT9S+E LfJlW0oMO2HJFmF7Pk4JqNeaoqPXE/ubd2/njPAnUqyJkbAspoPGcRHPNZ4+wTf1yE4P 8SFbFQReNsdLUXB/AUT0lfpRlfp1RX/X/lXM1T05fUU/rNC0bVcbsaIQ1+q4dsb+9fje 7H2Q== X-Gm-Message-State: AMke39nb5fumPVEDywd5V5YUXcGfFy/UF2rH2hvSLMmCgsCkHacD6KPyD2KahTuD/LGRBxm1 X-Received: by 10.46.1.74 with SMTP id 71mr1419027ljb.74.1486654511705; Thu, 09 Feb 2017 07:35:11 -0800 (PST) Received: from gnarp.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id e86sm3670614lji.32.2017.02.09.07.35.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 09 Feb 2017 07:35:10 -0800 (PST) From: Linus Walleij To: linux-mmc@vger.kernel.org, Ulf Hansson , Adrian Hunter , Paolo Valente Cc: Chunyan Zhang , Baolin Wang , linux-block@vger.kernel.org, Jens Axboe , Christoph Hellwig , Arnd Bergmann , Linus Walleij Subject: [PATCH 09/16] mmc: core: kill off the context info Date: Thu, 9 Feb 2017 16:33:56 +0100 Message-Id: <20170209153403.9730-10-linus.walleij@linaro.org> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170209153403.9730-1-linus.walleij@linaro.org> References: <20170209153403.9730-1-linus.walleij@linaro.org> Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org The last member of the context info: is_waiting_last_req is just assigned values, never checked. Delete that and the whole context info as a result. Signed-off-by: Linus Walleij --- drivers/mmc/core/bus.c | 1 - drivers/mmc/core/core.c | 13 ------------- drivers/mmc/core/core.h | 2 -- drivers/mmc/core/queue.c | 9 +-------- include/linux/mmc/host.h | 9 --------- 5 files changed, 1 insertion(+), 33 deletions(-) -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Reviewed-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 301246513a37..22ed11ac961b 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -348,7 +348,6 @@ int mmc_add_card(struct mmc_card *card) #ifdef CONFIG_DEBUG_FS mmc_add_card_debugfs(card); #endif - mmc_init_context_info(card->host); card->dev.of_node = mmc_of_find_child_device(card->host, 0); diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 933a4d1f20d5..4b84f18518ac 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -2975,19 +2975,6 @@ void mmc_unregister_pm_notifier(struct mmc_host *host) } #endif -/** - * mmc_init_context_info() - init synchronization context - * @host: mmc host - * - * Init struct context_info needed to implement asynchronous - * request mechanism, used by mmc core, host driver and mmc requests - * supplier. - */ -void mmc_init_context_info(struct mmc_host *host) -{ - host->context_info.is_waiting_last_req = false; -} - static int __init mmc_init(void) { int ret; diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index 8a95c82554be..620bea373c3a 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h @@ -90,8 +90,6 @@ void mmc_remove_host_debugfs(struct mmc_host *host); void mmc_add_card_debugfs(struct mmc_card *card); void mmc_remove_card_debugfs(struct mmc_card *card); -void mmc_init_context_info(struct mmc_host *host); - int mmc_execute_tuning(struct mmc_card *card); int mmc_hs200_to_hs400(struct mmc_card *card); int mmc_hs400_to_hs200(struct mmc_card *card); diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c index 63927ffd6825..a845fe8d4fd1 100644 --- a/drivers/mmc/core/queue.c +++ b/drivers/mmc/core/queue.c @@ -53,7 +53,6 @@ static int mmc_queue_thread(void *d) { struct mmc_queue *mq = d; struct request_queue *q = mq->queue; - struct mmc_context_info *cntx = &mq->card->host->context_info; current->flags |= PF_MEMALLOC; @@ -65,15 +64,12 @@ static int mmc_queue_thread(void *d) set_current_state(TASK_INTERRUPTIBLE); req = blk_fetch_request(q); mq->asleep = false; - cntx->is_waiting_last_req = false; if (!req) { /* * Dispatch queue is empty so set flags for * mmc_request_fn() to wake us up. */ - if (mq->mqrq_prev->req) - cntx->is_waiting_last_req = true; - else + if (!mq->mqrq_prev->req) mq->asleep = true; } mq->mqrq_cur->req = req; @@ -123,7 +119,6 @@ static void mmc_request_fn(struct request_queue *q) { struct mmc_queue *mq = q->queuedata; struct request *req; - struct mmc_context_info *cntx; if (!mq) { while ((req = blk_fetch_request(q)) != NULL) { @@ -133,8 +128,6 @@ static void mmc_request_fn(struct request_queue *q) return; } - cntx = &mq->card->host->context_info; - if (mq->asleep) wake_up_process(mq->thread); } diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 970d7f9b1eba..a7c0ed887391 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -192,14 +192,6 @@ struct mmc_slot { void *handler_priv; }; -/** - * mmc_context_info - synchronization details for mmc context - * @is_waiting_last_req mmc context waiting for single running request - */ -struct mmc_context_info { - bool is_waiting_last_req; -}; - struct regulator; struct mmc_pwrseq; @@ -373,7 +365,6 @@ struct mmc_host { struct dentry *debugfs_root; struct mmc_async_req *areq; /* active async req */ - struct mmc_context_info context_info; /* async synchronization info */ /* finalization work thread, handles finalizing requests */ struct kthread_worker req_done_worker; From patchwork Thu Feb 9 15:33:57 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 93722 Delivered-To: patch@linaro.org Received: by 10.182.3.34 with SMTP id 2csp81264obz; Thu, 9 Feb 2017 07:36:25 -0800 (PST) X-Received: by 10.84.193.36 with SMTP id e33mr5028459pld.4.1486654585490; Thu, 09 Feb 2017 07:36:25 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p1si10315679pga.393.2017.02.09.07.36.25; Thu, 09 Feb 2017 07:36:25 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-mmc-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752685AbdBIPgQ (ORCPT + 5 others); Thu, 9 Feb 2017 10:36:16 -0500 Received: from mail-lf0-f47.google.com ([209.85.215.47]:35040 "EHLO mail-lf0-f47.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753923AbdBIPgI (ORCPT ); Thu, 9 Feb 2017 10:36:08 -0500 Received: by mail-lf0-f47.google.com with SMTP id n124so4533148lfd.2 for ; Thu, 09 Feb 2017 07:35:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=5cBy3a2SdO/KkSMLpJs+N9esxzJ6Dg/TfJOs50r40CA=; b=IuKPuttp3UNMkRzwU7SYHJLK0VQwfm1ur0OvS2ibIfNFZR/ryVarWzlNRV5BKwHpMg R/droVIEDUIK/AmrYJn7sa3vtY3zuNSeHLPSmdbXmVT6XUm59LZwW/81qwRqGxEsMywi lEBEgB3ZX5En8fqD0Y3icZcHRPEuC3fqy10ik= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=5cBy3a2SdO/KkSMLpJs+N9esxzJ6Dg/TfJOs50r40CA=; b=gWi/ioV9Bh2FanexaD7k46/V1KXfzgjX8a1XN19eD2rAqFvU4ox0fq0/iCDqDiGLCs 7KDoUVCCGaBDHRxeSqlaMDDWBAzFpDG7y4HveskVp7TM75GoM4kTEwtQaVBTVTbAJBRJ Ue9/M2CV4S9Nixg6/Tvs2kJsqzBNSM34GEMI2VMHiklisK0h4n09lrJbPtN+mY2h5uJg oWTtoYkWuhzLKQGnj0QeG1b8Na5AeOVTg8ZQbzF/eQW2Jq2Z8U3cpCbkTo57mJoki+96 ggM7Y9QktTOslYTMOY3ETxnb5v1o6NfAis6s3oJFRC90JF5x+EMBrY80zHO7Fd+tjw1V 2zDA== X-Gm-Message-State: AMke39kVucumxAh1Ak8UOUdTH1UwT4n14SxPb+RsonooypaToqE8XBC99O+A80SMlntZB1cc X-Received: by 10.25.104.20 with SMTP id d20mr1378164lfc.108.1486654516308; Thu, 09 Feb 2017 07:35:16 -0800 (PST) Received: from gnarp.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id e86sm3670614lji.32.2017.02.09.07.35.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 09 Feb 2017 07:35:15 -0800 (PST) From: Linus Walleij To: linux-mmc@vger.kernel.org, Ulf Hansson , Adrian Hunter , Paolo Valente Cc: Chunyan Zhang , Baolin Wang , linux-block@vger.kernel.org, Jens Axboe , Christoph Hellwig , Arnd Bergmann , Linus Walleij Subject: [PATCH 10/16] mmc: queue: simplify queue logic Date: Thu, 9 Feb 2017 16:33:57 +0100 Message-Id: <20170209153403.9730-11-linus.walleij@linaro.org> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170209153403.9730-1-linus.walleij@linaro.org> References: <20170209153403.9730-1-linus.walleij@linaro.org> Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org The if() statment checking if there is no current or previous request is now just looking ahead at something that will be concluded a few lines below. Simplify the logic by moving the assignment of .asleep. Signed-off-by: Linus Walleij --- drivers/mmc/core/queue.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Reviewed-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c index a845fe8d4fd1..bc116709c806 100644 --- a/drivers/mmc/core/queue.c +++ b/drivers/mmc/core/queue.c @@ -64,14 +64,6 @@ static int mmc_queue_thread(void *d) set_current_state(TASK_INTERRUPTIBLE); req = blk_fetch_request(q); mq->asleep = false; - if (!req) { - /* - * Dispatch queue is empty so set flags for - * mmc_request_fn() to wake us up. - */ - if (!mq->mqrq_prev->req) - mq->asleep = true; - } mq->mqrq_cur->req = req; spin_unlock_irq(q->queue_lock); @@ -95,6 +87,7 @@ static int mmc_queue_thread(void *d) mq->mqrq_prev->req = NULL; swap(mq->mqrq_prev, mq->mqrq_cur); } else { + mq->asleep = true; if (kthread_should_stop()) { set_current_state(TASK_RUNNING); break; From patchwork Thu Feb 9 15:33:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 93729 Delivered-To: patch@linaro.org Received: by 10.182.3.34 with SMTP id 2csp81443obz; Thu, 9 Feb 2017 07:36:45 -0800 (PST) X-Received: by 10.98.150.70 with SMTP id c67mr4371264pfe.84.1486654604912; Thu, 09 Feb 2017 07:36:44 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z4si10362155pfd.119.2017.02.09.07.36.44; Thu, 09 Feb 2017 07:36:44 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-mmc-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753775AbdBIPgj (ORCPT + 5 others); Thu, 9 Feb 2017 10:36:39 -0500 Received: from mail-lf0-f41.google.com ([209.85.215.41]:33323 "EHLO mail-lf0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753921AbdBIPgI (ORCPT ); Thu, 9 Feb 2017 10:36:08 -0500 Received: by mail-lf0-f41.google.com with SMTP id x1so4589695lff.0 for ; Thu, 09 Feb 2017 07:35:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=lmq/R0fH8Qp/gNE3KvmEVCfuBhpGugaQfGORXr/d1Ss=; b=DZPoF+B2/D/sTbrOUBI+wV4Dt5yAJ3R7Np04jNOZTHAgNce4qUbBXDaDMnqF3Y9rZ4 ZRuPWNOeiwOHUYckrOHaEWl85gnLIYDXglDEKPT6vEf6XmWn1+x6Iu1+56zjEHSHiufN IB/oeiZHk13iOwDbwotIpPbm686ZS3oZiHkI8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=lmq/R0fH8Qp/gNE3KvmEVCfuBhpGugaQfGORXr/d1Ss=; b=FreWI5J+BkFfB/swI2uozdvbkrxMHMCwWupwrSgaEEgaxMr/wKl9b76zytcTqjXO93 fvt5i8oXq1JlCRYWSDXaSzyq1iIA295iT99oIY0B4fEgiJ5GPwlMDWODEUfJvhzs5gam yiOwB0bT/td5+HDi2aQY+ysZXV/MPcXGE08e+REA5/mv1wiGIkCv5bfwv/Akwq9+wBJR TUlMgYxmDJMq/SO4TsqDLazmuUwAyp14e3ITCEKy/nET/u3od3UvKh08ZP0+yybhwV8Y VnZRta8E4azDgYP7KlO1n7sUMLbLXoyeI1cAZDbhON8mn4Hmu7EZ1fK5+TGDeI1NTtyf xffg== X-Gm-Message-State: AMke39k9t/Q7a3PLQA1rXA+cWObNyNLzN0c8DxKHB2SaVbwX/PTN11ma/9kssYTrwYFII3Oz X-Received: by 10.25.99.134 with SMTP id v6mr1360642lfi.170.1486654520883; Thu, 09 Feb 2017 07:35:20 -0800 (PST) Received: from gnarp.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id e86sm3670614lji.32.2017.02.09.07.35.19 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 09 Feb 2017 07:35:19 -0800 (PST) From: Linus Walleij To: linux-mmc@vger.kernel.org, Ulf Hansson , Adrian Hunter , Paolo Valente Cc: Chunyan Zhang , Baolin Wang , linux-block@vger.kernel.org, Jens Axboe , Christoph Hellwig , Arnd Bergmann , Linus Walleij Subject: [PATCH 11/16] mmc: block: shuffle retry and error handling Date: Thu, 9 Feb 2017 16:33:58 +0100 Message-Id: <20170209153403.9730-12-linus.walleij@linaro.org> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170209153403.9730-1-linus.walleij@linaro.org> References: <20170209153403.9730-1-linus.walleij@linaro.org> Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org Instead of doing retries at the same time as trying to submit new requests, do the retries when the request is reported as completed by the driver, in the finalization worker. This is achieved by letting the core worker call back into the block layer using mmc_blk_rw_done(), that will read the status and repeatedly try to hammer the request using single request etc by calling back to the core layer using mmc_restart_areq() The beauty of it is that the completion will not complete until the block layer has had the opportunity to hammer a bit at the card using a bunch of different approaches in the while() loop in mmc_blk_rw_done() The algorithm for recapture, retry and handle errors is essentially identical to the one we used to have in mmc_blk_issue_rw_rq(), only augmented to get called in another path. We have to add and initialize a pointer back to the struct mmc_queue from the struct mmc_queue_req to find the queue from the asynchronous request. Signed-off-by: Linus Walleij --- drivers/mmc/core/block.c | 307 +++++++++++++++++++++++------------------------ drivers/mmc/core/block.h | 3 + drivers/mmc/core/core.c | 23 +++- drivers/mmc/core/queue.c | 2 + drivers/mmc/core/queue.h | 1 + include/linux/mmc/core.h | 1 + include/linux/mmc/host.h | 1 - 7 files changed, 177 insertions(+), 161 deletions(-) -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Reviewed-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index c459d80c66bf..0bd9070f5f2e 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -1614,182 +1614,181 @@ static void mmc_blk_rw_cmd_abort(struct mmc_card *card, struct request *req) * @mq: the queue with the card and host to restart * @req: a new request that want to be started after the current one */ -static void mmc_blk_rw_try_restart(struct mmc_queue *mq, struct request *req) +static void mmc_blk_rw_try_restart(struct mmc_queue *mq) { - if (!req) - return; - - /* - * If the card was removed, just cancel everything and return. - */ - if (mmc_card_removed(mq->card)) { - req->rq_flags |= RQF_QUIET; - blk_end_request_all(req, -EIO); - return; - } - /* Else proceed and try to restart the current async request */ + /* Proceed and try to restart the current async request */ mmc_blk_rw_rq_prep(mq->mqrq_cur, mq->card, 0, mq); - mmc_start_areq(mq->card->host, &mq->mqrq_cur->areq, NULL); + mmc_restart_areq(mq->card->host, &mq->mqrq_cur->areq); } -static void mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *new_req) +void mmc_blk_rw_done(struct mmc_async_req *areq, + enum mmc_blk_status status) { - struct mmc_blk_data *md = mq->blkdata; - struct mmc_card *card = md->queue.card; - struct mmc_blk_request *brq; - int disable_multi = 0, retry = 0, type, retune_retry_done = 0; - enum mmc_blk_status status; + struct mmc_queue *mq; struct mmc_queue_req *mq_rq; + struct mmc_blk_request *brq; + struct mmc_blk_data *md; struct request *old_req; - struct mmc_async_req *new_areq; - struct mmc_async_req *old_areq; + struct mmc_card *card; + struct mmc_host *host; + int disable_multi = 0, retry = 0, type, retune_retry_done = 0; bool req_pending = true; - if (!new_req && !mq->mqrq_prev->req) - return; - - do { - if (new_req) { - /* - * When 4KB native sector is enabled, only 8 blocks - * multiple read or write is allowed - */ - if (mmc_large_sector(card) && - !IS_ALIGNED(blk_rq_sectors(new_req), 8)) { - pr_err("%s: Transfer size is not 4KB sector size aligned\n", - new_req->rq_disk->disk_name); - mmc_blk_rw_cmd_abort(card, new_req); - return; - } - - mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq); - new_areq = &mq->mqrq_cur->areq; - } else - new_areq = NULL; - - old_areq = mmc_start_areq(card->host, new_areq, &status); - if (!old_areq) { - /* - * We have just put the first request into the pipeline - * and there is nothing more to do until it is - * complete. - */ - return; - } - + /* + * An asynchronous request has been completed and we proceed + * to handle the result of it. + */ + mq_rq = container_of(areq, struct mmc_queue_req, areq); + mq = mq_rq->mq; + md = mq->blkdata; + card = mq->card; + host = card->host; + brq = &mq_rq->brq; + old_req = mq_rq->req; + type = rq_data_dir(old_req) == READ ? MMC_BLK_READ : MMC_BLK_WRITE; + + mmc_queue_bounce_post(mq_rq); + + switch (status) { + case MMC_BLK_SUCCESS: + case MMC_BLK_PARTIAL: /* - * An asynchronous request has been completed and we proceed - * to handle the result of it. + * A block was successfully transferred. */ - mq_rq = container_of(old_areq, struct mmc_queue_req, areq); - brq = &mq_rq->brq; - old_req = mq_rq->req; - type = rq_data_dir(old_req) == READ ? MMC_BLK_READ : MMC_BLK_WRITE; - mmc_queue_bounce_post(mq_rq); - - switch (status) { - case MMC_BLK_SUCCESS: - case MMC_BLK_PARTIAL: - /* - * A block was successfully transferred. - */ - mmc_blk_reset_success(md, type); + mmc_blk_reset_success(md, type); - req_pending = blk_end_request(old_req, 0, - brq->data.bytes_xfered); - /* - * If the blk_end_request function returns non-zero even - * though all data has been transferred and no errors - * were returned by the host controller, it's a bug. - */ - if (status == MMC_BLK_SUCCESS && req_pending) { - pr_err("%s BUG rq_tot %d d_xfer %d\n", - __func__, blk_rq_bytes(old_req), - brq->data.bytes_xfered); - mmc_blk_rw_cmd_abort(card, old_req); - return; - } - break; - case MMC_BLK_CMD_ERR: - req_pending = mmc_blk_rw_cmd_err(md, card, brq, old_req, req_pending); - if (mmc_blk_reset(md, card->host, type)) { - mmc_blk_rw_cmd_abort(card, old_req); - mmc_blk_rw_try_restart(mq, new_req); - return; - } - if (!req_pending) { - mmc_blk_rw_try_restart(mq, new_req); - return; - } - break; - case MMC_BLK_RETRY: - retune_retry_done = brq->retune_retry_done; - if (retry++ < 5) - break; - /* Fall through */ - case MMC_BLK_ABORT: - if (!mmc_blk_reset(md, card->host, type)) - break; + req_pending = blk_end_request(old_req, 0, + brq->data.bytes_xfered); + /* + * If the blk_end_request function returns non-zero even + * though all data has been transferred and no errors + * were returned by the host controller, it's a bug. + */ + if (status == MMC_BLK_SUCCESS && req_pending) { + pr_err("%s BUG rq_tot %d d_xfer %d\n", + __func__, blk_rq_bytes(old_req), + brq->data.bytes_xfered); mmc_blk_rw_cmd_abort(card, old_req); - mmc_blk_rw_try_restart(mq, new_req); return; - case MMC_BLK_DATA_ERR: { - int err; - - err = mmc_blk_reset(md, card->host, type); - if (!err) - break; - if (err == -ENODEV) { - mmc_blk_rw_cmd_abort(card, old_req); - mmc_blk_rw_try_restart(mq, new_req); - return; - } - /* Fall through */ } - case MMC_BLK_ECC_ERR: - if (brq->data.blocks > 1) { - /* Redo read one sector at a time */ - pr_warn("%s: retrying using single block read\n", - old_req->rq_disk->disk_name); - disable_multi = 1; - break; - } - /* - * After an error, we redo I/O one sector at a - * time, so we only reach here after trying to - * read a single sector. - */ - req_pending = blk_end_request(old_req, -EIO, - brq->data.blksz); - if (!req_pending) { - mmc_blk_rw_try_restart(mq, new_req); - return; - } - break; - case MMC_BLK_NOMEDIUM: + break; + case MMC_BLK_CMD_ERR: + req_pending = mmc_blk_rw_cmd_err(md, card, brq, old_req, req_pending); + if (mmc_blk_reset(md, host, type)) { mmc_blk_rw_cmd_abort(card, old_req); - mmc_blk_rw_try_restart(mq, new_req); + mmc_blk_rw_try_restart(mq); return; - default: - pr_err("%s: Unhandled return value (%d)", - old_req->rq_disk->disk_name, status); + } + if (!req_pending) { + mmc_blk_rw_try_restart(mq); + return; + } + break; + case MMC_BLK_RETRY: + retune_retry_done = brq->retune_retry_done; + if (retry++ < 5) + break; + /* Fall through */ + case MMC_BLK_ABORT: + if (!mmc_blk_reset(md, host, type)) + break; + mmc_blk_rw_cmd_abort(card, old_req); + mmc_blk_rw_try_restart(mq); + return; + case MMC_BLK_DATA_ERR: { + int err; + err = mmc_blk_reset(md, host, type); + if (!err) + break; + if (err == -ENODEV) { mmc_blk_rw_cmd_abort(card, old_req); - mmc_blk_rw_try_restart(mq, new_req); + mmc_blk_rw_try_restart(mq); return; } + /* Fall through */ + } + case MMC_BLK_ECC_ERR: + if (brq->data.blocks > 1) { + /* Redo read one sector at a time */ + pr_warn("%s: retrying using single block read\n", + old_req->rq_disk->disk_name); + disable_multi = 1; + break; + } + /* + * After an error, we redo I/O one sector at a + * time, so we only reach here after trying to + * read a single sector. + */ + req_pending = blk_end_request(old_req, -EIO, + brq->data.blksz); + if (!req_pending) { + mmc_blk_rw_try_restart(mq); + return; + } + break; + case MMC_BLK_NOMEDIUM: + mmc_blk_rw_cmd_abort(card, old_req); + mmc_blk_rw_try_restart(mq); + return; + default: + pr_err("%s: Unhandled return value (%d)", + old_req->rq_disk->disk_name, status); + mmc_blk_rw_cmd_abort(card, old_req); + mmc_blk_rw_try_restart(mq); + return; + } - if (req_pending) { - /* - * In case of a incomplete request - * prepare it again and resend. - */ - mmc_blk_rw_rq_prep(mq_rq, card, - disable_multi, mq); - mmc_start_areq(card->host, - &mq_rq->areq, NULL); - mq_rq->brq.retune_retry_done = retune_retry_done; + if (req_pending) { + /* + * In case of a incomplete request + * prepare it again and resend. + */ + mmc_blk_rw_rq_prep(mq_rq, card, + disable_multi, mq); + mq_rq->brq.retune_retry_done = retune_retry_done; + mmc_restart_areq(host, &mq->mqrq_cur->areq); + } +} + +static void mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *new_req) +{ + enum mmc_blk_status status; + struct mmc_async_req *new_areq; + struct mmc_async_req *old_areq; + struct mmc_card *card = mq->card; + + if (!new_req && !mq->mqrq_prev->req) + return; + + if (new_req) { + /* + * When 4KB native sector is enabled, only 8 blocks + * multiple read or write is allowed + */ + if (mmc_large_sector(card) && + !IS_ALIGNED(blk_rq_sectors(new_req), 8)) { + pr_err("%s: Transfer size is not 4KB sector size aligned\n", + new_req->rq_disk->disk_name); + mmc_blk_rw_cmd_abort(card, new_req); + return; } - } while (req_pending); + + mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq); + new_areq = &mq->mqrq_cur->areq; + } else + new_areq = NULL; + + old_areq = mmc_start_areq(card->host, new_areq, &status); + if (!old_areq) { + /* + * We have just put the first request into the pipeline + * and there is nothing more to do until it is + * complete. + */ + return; + } + /* FIXME: yes, we just disregard the old_areq */ } void mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) diff --git a/drivers/mmc/core/block.h b/drivers/mmc/core/block.h index 860ca7c8df86..b4b489911599 100644 --- a/drivers/mmc/core/block.h +++ b/drivers/mmc/core/block.h @@ -1,9 +1,12 @@ #ifndef _MMC_CORE_BLOCK_H #define _MMC_CORE_BLOCK_H +struct mmc_async_req; +enum mmc_blk_status; struct mmc_queue; struct request; +void mmc_blk_rw_done(struct mmc_async_req *areq, enum mmc_blk_status status); void mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req); #endif diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 4b84f18518ac..34337ef6705e 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -39,6 +39,7 @@ #define CREATE_TRACE_POINTS #include +#include "block.h" #include "core.h" #include "card.h" #include "bus.h" @@ -632,13 +633,25 @@ void mmc_finalize_areq(struct kthread_work *work) /* Successfully postprocess the old request at this point */ mmc_post_req(host, areq->mrq, 0); + mmc_blk_rw_done(areq, status); - areq->finalization_status = status; complete(&areq->complete); } EXPORT_SYMBOL(mmc_finalize_areq); /** + * mmc_restart_areq() - restart an asynchronous request + * @host: MMC host to restart the command on + * @areq: the asynchronous request to restart + */ +int mmc_restart_areq(struct mmc_host *host, + struct mmc_async_req *areq) +{ + return __mmc_start_data_req(host, areq->mrq); +} +EXPORT_SYMBOL(mmc_restart_areq); + +/** * mmc_start_areq - start an asynchronous request * @host: MMC host to start command * @areq: asynchronous request to start @@ -667,12 +680,10 @@ struct mmc_async_req *mmc_start_areq(struct mmc_host *host, mmc_pre_req(host, areq->mrq); /* Finalize previous request, if there is one */ - if (previous) { + if (previous) wait_for_completion(&previous->complete); - status = previous->finalization_status; - } else { - status = MMC_BLK_SUCCESS; - } + + status = MMC_BLK_SUCCESS; if (ret_stat) *ret_stat = status; diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c index bc116709c806..ae6837317fe0 100644 --- a/drivers/mmc/core/queue.c +++ b/drivers/mmc/core/queue.c @@ -268,7 +268,9 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, if (!mq->mqrq) goto blk_cleanup; mq->mqrq_cur = &mq->mqrq[0]; + mq->mqrq_cur->mq = mq; mq->mqrq_prev = &mq->mqrq[1]; + mq->mqrq_prev->mq = mq; mq->queue->queuedata = mq; blk_queue_prep_rq(mq->queue, mmc_prep_request); diff --git a/drivers/mmc/core/queue.h b/drivers/mmc/core/queue.h index 39d8e710287e..c18d3f908433 100644 --- a/drivers/mmc/core/queue.h +++ b/drivers/mmc/core/queue.h @@ -34,6 +34,7 @@ struct mmc_queue_req { struct scatterlist *bounce_sg; unsigned int bounce_sg_len; struct mmc_async_req areq; + struct mmc_queue *mq; }; struct mmc_queue { diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 5db0fb722c37..55b45dcddee6 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -159,6 +159,7 @@ struct mmc_card; struct mmc_async_req; void mmc_finalize_areq(struct kthread_work *work); +int mmc_restart_areq(struct mmc_host *host, struct mmc_async_req *areq); struct mmc_async_req *mmc_start_areq(struct mmc_host *host, struct mmc_async_req *areq, enum mmc_blk_status *ret_stat); diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index a7c0ed887391..47d80b8470cd 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -171,7 +171,6 @@ struct mmc_async_req { */ enum mmc_blk_status (*err_check)(struct mmc_card *, struct mmc_async_req *); struct kthread_work finalization_work; - enum mmc_blk_status finalization_status; struct completion complete; struct mmc_host *host; }; From patchwork Thu Feb 9 15:33:59 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 93728 Delivered-To: patch@linaro.org Received: by 10.182.3.34 with SMTP id 2csp81436obz; Thu, 9 Feb 2017 07:36:43 -0800 (PST) X-Received: by 10.98.141.194 with SMTP id p63mr4345832pfk.185.1486654603738; Thu, 09 Feb 2017 07:36:43 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z4si10362155pfd.119.2017.02.09.07.36.43; Thu, 09 Feb 2017 07:36:43 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-mmc-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932190AbdBIPgl (ORCPT + 5 others); Thu, 9 Feb 2017 10:36:41 -0500 Received: from mail-lf0-f44.google.com ([209.85.215.44]:33353 "EHLO mail-lf0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753925AbdBIPgI (ORCPT ); Thu, 9 Feb 2017 10:36:08 -0500 Received: by mail-lf0-f44.google.com with SMTP id x1so4591062lff.0 for ; Thu, 09 Feb 2017 07:35:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=WfADosfQKOLXg6eOEnSYje1veX1H06OAjr3FdGAbpp8=; b=DqvXrJlBaRW9kaye3hwfqlhqyS9BQEIIJIGK+Yswk+3odL+aTOROiFB3mljNXkmAu+ xLvjWPnbDGdNtYR5fBx8kmK0iibkDhbihSy9rlILPcb8pfGY9vuAy6YrAdL7piRs5BQD rKARtnz2boqoQPQKazEvyntWtdggWoBHs2LWA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=WfADosfQKOLXg6eOEnSYje1veX1H06OAjr3FdGAbpp8=; b=T9G8Ivc1n2uetGhJuPRj/r+Y7mco8v7hKdZoYlW5T8sSLZq22GGlEmL11+v1eWBDhG vWFt/OH+DTCmsk1FxnXA8Mmez9wXK5tkWwtVe+AQLvl4uCUuclE34CnixeX769JHLqbA K27XwW+ZcPYUyKghcv0HZdocOHOVdUyZ7o640Ucf8qGT6A4rXFUmUKDqmDS7S+ag/Qvn roNBw1je9OmpxDKSzqlqlY4z+2VX+eECTY3Gt83PK2bQ9/5w8uHvKS2o4DHtfzseFMWo U0zKcxnCm2apJ6kgac2ABfEcZZr28QLiYYMS4cNX7/xNlWFLgowC1lljkVlkkX8Abhhr 5s+Q== X-Gm-Message-State: AMke39nMtcWR2uCqLl5ZRR9Ii25TUvH/l0Gfyu+Kdd3Pc4jV9G6ssjloMhM54oPukLRhyQMc X-Received: by 10.25.203.87 with SMTP id b84mr1264620lfg.158.1486654525327; Thu, 09 Feb 2017 07:35:25 -0800 (PST) Received: from gnarp.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id e86sm3670614lji.32.2017.02.09.07.35.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 09 Feb 2017 07:35:24 -0800 (PST) From: Linus Walleij To: linux-mmc@vger.kernel.org, Ulf Hansson , Adrian Hunter , Paolo Valente Cc: Chunyan Zhang , Baolin Wang , linux-block@vger.kernel.org, Jens Axboe , Christoph Hellwig , Arnd Bergmann , Linus Walleij Subject: [PATCH 12/16] mmc: queue: stop flushing the pipeline with NULL Date: Thu, 9 Feb 2017 16:33:59 +0100 Message-Id: <20170209153403.9730-13-linus.walleij@linaro.org> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170209153403.9730-1-linus.walleij@linaro.org> References: <20170209153403.9730-1-linus.walleij@linaro.org> Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org Remove all the pipeline flush: i.e. repeatedly sending NULL down to the core layer to flush out asynchronous requests, and also sending NULL after "special" commands to achieve the same flush. Instead: let the "special" commands wait for any ongoing asynchronous transfers using the completion, and apart from that expect the core.c and block.c layers to deal with the ongoing requests autonomously without any "push" from the queue. Signed-off-by: Linus Walleij --- drivers/mmc/core/block.c | 80 +++++++++++++++++------------------------------- drivers/mmc/core/core.c | 37 ++++++++++------------ drivers/mmc/core/queue.c | 18 ++++++++--- include/linux/mmc/core.h | 5 ++- 4 files changed, 60 insertions(+), 80 deletions(-) -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 0bd9070f5f2e..4952a105780e 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -1753,42 +1753,27 @@ void mmc_blk_rw_done(struct mmc_async_req *areq, static void mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *new_req) { - enum mmc_blk_status status; - struct mmc_async_req *new_areq; - struct mmc_async_req *old_areq; struct mmc_card *card = mq->card; - if (!new_req && !mq->mqrq_prev->req) + if (!new_req) { + pr_err("%s: NULL request!\n", __func__); return; + } - if (new_req) { - /* - * When 4KB native sector is enabled, only 8 blocks - * multiple read or write is allowed - */ - if (mmc_large_sector(card) && - !IS_ALIGNED(blk_rq_sectors(new_req), 8)) { - pr_err("%s: Transfer size is not 4KB sector size aligned\n", - new_req->rq_disk->disk_name); - mmc_blk_rw_cmd_abort(card, new_req); - return; - } - - mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq); - new_areq = &mq->mqrq_cur->areq; - } else - new_areq = NULL; - - old_areq = mmc_start_areq(card->host, new_areq, &status); - if (!old_areq) { - /* - * We have just put the first request into the pipeline - * and there is nothing more to do until it is - * complete. - */ + /* + * When 4KB native sector is enabled, only 8 blocks + * multiple read or write is allowed + */ + if (mmc_large_sector(card) && + !IS_ALIGNED(blk_rq_sectors(new_req), 8)) { + pr_err("%s: Transfer size is not 4KB sector size aligned\n", + new_req->rq_disk->disk_name); + mmc_blk_rw_cmd_abort(card, new_req); return; } - /* FIXME: yes, we just disregard the old_areq */ + + mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq); + mmc_start_areq(card->host, &mq->mqrq_cur->areq); } void mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) @@ -1796,48 +1781,39 @@ void mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) int ret; struct mmc_blk_data *md = mq->blkdata; struct mmc_card *card = md->queue.card; - bool req_is_special = mmc_req_is_special(req); - - if (req && !mq->mqrq_prev->req) - /* claim host only for the first request */ - mmc_get_card(card); ret = mmc_blk_part_switch(card, md); if (ret) { if (req) { blk_end_request_all(req, -EIO); } - goto out; + return; } if (req && req_op(req) == REQ_OP_DISCARD) { /* complete ongoing async transfer before issuing discard */ - if (card->host->areq) - mmc_blk_issue_rw_rq(mq, NULL); + if (card->host->areq) { + wait_for_completion(&card->host->areq->complete); + card->host->areq = NULL; + } mmc_blk_issue_discard_rq(mq, req); } else if (req && req_op(req) == REQ_OP_SECURE_ERASE) { /* complete ongoing async transfer before issuing secure erase*/ - if (card->host->areq) - mmc_blk_issue_rw_rq(mq, NULL); + if (card->host->areq) { + wait_for_completion(&card->host->areq->complete); + card->host->areq = NULL; + } mmc_blk_issue_secdiscard_rq(mq, req); } else if (req && req_op(req) == REQ_OP_FLUSH) { /* complete ongoing async transfer before issuing flush */ - if (card->host->areq) - mmc_blk_issue_rw_rq(mq, NULL); + if (card->host->areq) { + wait_for_completion(&card->host->areq->complete); + card->host->areq = NULL; + } mmc_blk_issue_flush(mq, req); } else { mmc_blk_issue_rw_rq(mq, req); } - -out: - if (!req || req_is_special) - /* - * Release host when there are no more requests - * and after special request(discard, flush) is done. - * In case sepecial request, there is no reentry to - * the 'mmc_blk_issue_rq' with 'mqrq_prev->req'. - */ - mmc_put_card(card); } static inline int mmc_blk_readonly(struct mmc_card *card) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 34337ef6705e..03c290e5e2c9 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -667,42 +667,37 @@ EXPORT_SYMBOL(mmc_restart_areq); * return the completed request. If there is no ongoing request, NULL * is returned without waiting. NULL is not an error condition. */ -struct mmc_async_req *mmc_start_areq(struct mmc_host *host, - struct mmc_async_req *areq, - enum mmc_blk_status *ret_stat) +int mmc_start_areq(struct mmc_host *host, + struct mmc_async_req *areq) { - enum mmc_blk_status status; - int start_err = 0; + int ret; struct mmc_async_req *previous = host->areq; /* Prepare a new request */ - if (areq) - mmc_pre_req(host, areq->mrq); + if (!areq) { + pr_err("%s: NULL asynchronous request!\n", __func__); + return -EIO; + } + + mmc_pre_req(host, areq->mrq); /* Finalize previous request, if there is one */ if (previous) wait_for_completion(&previous->complete); - status = MMC_BLK_SUCCESS; - if (ret_stat) - *ret_stat = status; - /* Fine so far, start the new request! */ - if (status == MMC_BLK_SUCCESS && areq) { - init_completion(&areq->complete); - start_err = __mmc_start_data_req(host, areq->mrq); - } + init_completion(&areq->complete); + ret = __mmc_start_data_req(host, areq->mrq); /* Cancel a prepared request if it was not started. */ - if ((status != MMC_BLK_SUCCESS || start_err) && areq) + if (ret) { mmc_post_req(host, areq->mrq, -EINVAL); - - if (status != MMC_BLK_SUCCESS) host->areq = NULL; - else - host->areq = areq; + pr_err("%s: failed to start request\n", __func__); + } + host->areq = areq; - return previous; + return ret; } EXPORT_SYMBOL(mmc_start_areq); diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c index ae6837317fe0..c9f28de7b0f4 100644 --- a/drivers/mmc/core/queue.c +++ b/drivers/mmc/core/queue.c @@ -53,6 +53,7 @@ static int mmc_queue_thread(void *d) { struct mmc_queue *mq = d; struct request_queue *q = mq->queue; + bool claimed_host = false; current->flags |= PF_MEMALLOC; @@ -67,9 +68,11 @@ static int mmc_queue_thread(void *d) mq->mqrq_cur->req = req; spin_unlock_irq(q->queue_lock); - if (req || mq->mqrq_prev->req) { + if (req) { bool req_is_special = mmc_req_is_special(req); + if (!claimed_host) + mmc_get_card(mq->card); set_current_state(TASK_RUNNING); mmc_blk_issue_rq(mq, req); cond_resched(); @@ -78,11 +81,14 @@ static int mmc_queue_thread(void *d) * and vice versa. * In case of special requests, current request * has been finished. Do not assign it to previous - * request. + * request. Always unclaim the host after special + * commands. */ - if (req_is_special) + if (req_is_special) { mq->mqrq_cur->req = NULL; - + mmc_put_card(mq->card); + claimed_host = false; + } mq->mqrq_prev->brq.mrq.data = NULL; mq->mqrq_prev->req = NULL; swap(mq->mqrq_prev, mq->mqrq_cur); @@ -97,6 +103,10 @@ static int mmc_queue_thread(void *d) down(&mq->thread_sem); } } while (1); + + if (claimed_host) + mmc_put_card(mq->card); + up(&mq->thread_sem); return 0; diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 55b45dcddee6..af651e723ba2 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -160,9 +160,8 @@ struct mmc_async_req; void mmc_finalize_areq(struct kthread_work *work); int mmc_restart_areq(struct mmc_host *host, struct mmc_async_req *areq); -struct mmc_async_req *mmc_start_areq(struct mmc_host *host, - struct mmc_async_req *areq, - enum mmc_blk_status *ret_stat); +int mmc_start_areq(struct mmc_host *host, + struct mmc_async_req *areq); void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq); int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries); From patchwork Thu Feb 9 15:34:00 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 93727 Delivered-To: patch@linaro.org Received: by 10.182.3.34 with SMTP id 2csp81429obz; Thu, 9 Feb 2017 07:36:43 -0800 (PST) X-Received: by 10.99.158.68 with SMTP id r4mr4689716pgo.153.1486654603077; Thu, 09 Feb 2017 07:36:43 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z4si10362155pfd.119.2017.02.09.07.36.42; Thu, 09 Feb 2017 07:36:43 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-mmc-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753919AbdBIPgk (ORCPT + 5 others); Thu, 9 Feb 2017 10:36:40 -0500 Received: from mail-lf0-f44.google.com ([209.85.215.44]:34114 "EHLO mail-lf0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753928AbdBIPgI (ORCPT ); Thu, 9 Feb 2017 10:36:08 -0500 Received: by mail-lf0-f44.google.com with SMTP id v186so4554147lfa.1 for ; Thu, 09 Feb 2017 07:35:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ExL/g8vc0+to/j6OfBKE7ysB7kSVD0s36ZLsM1b0V9U=; b=jymvwxl2nAO7a4FR0Vx2thlj0SgAxByCDAPyvPFf6FpxsdKpTdyej1vzZ41GoOQWr4 5v+gv7rrxbEim2Gvgj81pkgSnOus7XcWsG0iJxYaZOyGTOqlazKb6SryOypO+74rjw/3 kIYXu4pDckRY01TBFBc/YCH+zCw7vSi0MT8SA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ExL/g8vc0+to/j6OfBKE7ysB7kSVD0s36ZLsM1b0V9U=; b=rODwUXweEiCAuC032CPraXi4as6im+l7yVfz+I+9yUOhFymueeL18eEAEPRZO/yBfz DBDZWdk8dqVKjWC6h0ptw29uUFYlzmwOB7fLNNAgJfIniShDtlKxIi8jq5XG0TpHsdWB 78ObQlx/qTfAm/XEVozCQGPSJ+lnPzGZjn+NW8KDB8oa7K10FC3yggbCCkjvjjN0nr0R OiAcyhfL9lekeg/F6Kr5lNFxU/1melfTqvY2KGxnE3DEun/L5ZtuWGiJ05oG7N2TdeoC k4tsBRss91zmN5PXcPOPszTrGyGik03CaIjPIPgf+oz9znkxuMIipWNANhCPjNDX++wa aVSw== X-Gm-Message-State: AMke39n6WqLrBvDIPcSiiE4jW4f9wJBdsxnRQGXArVAAzCE/VRE7MdXuzztTvWeeEOhZ5IQS X-Received: by 10.25.135.130 with SMTP id j124mr1343262lfd.11.1486654528756; Thu, 09 Feb 2017 07:35:28 -0800 (PST) Received: from gnarp.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id e86sm3670614lji.32.2017.02.09.07.35.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 09 Feb 2017 07:35:27 -0800 (PST) From: Linus Walleij To: linux-mmc@vger.kernel.org, Ulf Hansson , Adrian Hunter , Paolo Valente Cc: Chunyan Zhang , Baolin Wang , linux-block@vger.kernel.org, Jens Axboe , Christoph Hellwig , Arnd Bergmann , Linus Walleij Subject: [PATCH 13/16] mmc: queue: issue struct mmc_queue_req items Date: Thu, 9 Feb 2017 16:34:00 +0100 Message-Id: <20170209153403.9730-14-linus.walleij@linaro.org> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170209153403.9730-1-linus.walleij@linaro.org> References: <20170209153403.9730-1-linus.walleij@linaro.org> Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org Instead of passing two pointers around and messing and reassigning to the left and right, issue mmc_queue_req and dereference the queue from the request where needed. The struct mmc_queue_req is the thing that has a lifecycle after all: this is what we are keepin in out queue. Augment all users to be passed the struct mmc_queue_req as well. Signed-off-by: Linus Walleij --- drivers/mmc/core/block.c | 88 ++++++++++++++++++++++++------------------------ drivers/mmc/core/block.h | 5 ++- drivers/mmc/core/queue.c | 6 ++-- 3 files changed, 50 insertions(+), 49 deletions(-) -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 4952a105780e..628a22b9bf41 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -1151,9 +1151,9 @@ int mmc_access_rpmb(struct mmc_queue *mq) return false; } -static void mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req) +static void mmc_blk_issue_discard_rq(struct mmc_queue_req *mq_rq) { - struct mmc_blk_data *md = mq->blkdata; + struct mmc_blk_data *md = mq_rq->mq->blkdata; struct mmc_card *card = md->queue.card; unsigned int from, nr, arg; int err = 0, type = MMC_BLK_DISCARD; @@ -1163,8 +1163,8 @@ static void mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req) goto fail; } - from = blk_rq_pos(req); - nr = blk_rq_sectors(req); + from = blk_rq_pos(mq_rq->req); + nr = blk_rq_sectors(mq_rq->req); if (mmc_can_discard(card)) arg = MMC_DISCARD_ARG; @@ -1188,13 +1188,12 @@ static void mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req) if (!err) mmc_blk_reset_success(md, type); fail: - blk_end_request(req, err, blk_rq_bytes(req)); + blk_end_request(mq_rq->req, err, blk_rq_bytes(mq_rq->req)); } -static void mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq, - struct request *req) +static void mmc_blk_issue_secdiscard_rq(struct mmc_queue_req *mq_rq) { - struct mmc_blk_data *md = mq->blkdata; + struct mmc_blk_data *md = mq_rq->mq->blkdata; struct mmc_card *card = md->queue.card; unsigned int from, nr, arg; int err = 0, type = MMC_BLK_SECDISCARD; @@ -1204,8 +1203,8 @@ static void mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq, goto out; } - from = blk_rq_pos(req); - nr = blk_rq_sectors(req); + from = blk_rq_pos(mq_rq->req); + nr = blk_rq_sectors(mq_rq->req); if (mmc_can_trim(card) && !mmc_erase_group_aligned(card, from, nr)) arg = MMC_SECURE_TRIM1_ARG; @@ -1253,12 +1252,12 @@ static void mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq, if (!err) mmc_blk_reset_success(md, type); out: - blk_end_request(req, err, blk_rq_bytes(req)); + blk_end_request(mq_rq->req, err, blk_rq_bytes(mq_rq->req)); } -static void mmc_blk_issue_flush(struct mmc_queue *mq, struct request *req) +static void mmc_blk_issue_flush(struct mmc_queue_req *mq_rq) { - struct mmc_blk_data *md = mq->blkdata; + struct mmc_blk_data *md = mq_rq->mq->blkdata; struct mmc_card *card = md->queue.card; int ret = 0; @@ -1266,7 +1265,7 @@ static void mmc_blk_issue_flush(struct mmc_queue *mq, struct request *req) if (ret) ret = -EIO; - blk_end_request_all(req, ret); + blk_end_request_all(mq_rq->req, ret); } /* @@ -1614,11 +1613,13 @@ static void mmc_blk_rw_cmd_abort(struct mmc_card *card, struct request *req) * @mq: the queue with the card and host to restart * @req: a new request that want to be started after the current one */ -static void mmc_blk_rw_try_restart(struct mmc_queue *mq) +static void mmc_blk_rw_try_restart(struct mmc_queue_req *mq_rq) { + struct mmc_queue *mq = mq_rq->mq; + /* Proceed and try to restart the current async request */ - mmc_blk_rw_rq_prep(mq->mqrq_cur, mq->card, 0, mq); - mmc_restart_areq(mq->card->host, &mq->mqrq_cur->areq); + mmc_blk_rw_rq_prep(mq_rq, mq->card, 0, mq); + mmc_restart_areq(mq->card->host, &mq_rq->areq); } void mmc_blk_rw_done(struct mmc_async_req *areq, @@ -1676,11 +1677,11 @@ void mmc_blk_rw_done(struct mmc_async_req *areq, req_pending = mmc_blk_rw_cmd_err(md, card, brq, old_req, req_pending); if (mmc_blk_reset(md, host, type)) { mmc_blk_rw_cmd_abort(card, old_req); - mmc_blk_rw_try_restart(mq); + mmc_blk_rw_try_restart(mq_rq); return; } if (!req_pending) { - mmc_blk_rw_try_restart(mq); + mmc_blk_rw_try_restart(mq_rq); return; } break; @@ -1693,7 +1694,7 @@ void mmc_blk_rw_done(struct mmc_async_req *areq, if (!mmc_blk_reset(md, host, type)) break; mmc_blk_rw_cmd_abort(card, old_req); - mmc_blk_rw_try_restart(mq); + mmc_blk_rw_try_restart(mq_rq); return; case MMC_BLK_DATA_ERR: { int err; @@ -1702,7 +1703,7 @@ void mmc_blk_rw_done(struct mmc_async_req *areq, break; if (err == -ENODEV) { mmc_blk_rw_cmd_abort(card, old_req); - mmc_blk_rw_try_restart(mq); + mmc_blk_rw_try_restart(mq_rq); return; } /* Fall through */ @@ -1723,19 +1724,19 @@ void mmc_blk_rw_done(struct mmc_async_req *areq, req_pending = blk_end_request(old_req, -EIO, brq->data.blksz); if (!req_pending) { - mmc_blk_rw_try_restart(mq); + mmc_blk_rw_try_restart(mq_rq); return; } break; case MMC_BLK_NOMEDIUM: mmc_blk_rw_cmd_abort(card, old_req); - mmc_blk_rw_try_restart(mq); + mmc_blk_rw_try_restart(mq_rq); return; default: pr_err("%s: Unhandled return value (%d)", old_req->rq_disk->disk_name, status); mmc_blk_rw_cmd_abort(card, old_req); - mmc_blk_rw_try_restart(mq); + mmc_blk_rw_try_restart(mq_rq); return; } @@ -1747,15 +1748,16 @@ void mmc_blk_rw_done(struct mmc_async_req *areq, mmc_blk_rw_rq_prep(mq_rq, card, disable_multi, mq); mq_rq->brq.retune_retry_done = retune_retry_done; - mmc_restart_areq(host, &mq->mqrq_cur->areq); + mmc_restart_areq(host, &mq_rq->areq); } } -static void mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *new_req) +static void mmc_blk_issue_rw_rq(struct mmc_queue_req *mq_rq) { + struct mmc_queue *mq = mq_rq->mq; struct mmc_card *card = mq->card; - if (!new_req) { + if (!mq_rq->req) { pr_err("%s: NULL request!\n", __func__); return; } @@ -1765,54 +1767,52 @@ static void mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *new_req) * multiple read or write is allowed */ if (mmc_large_sector(card) && - !IS_ALIGNED(blk_rq_sectors(new_req), 8)) { + !IS_ALIGNED(blk_rq_sectors(mq_rq->req), 8)) { pr_err("%s: Transfer size is not 4KB sector size aligned\n", - new_req->rq_disk->disk_name); - mmc_blk_rw_cmd_abort(card, new_req); + mq_rq->req->rq_disk->disk_name); + mmc_blk_rw_cmd_abort(card, mq_rq->req); return; } - mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq); - mmc_start_areq(card->host, &mq->mqrq_cur->areq); + mmc_blk_rw_rq_prep(mq_rq, card, 0, mq); + mmc_start_areq(card->host, &mq_rq->areq); } -void mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) +void mmc_blk_issue_rq(struct mmc_queue_req *mq_rq) { int ret; - struct mmc_blk_data *md = mq->blkdata; + struct mmc_blk_data *md = mq_rq->mq->blkdata; struct mmc_card *card = md->queue.card; ret = mmc_blk_part_switch(card, md); if (ret) { - if (req) { - blk_end_request_all(req, -EIO); - } + blk_end_request_all(mq_rq->req, -EIO); return; } - if (req && req_op(req) == REQ_OP_DISCARD) { + if (req_op(mq_rq->req) == REQ_OP_DISCARD) { /* complete ongoing async transfer before issuing discard */ if (card->host->areq) { wait_for_completion(&card->host->areq->complete); card->host->areq = NULL; } - mmc_blk_issue_discard_rq(mq, req); - } else if (req && req_op(req) == REQ_OP_SECURE_ERASE) { + mmc_blk_issue_discard_rq(mq_rq); + } else if (req_op(mq_rq->req) == REQ_OP_SECURE_ERASE) { /* complete ongoing async transfer before issuing secure erase*/ if (card->host->areq) { wait_for_completion(&card->host->areq->complete); card->host->areq = NULL; } - mmc_blk_issue_secdiscard_rq(mq, req); - } else if (req && req_op(req) == REQ_OP_FLUSH) { + mmc_blk_issue_secdiscard_rq(mq_rq); + } else if (req_op(mq_rq->req) == REQ_OP_FLUSH) { /* complete ongoing async transfer before issuing flush */ if (card->host->areq) { wait_for_completion(&card->host->areq->complete); card->host->areq = NULL; } - mmc_blk_issue_flush(mq, req); + mmc_blk_issue_flush(mq_rq); } else { - mmc_blk_issue_rw_rq(mq, req); + mmc_blk_issue_rw_rq(mq_rq); } } diff --git a/drivers/mmc/core/block.h b/drivers/mmc/core/block.h index b4b489911599..0326fa5d8217 100644 --- a/drivers/mmc/core/block.h +++ b/drivers/mmc/core/block.h @@ -3,10 +3,9 @@ struct mmc_async_req; enum mmc_blk_status; -struct mmc_queue; -struct request; +struct mmc_queue_req; void mmc_blk_rw_done(struct mmc_async_req *areq, enum mmc_blk_status status); -void mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req); +void mmc_blk_issue_rq(struct mmc_queue_req *mq_rq); #endif diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c index c9f28de7b0f4..c4e1ced55796 100644 --- a/drivers/mmc/core/queue.c +++ b/drivers/mmc/core/queue.c @@ -54,6 +54,7 @@ static int mmc_queue_thread(void *d) struct mmc_queue *mq = d; struct request_queue *q = mq->queue; bool claimed_host = false; + struct mmc_queue_req *mq_rq; current->flags |= PF_MEMALLOC; @@ -65,7 +66,8 @@ static int mmc_queue_thread(void *d) set_current_state(TASK_INTERRUPTIBLE); req = blk_fetch_request(q); mq->asleep = false; - mq->mqrq_cur->req = req; + mq_rq = mq->mqrq_cur; + mq_rq->req = req; spin_unlock_irq(q->queue_lock); if (req) { @@ -74,7 +76,7 @@ static int mmc_queue_thread(void *d) if (!claimed_host) mmc_get_card(mq->card); set_current_state(TASK_RUNNING); - mmc_blk_issue_rq(mq, req); + mmc_blk_issue_rq(mq_rq); cond_resched(); /* * Current request becomes previous request From patchwork Thu Feb 9 15:34:01 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 93725 Delivered-To: patch@linaro.org Received: by 10.182.3.34 with SMTP id 2csp81411obz; Thu, 9 Feb 2017 07:36:40 -0800 (PST) X-Received: by 10.99.149.27 with SMTP id p27mr4740559pgd.21.1486654600679; Thu, 09 Feb 2017 07:36:40 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z4si10362155pfd.119.2017.02.09.07.36.40; Thu, 09 Feb 2017 07:36:40 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-mmc-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752468AbdBIPgi (ORCPT + 5 others); Thu, 9 Feb 2017 10:36:38 -0500 Received: from mail-lf0-f46.google.com ([209.85.215.46]:34155 "EHLO mail-lf0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753933AbdBIPgI (ORCPT ); Thu, 9 Feb 2017 10:36:08 -0500 Received: by mail-lf0-f46.google.com with SMTP id v186so4555951lfa.1 for ; Thu, 09 Feb 2017 07:35:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=VQwrXJxMEXwgaC3sWPXooQxT3omh3crqluOrLQKhS3k=; b=EsrVELSnv1wAKlT2b5FqQkilFRuOFG4izPhAoVxzsFw7iAOdnvr5zqFDZeK1pikplE brcOiAw4kOQT5cxcUf8Ki88Vn/GNEDn/rxrMR1MiUr+RqIjsMLKXhBVtalUCpHUoBYJb nWPjQtcSmRuRxCtOFEp6P7zrCNGjg5MD00d0U= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=VQwrXJxMEXwgaC3sWPXooQxT3omh3crqluOrLQKhS3k=; b=TZvXGfYQEGZtRsDZkW3PSer/pOHEqNGQ9BCCoio8wxYooeOTC4yt//PtyM/v/sk9Vu +WvAiwyOzE79v5Cyb/1vzSa8bJKapcZR69Mf5K7JzS7HhJv1izL43PXMOXQ50+rJyILt 60+XPJWfRieL2n8OwmuxidtUYnQsEVPnORtX4H5T/YUhhnD2ZN9eZFXaCbvQZZj1cDU6 EcshVKM9Z3VUSuy+yQtnTpWd/0jAGr8ebCg+fnX8x+1IXb/pC/mTwajZcODbOZDc9Okr l6j4Yv635cojU4xYY05irsTTAcEcw9Tf0Z4yKz9bnS7bx6SGqknbzxnxFRfFpwUdyOK3 aSBg== X-Gm-Message-State: AMke39l20tEc3LnMLVsoLIT3FTucZcO8RdzY6YP07T87T7SehB1pk9HmGsNX5sqZj/g/saun X-Received: by 10.25.18.102 with SMTP id h99mr1164214lfi.63.1486654534216; Thu, 09 Feb 2017 07:35:34 -0800 (PST) Received: from gnarp.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id e86sm3670614lji.32.2017.02.09.07.35.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 09 Feb 2017 07:35:32 -0800 (PST) From: Linus Walleij To: linux-mmc@vger.kernel.org, Ulf Hansson , Adrian Hunter , Paolo Valente Cc: Chunyan Zhang , Baolin Wang , linux-block@vger.kernel.org, Jens Axboe , Christoph Hellwig , Arnd Bergmann , Linus Walleij Subject: [PATCH 14/16] mmc: queue: get/put struct mmc_queue_req Date: Thu, 9 Feb 2017 16:34:01 +0100 Message-Id: <20170209153403.9730-15-linus.walleij@linaro.org> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170209153403.9730-1-linus.walleij@linaro.org> References: <20170209153403.9730-1-linus.walleij@linaro.org> Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org The per-hardware-transaction struct mmc_queue_req is assigned from a pool of 2 requests using a current/previous scheme and then swapped around. This is confusing, especially if we need more than two to make our work efficient and parallel. Rewrite the mechanism to have a pool of struct mmc_queue_req and take one when we need one and put it back when we don't need it anymore. Signed-off-by: Linus Walleij --- drivers/mmc/core/block.c | 3 +++ drivers/mmc/core/core.c | 4 ++++ drivers/mmc/core/queue.c | 57 ++++++++++++++++++++++++++++++++++++++---------- drivers/mmc/core/queue.h | 8 ++++--- 4 files changed, 57 insertions(+), 15 deletions(-) -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Reviewed-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 628a22b9bf41..acca15cc1807 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -1797,6 +1797,7 @@ void mmc_blk_issue_rq(struct mmc_queue_req *mq_rq) card->host->areq = NULL; } mmc_blk_issue_discard_rq(mq_rq); + mmc_queue_req_put(mq_rq); } else if (req_op(mq_rq->req) == REQ_OP_SECURE_ERASE) { /* complete ongoing async transfer before issuing secure erase*/ if (card->host->areq) { @@ -1804,6 +1805,7 @@ void mmc_blk_issue_rq(struct mmc_queue_req *mq_rq) card->host->areq = NULL; } mmc_blk_issue_secdiscard_rq(mq_rq); + mmc_queue_req_put(mq_rq); } else if (req_op(mq_rq->req) == REQ_OP_FLUSH) { /* complete ongoing async transfer before issuing flush */ if (card->host->areq) { @@ -1811,6 +1813,7 @@ void mmc_blk_issue_rq(struct mmc_queue_req *mq_rq) card->host->areq = NULL; } mmc_blk_issue_flush(mq_rq); + mmc_queue_req_put(mq_rq); } else { mmc_blk_issue_rw_rq(mq_rq); } diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 03c290e5e2c9..50a8942b98c2 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -39,6 +39,7 @@ #define CREATE_TRACE_POINTS #include +#include "queue.h" #include "block.h" #include "core.h" #include "card.h" @@ -598,6 +599,8 @@ void mmc_finalize_areq(struct kthread_work *work) { struct mmc_async_req *areq = container_of(work, struct mmc_async_req, finalization_work); + struct mmc_queue_req *mq_rq = container_of(areq, struct mmc_queue_req, + areq); struct mmc_host *host = areq->host; enum mmc_blk_status status = MMC_BLK_SUCCESS; struct mmc_command *cmd; @@ -636,6 +639,7 @@ void mmc_finalize_areq(struct kthread_work *work) mmc_blk_rw_done(areq, status); complete(&areq->complete); + mmc_queue_req_put(mq_rq); } EXPORT_SYMBOL(mmc_finalize_areq); diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c index c4e1ced55796..cab0f51dbb4d 100644 --- a/drivers/mmc/core/queue.c +++ b/drivers/mmc/core/queue.c @@ -49,6 +49,42 @@ static int mmc_prep_request(struct request_queue *q, struct request *req) return BLKPREP_OK; } +/** + * Get an available queue item from the pool. + */ +static struct mmc_queue_req *mmc_queue_req_get(struct mmc_queue *mq) +{ + int i; + + /* + * This simply cannot fail so we just spin here + * until we get a queue request to work on. + */ + while (1) { + /* Just take the first unused queue request */ + spin_lock_irq(&mq->mqrq_lock); + for (i = 0; i < mq->qdepth; i++) { + if (!mq->mqrq[i].in_use) { + mq->mqrq[i].in_use = true; + spin_unlock_irq(&mq->mqrq_lock); + return &mq->mqrq[i]; + } + } + spin_unlock_irq(&mq->mqrq_lock); + + pr_warn_once("%s: out of queue items, spinning\n", __func__); + } +} + +void mmc_queue_req_put(struct mmc_queue_req *mq_rq) +{ + mq_rq->brq.mrq.data = NULL; + mq_rq->req = NULL; + spin_lock_irq(&mq_rq->mq->mqrq_lock); + mq_rq->in_use = false; + spin_unlock_irq(&mq_rq->mq->mqrq_lock); +} + static int mmc_queue_thread(void *d) { struct mmc_queue *mq = d; @@ -62,17 +98,17 @@ static int mmc_queue_thread(void *d) do { struct request *req = NULL; - spin_lock_irq(q->queue_lock); set_current_state(TASK_INTERRUPTIBLE); + spin_lock_irq(q->queue_lock); req = blk_fetch_request(q); - mq->asleep = false; - mq_rq = mq->mqrq_cur; - mq_rq->req = req; spin_unlock_irq(q->queue_lock); + mq->asleep = false; if (req) { bool req_is_special = mmc_req_is_special(req); + mq_rq = mmc_queue_req_get(mq); + mq_rq->req = req; if (!claimed_host) mmc_get_card(mq->card); set_current_state(TASK_RUNNING); @@ -87,13 +123,9 @@ static int mmc_queue_thread(void *d) * commands. */ if (req_is_special) { - mq->mqrq_cur->req = NULL; mmc_put_card(mq->card); claimed_host = false; } - mq->mqrq_prev->brq.mrq.data = NULL; - mq->mqrq_prev->req = NULL; - swap(mq->mqrq_prev, mq->mqrq_cur); } else { mq->asleep = true; if (kthread_should_stop()) { @@ -265,6 +297,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, u64 limit = BLK_BOUNCE_HIGH; bool bounce = false; int ret = -ENOMEM; + int i; if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask) limit = (u64)dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT; @@ -275,14 +308,14 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, return -ENOMEM; mq->qdepth = 2; + spin_lock_init(&mq->mqrq_lock); mq->mqrq = kcalloc(mq->qdepth, sizeof(struct mmc_queue_req), GFP_KERNEL); if (!mq->mqrq) goto blk_cleanup; - mq->mqrq_cur = &mq->mqrq[0]; - mq->mqrq_cur->mq = mq; - mq->mqrq_prev = &mq->mqrq[1]; - mq->mqrq_prev->mq = mq; + for (i = 0; i < mq->qdepth; i++) + mq->mqrq[i].mq = mq; + mq->queue->queuedata = mq; blk_queue_prep_rq(mq->queue, mmc_prep_request); diff --git a/drivers/mmc/core/queue.h b/drivers/mmc/core/queue.h index c18d3f908433..886a05482b74 100644 --- a/drivers/mmc/core/queue.h +++ b/drivers/mmc/core/queue.h @@ -2,6 +2,7 @@ #define MMC_QUEUE_H #include +#include #include #include #include @@ -27,6 +28,7 @@ struct mmc_blk_request { }; struct mmc_queue_req { + bool in_use; struct request *req; struct mmc_blk_request brq; struct scatterlist *sg; @@ -45,12 +47,12 @@ struct mmc_queue { bool asleep; struct mmc_blk_data *blkdata; struct request_queue *queue; + spinlock_t mqrq_lock; struct mmc_queue_req *mqrq; - struct mmc_queue_req *mqrq_cur; - struct mmc_queue_req *mqrq_prev; - int qdepth; + unsigned int qdepth; }; +extern void mmc_queue_req_put(struct mmc_queue_req *mq_rq); extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *, const char *); extern void mmc_cleanup_queue(struct mmc_queue *); From patchwork Thu Feb 9 15:34:02 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 93726 Delivered-To: patch@linaro.org Received: by 10.182.3.34 with SMTP id 2csp81425obz; Thu, 9 Feb 2017 07:36:42 -0800 (PST) X-Received: by 10.98.150.70 with SMTP id c67mr4371080pfe.84.1486654602726; Thu, 09 Feb 2017 07:36:42 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z4si10362155pfd.119.2017.02.09.07.36.42; Thu, 09 Feb 2017 07:36:42 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-mmc-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753914AbdBIPgk (ORCPT + 5 others); Thu, 9 Feb 2017 10:36:40 -0500 Received: from mail-lf0-f45.google.com ([209.85.215.45]:35209 "EHLO mail-lf0-f45.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753934AbdBIPgI (ORCPT ); Thu, 9 Feb 2017 10:36:08 -0500 Received: by mail-lf0-f45.google.com with SMTP id n124so4540840lfd.2 for ; Thu, 09 Feb 2017 07:35:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=xPNOgo5O7TyHe/Frs8si8vJ7XvuNUdZIePe2OYGGFBk=; b=gwKC40Q5J+vqXeA80hDPh1sztnsM2rOjxQZZfJEYvLK3jIxjPGl7OSmJswFBqSb91p XEyPX0l+8pbG+b4K1IY4OmVmTaBQeCt2iFxHihBoHPrhs0E5q/e4CKJ1Fro+txTDG7P8 WN5R8imeKcrHtBptQZLTaqPTaecbTHW+8wl04= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=xPNOgo5O7TyHe/Frs8si8vJ7XvuNUdZIePe2OYGGFBk=; b=Ga2z7HQL7BGGdim/pDAR3eCROwTjbsx9EQs6kNcGlwG7CFMy0880iB8IjyR9NxqSrr CPs29u2O4rEOqTc5mJbgQnxrVq74NXXZ3PJEyVpQtqt+1y33oL/zEFjQyFyYbn+XCvwx Nt0xcNo+xB6JqTH5kGlETZHea+26UQ4e4uZqnhBP1jgTkepYBn0PdFL7ympXkCrj6eHU qo3ZifdZ7NxPyPi52DEjKdWX9BOtfYSsqLi8yvReUx7RkYPLp7j3gCRE0rgf0ugHqmnN VaP/zpnyqGsG3siZe1Fn5p+avy2Wd7Ax/PHLEhEW4rMuJwc9Ei6HArs/laKLGOe6Z1kV n0OQ== X-Gm-Message-State: AMke39mFPC0xw9M3F/eYnjHZTZAjQSmItwasCdXngO/+y5iqXrBUTcMX1U6XK5tCHnO5sl6g X-Received: by 10.46.9.216 with SMTP id 207mr1512664ljj.4.1486654540244; Thu, 09 Feb 2017 07:35:40 -0800 (PST) Received: from gnarp.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id e86sm3670614lji.32.2017.02.09.07.35.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 09 Feb 2017 07:35:38 -0800 (PST) From: Linus Walleij To: linux-mmc@vger.kernel.org, Ulf Hansson , Adrian Hunter , Paolo Valente Cc: Chunyan Zhang , Baolin Wang , linux-block@vger.kernel.org, Jens Axboe , Christoph Hellwig , Arnd Bergmann , Linus Walleij Subject: [PATCH 15/16] mmc: queue: issue requests in massive parallel Date: Thu, 9 Feb 2017 16:34:02 +0100 Message-Id: <20170209153403.9730-16-linus.walleij@linaro.org> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170209153403.9730-1-linus.walleij@linaro.org> References: <20170209153403.9730-1-linus.walleij@linaro.org> Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org This makes a crucial change to the issueing mechanism for the MMC requests: Before commit "mmc: core: move the asynchronous post-processing" some parallelism on the read/write requests was achieved by speculatively postprocessing a request and re-preprocess and re-issue the request if something went wrong, which we discover later when checking for an error. This is kind of ugly. Instead we need a mechanism like here: We issue requests, and when they come back from the hardware, we know if they finished successfully or not. If the request was successful, we complete the asynchronous request and let a new request immediately start on the hardware. If, and only if, it returned an error from the hardware we go down the error path. This is achieved by splitting the work path from the hardware in two: a successful path ending up calling down to mmc_blk_rw_done_success() and an errorpath calling down to mmc_blk_rw_done_error(). This has a profound effect: we reintroduce the parallelism on the successful path as mmc_post_req() can now be called in while the next request is in transit (just like prior to commit "mmc: core: move the asynchronous post-processing") but ALSO we can call mmc_queue_bounce_post() and blk_end_request() in parallel. The latter has the profound effect of issuing a new request again so that we actually need to have at least three requests in transit at the same time: we haven't yet dropped the reference to our struct mmc_queue_req so we need at least three. I put the pool to 4 requests for now. I expect the imrovement to be noticeable on systems that use bounce buffers since they can now process requests in parallel with post-processing their bounce buffers, but I don't have a test target for that. Signed-off-by: Linus Walleij --- drivers/mmc/core/block.c | 61 +++++++++++++++++++++++++++++++++++++----------- drivers/mmc/core/block.h | 4 +++- drivers/mmc/core/core.c | 27 ++++++++++++++++++--- drivers/mmc/core/queue.c | 2 +- 4 files changed, 75 insertions(+), 19 deletions(-) -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index acca15cc1807..f1008ce5376b 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -1622,8 +1622,51 @@ static void mmc_blk_rw_try_restart(struct mmc_queue_req *mq_rq) mmc_restart_areq(mq->card->host, &mq_rq->areq); } -void mmc_blk_rw_done(struct mmc_async_req *areq, - enum mmc_blk_status status) +/** + * Final handling of an asynchronous request if there was no error. + * This is the common path that we take when everything is nice + * and smooth. The status from the command is always MMC_BLK_SUCCESS. + */ +void mmc_blk_rw_done_success(struct mmc_async_req *areq) +{ + struct mmc_queue_req *mq_rq; + struct mmc_blk_request *brq; + struct mmc_blk_data *md; + struct request *old_req; + bool req_pending; + int type; + + mq_rq = container_of(areq, struct mmc_queue_req, areq); + md = mq_rq->mq->blkdata; + brq = &mq_rq->brq; + old_req = mq_rq->req; + type = rq_data_dir(old_req) == READ ? MMC_BLK_READ : MMC_BLK_WRITE; + + mmc_queue_bounce_post(mq_rq); + mmc_blk_reset_success(md, type); + req_pending = blk_end_request(old_req, 0, + brq->data.bytes_xfered); + /* + * If the blk_end_request function returns non-zero even + * though all data has been transferred and no errors + * were returned by the host controller, it's a bug. + */ + if (req_pending) { + pr_err("%s BUG rq_tot %d d_xfer %d\n", + __func__, blk_rq_bytes(old_req), + brq->data.bytes_xfered); + return; + } +} + +/** + * Error, recapture, retry etc for asynchronous requests. + * This is the error path that we take when there is bad status + * coming back from the hardware and we need to do a bit of + * cleverness. + */ +void mmc_blk_rw_done_error(struct mmc_async_req *areq, + enum mmc_blk_status status) { struct mmc_queue *mq; struct mmc_queue_req *mq_rq; @@ -1652,6 +1695,8 @@ void mmc_blk_rw_done(struct mmc_async_req *areq, switch (status) { case MMC_BLK_SUCCESS: + pr_err("%s: MMC_BLK_SUCCESS on error path\n", __func__); + /* This should not happen: anyway fall through */ case MMC_BLK_PARTIAL: /* * A block was successfully transferred. @@ -1660,18 +1705,6 @@ void mmc_blk_rw_done(struct mmc_async_req *areq, req_pending = blk_end_request(old_req, 0, brq->data.bytes_xfered); - /* - * If the blk_end_request function returns non-zero even - * though all data has been transferred and no errors - * were returned by the host controller, it's a bug. - */ - if (status == MMC_BLK_SUCCESS && req_pending) { - pr_err("%s BUG rq_tot %d d_xfer %d\n", - __func__, blk_rq_bytes(old_req), - brq->data.bytes_xfered); - mmc_blk_rw_cmd_abort(card, old_req); - return; - } break; case MMC_BLK_CMD_ERR: req_pending = mmc_blk_rw_cmd_err(md, card, brq, old_req, req_pending); diff --git a/drivers/mmc/core/block.h b/drivers/mmc/core/block.h index 0326fa5d8217..eae47ae7c903 100644 --- a/drivers/mmc/core/block.h +++ b/drivers/mmc/core/block.h @@ -5,7 +5,9 @@ struct mmc_async_req; enum mmc_blk_status; struct mmc_queue_req; -void mmc_blk_rw_done(struct mmc_async_req *areq, enum mmc_blk_status status); +void mmc_blk_rw_done_success(struct mmc_async_req *areq); +void mmc_blk_rw_done_error(struct mmc_async_req *areq, + enum mmc_blk_status status); void mmc_blk_issue_rq(struct mmc_queue_req *mq_rq); #endif diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 50a8942b98c2..04666ad91df0 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -634,11 +634,32 @@ void mmc_finalize_areq(struct kthread_work *work) mmc_start_bkops(host->card, true); } - /* Successfully postprocess the old request at this point */ - mmc_post_req(host, areq->mrq, 0); - mmc_blk_rw_done(areq, status); + /* + * Postprocess the old request at this point: + * on success: take a fast path! + * on error: take the slow path, retrying etc + */ + if (status != MMC_BLK_SUCCESS) { + mmc_post_req(host, areq->mrq, 0); + /* + * This call can lead to retransmissions using + * mmc_restart_areq() so do not complete until + * after this call! + */ + mmc_blk_rw_done_error(areq, status); + complete(&areq->complete); + mmc_queue_req_put(mq_rq); + return; + } + /* + * There will not be any retransmissions etc + * at this point, so let the next request get + * access to the hardware. + */ complete(&areq->complete); + mmc_post_req(host, areq->mrq, 0); + mmc_blk_rw_done_success(areq); mmc_queue_req_put(mq_rq); } EXPORT_SYMBOL(mmc_finalize_areq); diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c index cab0f51dbb4d..e7ba5bef2df3 100644 --- a/drivers/mmc/core/queue.c +++ b/drivers/mmc/core/queue.c @@ -307,7 +307,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, if (!mq->queue) return -ENOMEM; - mq->qdepth = 2; + mq->qdepth = 4; spin_lock_init(&mq->mqrq_lock); mq->mqrq = kcalloc(mq->qdepth, sizeof(struct mmc_queue_req), GFP_KERNEL); From patchwork Thu Feb 9 15:34:03 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 93724 Delivered-To: patch@linaro.org Received: by 10.182.3.34 with SMTP id 2csp81282obz; Thu, 9 Feb 2017 07:36:26 -0800 (PST) X-Received: by 10.84.213.151 with SMTP id g23mr4972596pli.43.1486654586667; Thu, 09 Feb 2017 07:36:26 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p1si10315679pga.393.2017.02.09.07.36.26; Thu, 09 Feb 2017 07:36:26 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-mmc-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753918AbdBIPgY (ORCPT + 5 others); Thu, 9 Feb 2017 10:36:24 -0500 Received: from mail-lf0-f49.google.com ([209.85.215.49]:35243 "EHLO mail-lf0-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753936AbdBIPgJ (ORCPT ); Thu, 9 Feb 2017 10:36:09 -0500 Received: by mail-lf0-f49.google.com with SMTP id n124so4542420lfd.2 for ; Thu, 09 Feb 2017 07:35:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=hQEKzSGnXZUgyxrmLoaa5eoDCkgTuxl3CSp1FYQy2uo=; b=ZmYr7R1hCxRk/HvTncXzJyvEmBhhPnp56au6fxbPP1kfjaw2bdJ4uO5CqL6KcQPOY6 rfRbi2Zyz1o77oMBMWzwVoaXmiZX2hDBWIgJDW5DkxKLqhFUm0miGRRX7u1yVvBXBpd8 aZ/F4yDNs7AYo5amFc7AKAW8crUmEq+dSVHpc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=hQEKzSGnXZUgyxrmLoaa5eoDCkgTuxl3CSp1FYQy2uo=; b=Jf07lfhPfcQ0hnseN2u/tP3F8EnIO18Uap3P4NmRFFj4R1CkCdU7rkwmX8TTVwigeu ErLCECiQVoCMiceGouqT/JZ1GBrjeud83mG9YQhMHGw7lM8DMCkx0C7SU4t850SjArl3 Vhw7FhPwYt9IlMM5CCLLBL0pGJvDe/IcPXghrxRlFH08CZauld7g25UyZ/tGOohGkxuL RFRBsJAgZ1PKMCUw5Tv2PJyJSJBP8Tt4eMyPU6tu9m2/VVwwKBT11+zAjtaybwKaJU3E W667BSUp+vXHsDTEfEENg++TbmlBbWGsBPeeO6/S6a7WleR/ZCdIJbUv9tnIRzIgOath n3Ig== X-Gm-Message-State: AMke39m9J4GRKoAtuia9LypLI2ywoFtqt13xergCWJ5rGcH6fBc3Oe/vdxra4kKrL+Zff3FF X-Received: by 10.25.92.2 with SMTP id q2mr1325167lfb.121.1486654545151; Thu, 09 Feb 2017 07:35:45 -0800 (PST) Received: from gnarp.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id e86sm3670614lji.32.2017.02.09.07.35.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 09 Feb 2017 07:35:43 -0800 (PST) From: Linus Walleij To: linux-mmc@vger.kernel.org, Ulf Hansson , Adrian Hunter , Paolo Valente Cc: Chunyan Zhang , Baolin Wang , linux-block@vger.kernel.org, Jens Axboe , Christoph Hellwig , Arnd Bergmann , Linus Walleij Subject: [PATCH 16/16] RFC: mmc: switch MMC/SD to use blk-mq multiqueueing v3 Date: Thu, 9 Feb 2017 16:34:03 +0100 Message-Id: <20170209153403.9730-17-linus.walleij@linaro.org> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170209153403.9730-1-linus.walleij@linaro.org> References: <20170209153403.9730-1-linus.walleij@linaro.org> Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org HACK ALERT: DO NOT MERGE THIS! IT IS A FYI PATCH FOR DISCUSSION ONLY. This is a totally new implementation of how to do multiqueue in the MMC/SD stack. It is based on top of my refactorings in the series which ends with this patch, and now makes proper use of .init_request() and .exit_request() to initialize the per-request hardware context, reusing good old struct mmc_queue_req which is what is actually intended by these functions. We kill off the kthread that was just calling blk_fetch_request() and let blk-mq drive all traffic, nice, that is how it should work. Due to having switched the submission mechanics around so that the completion of requests is now triggered from the host callbacks, we manage to keep the same performance for linear reads/writes as we have for the old block layer. Some open questions: - We used to issue mmc_get_card() when the first request comes in and mmc_put_card() when we get NULL from blk_fetch_request(). Well as we are not pushed any NULL requests anymore we need another way for the queue to tell us it is idle, or we should just set up a delayed work and release the card if no new requests appear for some time. - The flush was handled by issueing blk_end_request_all() in the old scheduler. Is blk_mq_complete_request() really doing the same job, or is there some extra magic needed here? - We can sometime get a partial read from a MMC command, meaning some of the request has been handled. We know how many bytes were read/written. We used to report this to the block layer using blk_end_request(old_req, 0, bytes_xfered) but the MQ scheduler seems to be missing a command that reports partial completion. How do we handle this? Apart from that my only remaining worries are about the block scheduler, but I hear Jens and Paolo are working to fix this. Signed-off-by: Linus Walleij --- drivers/mmc/core/block.c | 66 ++++----- drivers/mmc/core/core.c | 4 - drivers/mmc/core/queue.c | 355 ++++++++++++++++------------------------------- drivers/mmc/core/queue.h | 15 +- 4 files changed, 159 insertions(+), 281 deletions(-) -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index f1008ce5376b..f977117f7435 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -96,7 +97,6 @@ static DEFINE_SPINLOCK(mmc_blk_lock); * There is one mmc_blk_data per slot. */ struct mmc_blk_data { - spinlock_t lock; struct device *parent; struct gendisk *disk; struct mmc_queue queue; @@ -1188,7 +1188,7 @@ static void mmc_blk_issue_discard_rq(struct mmc_queue_req *mq_rq) if (!err) mmc_blk_reset_success(md, type); fail: - blk_end_request(mq_rq->req, err, blk_rq_bytes(mq_rq->req)); + blk_mq_complete_request(mq_rq->req, err); } static void mmc_blk_issue_secdiscard_rq(struct mmc_queue_req *mq_rq) @@ -1265,7 +1265,8 @@ static void mmc_blk_issue_flush(struct mmc_queue_req *mq_rq) if (ret) ret = -EIO; - blk_end_request_all(mq_rq->req, ret); + /* FIXME: was using blk_end_request_all() to flush */ + blk_mq_complete_request(mq_rq->req, ret); } /* @@ -1589,12 +1590,15 @@ static bool mmc_blk_rw_cmd_err(struct mmc_blk_data *md, struct mmc_card *card, int err; err = mmc_sd_num_wr_blocks(card, &blocks); - if (err) + if (err) { req_pending = old_req_pending; - else - req_pending = blk_end_request(req, 0, blocks << 9); + } else { + blk_mq_complete_request(req, 0); + req_pending = false; + } } else { - req_pending = blk_end_request(req, 0, brq->data.bytes_xfered); + blk_mq_complete_request(req, 0); + req_pending = false; } return req_pending; } @@ -1630,33 +1634,18 @@ static void mmc_blk_rw_try_restart(struct mmc_queue_req *mq_rq) void mmc_blk_rw_done_success(struct mmc_async_req *areq) { struct mmc_queue_req *mq_rq; - struct mmc_blk_request *brq; struct mmc_blk_data *md; struct request *old_req; - bool req_pending; int type; mq_rq = container_of(areq, struct mmc_queue_req, areq); md = mq_rq->mq->blkdata; - brq = &mq_rq->brq; old_req = mq_rq->req; type = rq_data_dir(old_req) == READ ? MMC_BLK_READ : MMC_BLK_WRITE; mmc_queue_bounce_post(mq_rq); mmc_blk_reset_success(md, type); - req_pending = blk_end_request(old_req, 0, - brq->data.bytes_xfered); - /* - * If the blk_end_request function returns non-zero even - * though all data has been transferred and no errors - * were returned by the host controller, it's a bug. - */ - if (req_pending) { - pr_err("%s BUG rq_tot %d d_xfer %d\n", - __func__, blk_rq_bytes(old_req), - brq->data.bytes_xfered); - return; - } + blk_mq_complete_request(old_req, 0); } /** @@ -1702,9 +1691,16 @@ void mmc_blk_rw_done_error(struct mmc_async_req *areq, * A block was successfully transferred. */ mmc_blk_reset_success(md, type); - - req_pending = blk_end_request(old_req, 0, - brq->data.bytes_xfered); + /* + * FIXME: + * How do we handle a partial request? + * brq->data.bytes_xfered contains the number of + * successfully transfered bytes, how to report + * this to the MQ block layer and get a new, smaller + * request back? Currently just requeueing. + */ + blk_mq_requeue_request(old_req, false); + req_pending = false; break; case MMC_BLK_CMD_ERR: req_pending = mmc_blk_rw_cmd_err(md, card, brq, old_req, req_pending); @@ -1754,12 +1750,9 @@ void mmc_blk_rw_done_error(struct mmc_async_req *areq, * time, so we only reach here after trying to * read a single sector. */ - req_pending = blk_end_request(old_req, -EIO, - brq->data.blksz); - if (!req_pending) { - mmc_blk_rw_try_restart(mq_rq); - return; - } + blk_mq_complete_request(mq_rq->req, -EIO); + req_pending = false; + mmc_blk_rw_try_restart(mq_rq); break; case MMC_BLK_NOMEDIUM: mmc_blk_rw_cmd_abort(card, old_req); @@ -1819,7 +1812,8 @@ void mmc_blk_issue_rq(struct mmc_queue_req *mq_rq) ret = mmc_blk_part_switch(card, md); if (ret) { - blk_end_request_all(mq_rq->req, -EIO); + /* FIXME: was blk_end_request_all() to flush */ + blk_mq_complete_request(mq_rq->req, -EIO); return; } @@ -1830,7 +1824,6 @@ void mmc_blk_issue_rq(struct mmc_queue_req *mq_rq) card->host->areq = NULL; } mmc_blk_issue_discard_rq(mq_rq); - mmc_queue_req_put(mq_rq); } else if (req_op(mq_rq->req) == REQ_OP_SECURE_ERASE) { /* complete ongoing async transfer before issuing secure erase*/ if (card->host->areq) { @@ -1838,7 +1831,6 @@ void mmc_blk_issue_rq(struct mmc_queue_req *mq_rq) card->host->areq = NULL; } mmc_blk_issue_secdiscard_rq(mq_rq); - mmc_queue_req_put(mq_rq); } else if (req_op(mq_rq->req) == REQ_OP_FLUSH) { /* complete ongoing async transfer before issuing flush */ if (card->host->areq) { @@ -1846,7 +1838,6 @@ void mmc_blk_issue_rq(struct mmc_queue_req *mq_rq) card->host->areq = NULL; } mmc_blk_issue_flush(mq_rq); - mmc_queue_req_put(mq_rq); } else { mmc_blk_issue_rw_rq(mq_rq); } @@ -1906,11 +1897,10 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, goto err_kfree; } - spin_lock_init(&md->lock); INIT_LIST_HEAD(&md->part); md->usage = 1; - ret = mmc_init_queue(&md->queue, card, &md->lock, subname); + ret = mmc_init_queue(&md->queue, card, subname); if (ret) goto err_putdisk; diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 04666ad91df0..a81b6baa3bee 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -599,8 +599,6 @@ void mmc_finalize_areq(struct kthread_work *work) { struct mmc_async_req *areq = container_of(work, struct mmc_async_req, finalization_work); - struct mmc_queue_req *mq_rq = container_of(areq, struct mmc_queue_req, - areq); struct mmc_host *host = areq->host; enum mmc_blk_status status = MMC_BLK_SUCCESS; struct mmc_command *cmd; @@ -648,7 +646,6 @@ void mmc_finalize_areq(struct kthread_work *work) */ mmc_blk_rw_done_error(areq, status); complete(&areq->complete); - mmc_queue_req_put(mq_rq); return; } @@ -660,7 +657,6 @@ void mmc_finalize_areq(struct kthread_work *work) complete(&areq->complete); mmc_post_req(host, areq->mrq, 0); mmc_blk_rw_done_success(areq); - mmc_queue_req_put(mq_rq); } EXPORT_SYMBOL(mmc_finalize_areq); diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c index e7ba5bef2df3..9850d7342763 100644 --- a/drivers/mmc/core/queue.c +++ b/drivers/mmc/core/queue.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -49,126 +50,6 @@ static int mmc_prep_request(struct request_queue *q, struct request *req) return BLKPREP_OK; } -/** - * Get an available queue item from the pool. - */ -static struct mmc_queue_req *mmc_queue_req_get(struct mmc_queue *mq) -{ - int i; - - /* - * This simply cannot fail so we just spin here - * until we get a queue request to work on. - */ - while (1) { - /* Just take the first unused queue request */ - spin_lock_irq(&mq->mqrq_lock); - for (i = 0; i < mq->qdepth; i++) { - if (!mq->mqrq[i].in_use) { - mq->mqrq[i].in_use = true; - spin_unlock_irq(&mq->mqrq_lock); - return &mq->mqrq[i]; - } - } - spin_unlock_irq(&mq->mqrq_lock); - - pr_warn_once("%s: out of queue items, spinning\n", __func__); - } -} - -void mmc_queue_req_put(struct mmc_queue_req *mq_rq) -{ - mq_rq->brq.mrq.data = NULL; - mq_rq->req = NULL; - spin_lock_irq(&mq_rq->mq->mqrq_lock); - mq_rq->in_use = false; - spin_unlock_irq(&mq_rq->mq->mqrq_lock); -} - -static int mmc_queue_thread(void *d) -{ - struct mmc_queue *mq = d; - struct request_queue *q = mq->queue; - bool claimed_host = false; - struct mmc_queue_req *mq_rq; - - current->flags |= PF_MEMALLOC; - - down(&mq->thread_sem); - do { - struct request *req = NULL; - - set_current_state(TASK_INTERRUPTIBLE); - spin_lock_irq(q->queue_lock); - req = blk_fetch_request(q); - spin_unlock_irq(q->queue_lock); - mq->asleep = false; - - if (req) { - bool req_is_special = mmc_req_is_special(req); - - mq_rq = mmc_queue_req_get(mq); - mq_rq->req = req; - if (!claimed_host) - mmc_get_card(mq->card); - set_current_state(TASK_RUNNING); - mmc_blk_issue_rq(mq_rq); - cond_resched(); - /* - * Current request becomes previous request - * and vice versa. - * In case of special requests, current request - * has been finished. Do not assign it to previous - * request. Always unclaim the host after special - * commands. - */ - if (req_is_special) { - mmc_put_card(mq->card); - claimed_host = false; - } - } else { - mq->asleep = true; - if (kthread_should_stop()) { - set_current_state(TASK_RUNNING); - break; - } - up(&mq->thread_sem); - schedule(); - down(&mq->thread_sem); - } - } while (1); - - if (claimed_host) - mmc_put_card(mq->card); - - up(&mq->thread_sem); - - return 0; -} - -/* - * Generic MMC request handler. This is called for any queue on a - * particular host. When the host is not busy, we look for a request - * on any queue on this host, and attempt to issue it. This may - * not be the queue we were asked to process. - */ -static void mmc_request_fn(struct request_queue *q) -{ - struct mmc_queue *mq = q->queuedata; - struct request *req; - - if (!mq) { - while ((req = blk_fetch_request(q)) != NULL) { - req->rq_flags |= RQF_QUIET; - __blk_end_request_all(req, -EIO); - } - return; - } - - if (mq->asleep) - wake_up_process(mq->thread); -} - static struct scatterlist *mmc_alloc_sg(int sg_len, int *err) { struct scatterlist *sg; @@ -205,55 +86,80 @@ static void mmc_queue_setup_discard(struct request_queue *q, queue_flag_set_unlocked(QUEUE_FLAG_SECERASE, q); } -#ifdef CONFIG_MMC_BLOCK_BOUNCE -static bool mmc_queue_alloc_bounce_bufs(struct mmc_queue *mq, - unsigned int bouncesz) +static int mmc_queue_rq(struct blk_mq_hw_ctx *hctx, + const struct blk_mq_queue_data *bd) { - int i; + struct mmc_queue_req *mq_rq = blk_mq_rq_to_pdu(bd->rq); + struct mmc_queue *mq = mq_rq->mq; + bool req_is_special = mmc_req_is_special(bd->rq); - for (i = 0; i < mq->qdepth; i++) { - mq->mqrq[i].bounce_buf = kmalloc(bouncesz, GFP_KERNEL); - if (!mq->mqrq[i].bounce_buf) - goto out_err; + /* start this request */ + mq_rq->req = bd->rq; + mq_rq->brq.mrq.data = NULL; + blk_mq_start_request(mq_rq->req); + + if (!mq->claimed_host) { + mmc_get_card(mq->card); + mq->claimed_host = true; + } + set_current_state(TASK_RUNNING); + mmc_blk_issue_rq(mq_rq); + cond_resched(); + /* + * In case of special requests, current request + * has been finished. Always unclaim the host after special + * commands. + */ + if (req_is_special) { + mmc_put_card(mq->card); + mq->claimed_host = false; } - return true; + /* + * FIXME: unclaim host after timeout? + * Can blk-mq notify us that there are no requests coming + * for a while so we can relax the host? + */ + // if (claimed_host) + // mmc_put_card(mq->card); -out_err: - while (--i >= 0) { - kfree(mq->mqrq[i].bounce_buf); - mq->mqrq[i].bounce_buf = NULL; - } - pr_warn("%s: unable to allocate bounce buffers\n", - mmc_card_name(mq->card)); - return false; + return BLK_MQ_RQ_QUEUE_OK; } -static int mmc_queue_alloc_bounce_sgs(struct mmc_queue *mq, - unsigned int bouncesz) +static int mmc_init_request(void *data, struct request *rq, + unsigned int hctx_idx, unsigned int request_idx, + unsigned int numa_node) { - int i, ret; + struct mmc_queue_req *mq_rq = blk_mq_rq_to_pdu(rq); + struct mmc_queue *mq = data; + struct mmc_card *card = mq->card; + struct mmc_host *host = card->host; + int ret; - for (i = 0; i < mq->qdepth; i++) { - mq->mqrq[i].sg = mmc_alloc_sg(1, &ret); - if (ret) - return ret; + mq_rq->dev = host->parent; + mq_rq->mq = mq; + /* Set up bounces etc */ + dev_info(mq_rq->dev, "%s\n", __func__); - mq->mqrq[i].bounce_sg = mmc_alloc_sg(bouncesz / 512, &ret); - if (ret) - return ret; - } +#ifdef CONFIG_MMC_BLOCK_BOUNCE + if (mq->bouncesz) { + mq_rq->bounce_buf = kmalloc(mq->bouncesz, GFP_KERNEL); + if (!mq_rq->bounce_buf) + return -ENOMEM; + if (mq->bouncesz > 512) { + mq_rq->sg = mmc_alloc_sg(1, &ret); + if (ret) + return ret; - return 0; -} + mq_rq->bounce_sg = mmc_alloc_sg(mq->bouncesz / 512, + &ret); + if (ret) + return ret; + } + } else #endif - -static int mmc_queue_alloc_sgs(struct mmc_queue *mq, int max_segs) -{ - int i, ret; - - for (i = 0; i < mq->qdepth; i++) { - mq->mqrq[i].sg = mmc_alloc_sg(max_segs, &ret); + { + mq_rq->sg = mmc_alloc_sg(host->max_segs, &ret); if (ret) return ret; } @@ -261,26 +167,35 @@ static int mmc_queue_alloc_sgs(struct mmc_queue *mq, int max_segs) return 0; } -static void mmc_queue_req_free_bufs(struct mmc_queue_req *mqrq) +static void mmc_exit_request(void *data, struct request *rq, + unsigned int hctx_idx, unsigned int request_idx) { - kfree(mqrq->bounce_sg); - mqrq->bounce_sg = NULL; + struct mmc_queue_req *mq_rq = blk_mq_rq_to_pdu(rq); - kfree(mqrq->sg); - mqrq->sg = NULL; + dev_info(mq_rq->dev, "%s: hctx_idx = %u, request_idx = %u\n", + __func__, hctx_idx, request_idx); - kfree(mqrq->bounce_buf); - mqrq->bounce_buf = NULL; -} + kfree(mq_rq->bounce_sg); + mq_rq->bounce_sg = NULL; -static void mmc_queue_reqs_free_bufs(struct mmc_queue *mq) -{ - int i; + kfree(mq_rq->sg); + mq_rq->sg = NULL; - for (i = 0; i < mq->qdepth; i++) - mmc_queue_req_free_bufs(&mq->mqrq[i]); + kfree(mq_rq->bounce_buf); + mq_rq->bounce_buf = NULL; } +static struct blk_mq_ops mmc_mq_ops = { + .queue_rq = mmc_queue_rq, + .init_request = mmc_init_request, + .exit_request = mmc_exit_request, + /* + * .exit_request() will only be invoked if we explcitly call + * blk_mq_end_request() on all requests. Why would we do that, + * we will just call blk_mq_complete_request(). + */ +}; + /** * mmc_init_queue - initialise a queue structure. * @mq: mmc queue @@ -291,31 +206,47 @@ static void mmc_queue_reqs_free_bufs(struct mmc_queue *mq) * Initialise a MMC card request queue. */ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, - spinlock_t *lock, const char *subname) + const char *subname) { struct mmc_host *host = card->host; u64 limit = BLK_BOUNCE_HIGH; bool bounce = false; int ret = -ENOMEM; - int i; if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask) limit = (u64)dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT; mq->card = card; - mq->queue = blk_init_queue(mmc_request_fn, lock); - if (!mq->queue) + mq->tag_set.ops = &mmc_mq_ops; + /* The MMC/SD protocols have only one command pipe */ + mq->tag_set.nr_hw_queues = 1; + /* Set this to 2 to simulate async requests */ + mq->tag_set.queue_depth = 2; + /* + * The extra data allocated per block request. + */ + mq->tag_set.cmd_size = sizeof(struct mmc_queue_req); + mq->tag_set.numa_node = NUMA_NO_NODE; + /* We use blocking requests */ + mq->tag_set.flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_BLOCKING; + // BLK_MQ_F_SG_MERGE? + mq->tag_set.driver_data = mq; + + ret = blk_mq_alloc_tag_set(&mq->tag_set); + if (ret) { + dev_err(card->host->parent, "failed to allocate MQ tag set\n"); return -ENOMEM; + } - mq->qdepth = 4; - spin_lock_init(&mq->mqrq_lock); - mq->mqrq = kcalloc(mq->qdepth, sizeof(struct mmc_queue_req), - GFP_KERNEL); - if (!mq->mqrq) - goto blk_cleanup; - for (i = 0; i < mq->qdepth; i++) - mq->mqrq[i].mq = mq; + mq->queue = blk_mq_init_queue(&mq->tag_set); + if (!mq->queue) { + dev_err(card->host->parent, "failed to initialize block MQ\n"); + goto cleanup_free_tag_set; + } + + blk_queue_max_segments(mq->queue, host->max_segs); + mq->qdepth = 4; mq->queue->queuedata = mq; blk_queue_prep_rq(mq->queue, mmc_prep_request); @@ -337,18 +268,15 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, if (bouncesz > (host->max_blk_count * 512)) bouncesz = host->max_blk_count * 512; - if (bouncesz > 512 && - mmc_queue_alloc_bounce_bufs(mq, bouncesz)) { + if (bouncesz > 512) { blk_queue_bounce_limit(mq->queue, BLK_BOUNCE_ANY); blk_queue_max_hw_sectors(mq->queue, bouncesz / 512); blk_queue_max_segments(mq->queue, bouncesz / 512); blk_queue_max_segment_size(mq->queue, bouncesz); - - ret = mmc_queue_alloc_bounce_sgs(mq, bouncesz); - if (ret) - goto cleanup_queue; bounce = true; } + + mq->bouncesz = bouncesz; } #endif @@ -358,53 +286,29 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, min(host->max_blk_count, host->max_req_size / 512)); blk_queue_max_segments(mq->queue, host->max_segs); blk_queue_max_segment_size(mq->queue, host->max_seg_size); - - ret = mmc_queue_alloc_sgs(mq, host->max_segs); - if (ret) - goto cleanup_queue; - } - - sema_init(&mq->thread_sem, 1); - - mq->thread = kthread_run(mmc_queue_thread, mq, "mmcqd/%d%s", - host->index, subname ? subname : ""); - - if (IS_ERR(mq->thread)) { - ret = PTR_ERR(mq->thread); - goto cleanup_queue; } return 0; - cleanup_queue: - mmc_queue_reqs_free_bufs(mq); - kfree(mq->mqrq); - mq->mqrq = NULL; -blk_cleanup: - blk_cleanup_queue(mq->queue); +cleanup_free_tag_set: + blk_mq_free_tag_set(&mq->tag_set); + return ret; } void mmc_cleanup_queue(struct mmc_queue *mq) { struct request_queue *q = mq->queue; - unsigned long flags; /* Make sure the queue isn't suspended, as that will deadlock */ mmc_queue_resume(mq); - /* Then terminate our worker thread */ - kthread_stop(mq->thread); - /* Empty the queue */ - spin_lock_irqsave(q->queue_lock, flags); q->queuedata = NULL; blk_start_queue(q); - spin_unlock_irqrestore(q->queue_lock, flags); - mmc_queue_reqs_free_bufs(mq); - kfree(mq->mqrq); - mq->mqrq = NULL; + blk_cleanup_queue(mq->queue); + blk_mq_free_tag_set(&mq->tag_set); mq->card = NULL; } @@ -414,23 +318,16 @@ EXPORT_SYMBOL(mmc_cleanup_queue); * mmc_queue_suspend - suspend a MMC request queue * @mq: MMC queue to suspend * - * Stop the block request queue, and wait for our thread to - * complete any outstanding requests. This ensures that we + * Stop the block request queue. This ensures that we * won't suspend while a request is being processed. */ void mmc_queue_suspend(struct mmc_queue *mq) { struct request_queue *q = mq->queue; - unsigned long flags; if (!mq->suspended) { - mq->suspended |= true; - - spin_lock_irqsave(q->queue_lock, flags); + mq->suspended = true; blk_stop_queue(q); - spin_unlock_irqrestore(q->queue_lock, flags); - - down(&mq->thread_sem); } } @@ -441,16 +338,10 @@ void mmc_queue_suspend(struct mmc_queue *mq) void mmc_queue_resume(struct mmc_queue *mq) { struct request_queue *q = mq->queue; - unsigned long flags; if (mq->suspended) { mq->suspended = false; - - up(&mq->thread_sem); - - spin_lock_irqsave(q->queue_lock, flags); blk_start_queue(q); - spin_unlock_irqrestore(q->queue_lock, flags); } } diff --git a/drivers/mmc/core/queue.h b/drivers/mmc/core/queue.h index 886a05482b74..0a30fcc115ee 100644 --- a/drivers/mmc/core/queue.h +++ b/drivers/mmc/core/queue.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -28,7 +29,7 @@ struct mmc_blk_request { }; struct mmc_queue_req { - bool in_use; + struct device *dev; struct request *req; struct mmc_blk_request brq; struct scatterlist *sg; @@ -41,20 +42,20 @@ struct mmc_queue_req { struct mmc_queue { struct mmc_card *card; - struct task_struct *thread; - struct semaphore thread_sem; bool suspended; - bool asleep; + bool claimed_host; struct mmc_blk_data *blkdata; struct request_queue *queue; + struct blk_mq_tag_set tag_set; spinlock_t mqrq_lock; struct mmc_queue_req *mqrq; unsigned int qdepth; +#ifdef CONFIG_MMC_BLOCK_BOUNCE + unsigned int bouncesz; +#endif }; -extern void mmc_queue_req_put(struct mmc_queue_req *mq_rq); -extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *, - const char *); +extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, const char *); extern void mmc_cleanup_queue(struct mmc_queue *); extern void mmc_queue_suspend(struct mmc_queue *); extern void mmc_queue_resume(struct mmc_queue *);