From patchwork Thu Aug 31 11:56:47 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrian Hunter X-Patchwork-Id: 9932013 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 1512A60309 for ; Thu, 31 Aug 2017 12:03:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0626E27F92 for ; Thu, 31 Aug 2017 12:03:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EF0FD2892D; Thu, 31 Aug 2017 12:03:40 +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.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI 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 C6CB827F92 for ; Thu, 31 Aug 2017 12:03:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751250AbdHaMDj (ORCPT ); Thu, 31 Aug 2017 08:03:39 -0400 Received: from mga14.intel.com ([192.55.52.115]:35193 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751057AbdHaMDi (ORCPT ); Thu, 31 Aug 2017 08:03:38 -0400 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 31 Aug 2017 05:03:37 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.41,453,1498546800"; d="scan'208";a="1167905344" Received: from ahunter-desktop.fi.intel.com ([10.237.72.168]) by orsmga001.jf.intel.com with ESMTP; 31 Aug 2017 05:03:32 -0700 From: Adrian Hunter To: Ulf Hansson Cc: linux-mmc , linux-block , Bough Chen , Alex Lemberg , Mateusz Nowak , Yuliy Izrailov , Jaehoon Chung , Dong Aisheng , Das Asutosh , Zhangfei Gao , Sahitya Tummala , Harjani Ritesh , Venu Byravarasu , Linus Walleij , Shawn Lin Subject: [PATCH V7 01/10] mmc: core: Introduce host claiming by context Date: Thu, 31 Aug 2017 14:56:47 +0300 Message-Id: <1504180616-14514-2-git-send-email-adrian.hunter@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1504180616-14514-1-git-send-email-adrian.hunter@intel.com> References: <1504180616-14514-1-git-send-email-adrian.hunter@intel.com> Organization: Intel Finland Oy, Registered Address: PL 281, 00181 Helsinki, Business Identity Code: 0357606 - 4, Domiciled in Helsinki 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 Currently the host can be claimed by a task. Change this so that the host can be claimed by a context that may or may not be a task. This provides for the host to be claimed by a block driver queue to support blk-mq, while maintaining compatibility with the existing use of mmc_claim_host(). Signed-off-by: Adrian Hunter --- drivers/mmc/core/core.c | 109 ++++++++++++++++++++++++++++++++++++++++++++--- drivers/mmc/core/core.h | 8 ++++ include/linux/mmc/host.h | 7 ++- 3 files changed, 116 insertions(+), 8 deletions(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 66c9cf49ad2f..6a0ca128a520 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -832,9 +832,38 @@ unsigned int mmc_align_data_size(struct mmc_card *card, unsigned int sz) } EXPORT_SYMBOL(mmc_align_data_size); +/* + * Allow claiming an already claimed host if the context is the same or there is + * no context but the task is the same. + */ +static inline bool mmc_ctx_matches(struct mmc_host *host, struct mmc_ctx *ctx, + struct task_struct *task) +{ + return host->claimer == ctx || + (!ctx && task && host->claimer->task == task); +} + +static inline void mmc_ctx_set_claimer(struct mmc_host *host, + struct mmc_ctx *ctx, + struct task_struct *task) +{ + if (!host->claimer) { + if (ctx) + host->claimer = ctx; + else + host->claimer = &host->default_ctx; + } + if (task) + host->claimer->task = task; +} + /** - * __mmc_claim_host - exclusively claim a host + * __mmc_ctx_task_claim_host - exclusively claim a host * @host: mmc host to claim + * @ctx: context that claims the host or NULL in which case the default + * context will be used + * @task: task that claims the host or NULL in which case @ctx must be + * provided * @abort: whether or not the operation should be aborted * * Claim a host for a set of operations. If @abort is non null and @@ -842,7 +871,8 @@ unsigned int mmc_align_data_size(struct mmc_card *card, unsigned int sz) * that non-zero value without acquiring the lock. Returns zero * with the lock held otherwise. */ -int __mmc_claim_host(struct mmc_host *host, atomic_t *abort) +static int __mmc_ctx_task_claim_host(struct mmc_host *host, struct mmc_ctx *ctx, + struct task_struct *task, atomic_t *abort) { DECLARE_WAITQUEUE(wait, current); unsigned long flags; @@ -856,7 +886,7 @@ int __mmc_claim_host(struct mmc_host *host, atomic_t *abort) while (1) { set_current_state(TASK_UNINTERRUPTIBLE); stop = abort ? atomic_read(abort) : 0; - if (stop || !host->claimed || host->claimer == current) + if (stop || !host->claimed || mmc_ctx_matches(host, ctx, task)) break; spin_unlock_irqrestore(&host->lock, flags); schedule(); @@ -865,7 +895,7 @@ int __mmc_claim_host(struct mmc_host *host, atomic_t *abort) set_current_state(TASK_RUNNING); if (!stop) { host->claimed = 1; - host->claimer = current; + mmc_ctx_set_claimer(host, ctx, task); host->claim_cnt += 1; if (host->claim_cnt == 1) pm = true; @@ -879,8 +909,25 @@ int __mmc_claim_host(struct mmc_host *host, atomic_t *abort) return stop; } + +int __mmc_claim_host(struct mmc_host *host, atomic_t *abort) +{ + return __mmc_ctx_task_claim_host(host, NULL, current, abort); +} EXPORT_SYMBOL(__mmc_claim_host); +void mmc_ctx_claim_host(struct mmc_host *host, struct mmc_ctx *ctx) +{ + __mmc_ctx_task_claim_host(host, ctx, NULL, NULL); +} +EXPORT_SYMBOL(mmc_ctx_claim_host); + +void mmc_ctx_task_claim_host(struct mmc_host *host, struct mmc_ctx *ctx) +{ + __mmc_ctx_task_claim_host(host, ctx, current, NULL); +} +EXPORT_SYMBOL(mmc_ctx_task_claim_host); + /** * mmc_release_host - release a host * @host: mmc host to release @@ -888,18 +935,19 @@ int __mmc_claim_host(struct mmc_host *host, atomic_t *abort) * Release a MMC host, allowing others to claim the host * for their operations. */ -void mmc_release_host(struct mmc_host *host) +static void __mmc_release_host(struct mmc_host *host, bool task_release) { unsigned long flags; - WARN_ON(!host->claimed); - spin_lock_irqsave(&host->lock, flags); if (--host->claim_cnt) { /* Release for nested claim */ + if (task_release) + host->claimer->task = NULL; spin_unlock_irqrestore(&host->lock, flags); } else { host->claimed = 0; + host->claimer->task = NULL; host->claimer = NULL; spin_unlock_irqrestore(&host->lock, flags); wake_up(&host->wq); @@ -907,8 +955,32 @@ void mmc_release_host(struct mmc_host *host) pm_runtime_put_autosuspend(mmc_dev(host)); } } + +void mmc_release_host(struct mmc_host *host) +{ + WARN_ON(!host->claimed); + + __mmc_release_host(host, false); +} EXPORT_SYMBOL(mmc_release_host); +void mmc_ctx_release_host(struct mmc_host *host, struct mmc_ctx *ctx) +{ + WARN_ON(!host->claimed || host->claimer != ctx); + + __mmc_release_host(host, false); +} +EXPORT_SYMBOL(mmc_ctx_release_host); + +void mmc_ctx_task_release_host(struct mmc_host *host, struct mmc_ctx *ctx) +{ + WARN_ON(!host->claimed || host->claimer != ctx || + host->claimer->task != current); + + __mmc_release_host(host, true); +} +EXPORT_SYMBOL(mmc_ctx_task_release_host); + /* * This is a helper function, which fetches a runtime pm reference for the * card device and also claims the host. @@ -921,6 +993,17 @@ void mmc_get_card(struct mmc_card *card) EXPORT_SYMBOL(mmc_get_card); /* + * This is a helper function, which fetches a runtime pm reference for the + * card device and also claims the host for the mmc context. + */ +void mmc_ctx_get_card(struct mmc_card *card, struct mmc_ctx *ctx) +{ + pm_runtime_get_sync(&card->dev); + mmc_ctx_claim_host(card->host, ctx); +} +EXPORT_SYMBOL(mmc_ctx_get_card); + +/* * This is a helper function, which releases the host and drops the runtime * pm reference for the card device. */ @@ -933,6 +1016,18 @@ void mmc_put_card(struct mmc_card *card) EXPORT_SYMBOL(mmc_put_card); /* + * This is a helper function, which releases the host and drops the runtime + * pm reference for the card device. + */ +void mmc_ctx_put_card(struct mmc_card *card, struct mmc_ctx *ctx) +{ + mmc_ctx_release_host(card->host, ctx); + pm_runtime_mark_last_busy(&card->dev); + pm_runtime_put_autosuspend(&card->dev); +} +EXPORT_SYMBOL(mmc_ctx_put_card); + +/* * Internal function that does the actual ios call to the host driver, * optionally printing some debug output. */ diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index ca861091a776..a79b6054a7b2 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h @@ -144,4 +144,12 @@ static inline void mmc_claim_host(struct mmc_host *host) __mmc_claim_host(host, NULL); } +void mmc_ctx_claim_host(struct mmc_host *host, struct mmc_ctx *ctx); +void mmc_ctx_release_host(struct mmc_host *host, struct mmc_ctx *ctx); +void mmc_ctx_task_claim_host(struct mmc_host *host, struct mmc_ctx *ctx); +void mmc_ctx_task_release_host(struct mmc_host *host, struct mmc_ctx *ctx); + +void mmc_ctx_get_card(struct mmc_card *card, struct mmc_ctx *ctx); +void mmc_ctx_put_card(struct mmc_card *card, struct mmc_ctx *ctx); + #endif diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index f3f2d07feb2a..228a493c3b25 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -255,6 +255,10 @@ struct mmc_supply { struct regulator *vqmmc; /* Optional Vccq supply */ }; +struct mmc_ctx { + struct task_struct *task; +}; + struct mmc_host { struct device *parent; struct device class_dev; @@ -388,8 +392,9 @@ struct mmc_host { struct mmc_card *card; /* device attached to this host */ wait_queue_head_t wq; - struct task_struct *claimer; /* task that has host claimed */ + struct mmc_ctx *claimer; /* context that has host claimed */ int claim_cnt; /* "claim" nesting count */ + struct mmc_ctx default_ctx; /* default context */ struct delayed_work detect; int detect_change; /* card detect flag */