From patchwork Thu May 11 12:39:02 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulf Hansson X-Patchwork-Id: 9721371 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 8744F601E7 for ; Thu, 11 May 2017 12:39:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7C6FD28652 for ; Thu, 11 May 2017 12:39:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7129E28660; Thu, 11 May 2017 12:39:14 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 08DBA28652 for ; Thu, 11 May 2017 12:39:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932732AbdEKMjM (ORCPT ); Thu, 11 May 2017 08:39:12 -0400 Received: from mail-wr0-f182.google.com ([209.85.128.182]:35901 "EHLO mail-wr0-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932730AbdEKMjL (ORCPT ); Thu, 11 May 2017 08:39:11 -0400 Received: by mail-wr0-f182.google.com with SMTP id l50so19421586wrc.3 for ; Thu, 11 May 2017 05:39:10 -0700 (PDT) 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=4dPoyW1Q25bFcFdk/CwHC/dXRZb6eYQA9pRjDQsrLds=; b=GTZKcRjW4O5pcqM/GSNbJTN0QwvgS3vhtwlZLTWnUtEx2NQUjSPUd38y9TMqzPxHII grJQjOpgr0xrMsjp5n/6RjLs1/jVePMKM01vPXbMxV/CRKvm0/ECxbYvff0T5rO3Zpay x2Tmp5PgaLLahohKgVnLoKlYijsDDo47IOeIU= 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=4dPoyW1Q25bFcFdk/CwHC/dXRZb6eYQA9pRjDQsrLds=; b=dR1NXYk1lmLxmUjo4jFv0QobH0+V15xxWKDIwnFkWzuKpG4vgmRaBOqWkgezXNe2RY Yi05ADtKN+IruFjuCLi937HN/Fn7WJAKrXJlKwuLjeAce1OfA+SIJqD5xy9Db2JkBD0J DRpQv6fWiOycFVyGmEmxvhcizxrY1tAhfsuw/yoTJtmY8WtPU7V7KQIGbF1CT1YaM25s qB0ZI/EV8Y6pfQOlEDzv/W7+PHfIuDJqIrkd9ranTm4iW3U6vHHJRO0MvLxgGbcygh7l ItSs9+kBS0waveXdTjhil1ePeGz4mFRLdJTaKDjZJxr9MzpKM6FYeJt3QYiue/0i/Gvi lUbg== X-Gm-Message-State: AODbwcDueAdiRhJTwMyDy1M6/CzgFP6sMeKzxE6BQmMibpVueAmRKgav ceSYal0Hz3XvUMhz X-Received: by 10.46.33.146 with SMTP id h18mr43495lji.86.1494506349341; Thu, 11 May 2017 05:39:09 -0700 (PDT) Received: from localhost.localdomain (h-155-4-221-67.na.cust.bahnhof.se. [155.4.221.67]) by smtp.gmail.com with ESMTPSA id h13sm13935ljh.5.2017.05.11.05.39.08 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 11 May 2017 05:39:08 -0700 (PDT) From: Ulf Hansson To: linux-mmc@vger.kernel.org, Ulf Hansson Cc: Jens Axboe , Paolo Valente , linux-block@vger.kernel.org, Linus Walleij , Mark Brown , Adrian Hunter Subject: [RFC PATCH 3/3] mmc: core: Allow mmc block device to re-claim the host Date: Thu, 11 May 2017 14:39:02 +0200 Message-Id: <1494506343-28572-4-git-send-email-ulf.hansson@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1494506343-28572-1-git-send-email-ulf.hansson@linaro.org> References: <1494506343-28572-1-git-send-email-ulf.hansson@linaro.org> Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The current mmc block device implementation is tricky when it comes to claim and release of the host, while processing I/O requests. In principle we need to claim the host at the first request entering the queue and then we need to release the host, as soon as the queue becomes empty. This complexity relates to the asynchronous request mechanism that the mmc block device driver implements. For the legacy block interface that we currently implements, the above issue can be addressed, as we can find out when the queue really becomes empty. However, to find out whether the queue is empty, isn't really an applicable method when using the new blk-mq interface, as requests are instead pushed to us via the struct struct blk_mq_ops and its function pointers. Being able to support the asynchronous request method using the blk-mq interface, means we have to allow the mmc block device driver to re-claim the host from different tasks/contexts, as we may have > 1 request to operate upon. Therefore, let's extend the mmc_claim_host() API to support reference counting for the mmc block device. Signed-off-by: Ulf Hansson --- drivers/mmc/core/core.c | 14 ++++++++++---- drivers/mmc/core/core.h | 7 ++++++- include/linux/mmc/host.h | 1 + 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 0701e30..3633699 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1019,12 +1019,12 @@ unsigned int mmc_align_data_size(struct mmc_card *card, unsigned int sz) EXPORT_SYMBOL(mmc_align_data_size); /** - * mmc_claim_host - exclusively claim a host + * __mmc_claim_host - exclusively claim a host * @host: mmc host to claim * * Claim a host for a set of operations. */ -void mmc_claim_host(struct mmc_host *host) +void __mmc_claim_host(struct mmc_host *host, bool is_blkdev) { DECLARE_WAITQUEUE(wait, current); unsigned long flags; @@ -1036,7 +1036,11 @@ void mmc_claim_host(struct mmc_host *host) spin_lock_irqsave(&host->lock, flags); while (1) { set_current_state(TASK_UNINTERRUPTIBLE); - if (!host->claimed || host->claimer == current) + if (!host->claimed) + break; + if (host->claimer_is_blkdev && is_blkdev) + break; + if (host->claimer == current) break; spin_unlock_irqrestore(&host->lock, flags); schedule(); @@ -1045,6 +1049,7 @@ void mmc_claim_host(struct mmc_host *host) set_current_state(TASK_RUNNING); host->claimed = 1; host->claimer = current; + host->claimer_is_blkdev = is_blkdev; host->claim_cnt += 1; if (host->claim_cnt == 1) pm = true; @@ -1054,7 +1059,7 @@ void mmc_claim_host(struct mmc_host *host) if (pm) pm_runtime_get_sync(mmc_dev(host)); } -EXPORT_SYMBOL(mmc_claim_host); +EXPORT_SYMBOL(__mmc_claim_host); /** * mmc_release_host - release a host @@ -1076,6 +1081,7 @@ void mmc_release_host(struct mmc_host *host) } else { host->claimed = 0; host->claimer = NULL; + host->claimer_is_blkdev = 0; spin_unlock_irqrestore(&host->lock, flags); wake_up(&host->wq); pm_runtime_mark_last_busy(mmc_dev(host)); diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index b247b1f..1598a37 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h @@ -122,9 +122,14 @@ int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen); int mmc_set_blockcount(struct mmc_card *card, unsigned int blockcount, bool is_rel_write); -void mmc_claim_host(struct mmc_host *host); +void __mmc_claim_host(struct mmc_host *host, bool is_blkdev); void mmc_release_host(struct mmc_host *host); void mmc_get_card(struct mmc_card *card); void mmc_put_card(struct mmc_card *card); +static inline void mmc_claim_host(struct mmc_host *host) +{ + __mmc_claim_host(host, 0); +} + #endif diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 8a4131f..7199817 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -347,6 +347,7 @@ struct mmc_host { wait_queue_head_t wq; struct task_struct *claimer; /* task that has host claimed */ + bool claimer_is_blkdev; /* claimer is blkdev */ int claim_cnt; /* "claim" nesting count */ struct delayed_work detect;