From patchwork Tue Dec 1 15:15:16 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulf Hansson X-Patchwork-Id: 7738051 Return-Path: X-Original-To: patchwork-linux-mmc@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id DD39B9F1C2 for ; Tue, 1 Dec 2015 15:16:18 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 32F6B204D5 for ; Tue, 1 Dec 2015 15:16:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6B2A52043C for ; Tue, 1 Dec 2015 15:16:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751881AbbLAPQD (ORCPT ); Tue, 1 Dec 2015 10:16:03 -0500 Received: from mail-lf0-f53.google.com ([209.85.215.53]:36296 "EHLO mail-lf0-f53.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753996AbbLAPP1 (ORCPT ); Tue, 1 Dec 2015 10:15:27 -0500 Received: by lfs39 with SMTP id 39so11288343lfs.3 for ; Tue, 01 Dec 2015 07:15:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro-org.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id; bh=QlXkIbz+Irvo0HkHqkmfJBX0F3sHDmhKiuCbTxtj/gI=; b=U2VUtImoeBEK9OWK7x4U7XB3PEQ7Kqqg1jkGXuBr45p5919EJo0u7bT4KGllpPHO/T bY71Bvx3i3qOETJvSfKAMTRpte06iB90noiU8cEFXma0lpCHpSmNB76Kqau+BhFMHKI7 +xJWdu+yR1mPYxLRD3QxNJUB0iDlaGiHzyDLt2sqJCucWM39uaxJ3z1TXqGjFX4HuywV O5S2XsQe48KHuvdGlliSlONMLJy/8C+WHKQUFC7pyMXqYDJmVCzqf0djOy7OHKeyapwk sJavnZJ/T/7yL9baCuRDLvK9FgdHri8FyfW0hooTZK/TZnEDhvXgmu5vDiF4kPqrSvWu pZ+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=QlXkIbz+Irvo0HkHqkmfJBX0F3sHDmhKiuCbTxtj/gI=; b=Vd08XQXW82C1z2CMS0MnTpQMBjPr5Z6U8/FrT8ZdJztVH+PzbkH4Lse60o9w87Zmxh ksa9NssdHfbGZK+MCazoAqIC/uATpuxUy523j6mosbNlZdKRI69x3vFn20x2XyE/lkYC dn7jlyv9xptWxOyKlSo7gmgeuTQGVWweBt9ifwecBB67F26dZPXEF5oCpJCBQ0fEOcLw uA13FR1qaJHvYA1bxbvkEdSW1a1zM/E91k91MLttEtHu7akwgiQWGas+6DftopcH1hi9 Uf98nrBs838XKTi0MAwi+EFGwFPBdwIdRT3XSWDfVjoFSZbBjwK9/hWv3F+IBSUd8vHO NS8A== X-Gm-Message-State: ALoCoQnG3Ua1Ra/5i/oQGcJbI0p/MvEM+VSl2yGK6+a9iUBHKu6hg+1IuL6m/Dh2e7YVnRW0GT71 X-Received: by 10.112.129.134 with SMTP id nw6mr29687001lbb.10.1448982923788; Tue, 01 Dec 2015 07:15:23 -0800 (PST) Received: from uffe-Latitude-E6430s.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id aa4sm7781575lbc.10.2015.12.01.07.15.22 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 01 Dec 2015 07:15:23 -0800 (PST) From: Ulf Hansson To: linux-mmc@vger.kernel.org, Ulf Hansson Cc: Jaehoon Chung Subject: [PATCH] mmc: core: Optimize boot time by detecting cards simultaneously Date: Tue, 1 Dec 2015 16:15:16 +0100 Message-Id: <1448982916-21485-1-git-send-email-ulf.hansson@linaro.org> X-Mailer: git-send-email 1.9.1 Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID,T_RP_MATCHES_RCVD,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The mmc workqueue is an ordered workqueue, allowing only one work to execute per given time. As this workqueue is used for card detection, the conseqeunce is that cards will be detected one by one waiting for each other. Moreover, most of the time spent during card initialization is waiting for the card's internal firmware to be ready. From a CPU perspective this typically means waiting for a completion variable to be kicked via an IRQ-handler or waiting for a sleep timer to finish. This behaviour of detecting/initializing cards is sub-optimal, especially for SOCs having several controllers/cards. Let's convert to use the system_freezable_wq for the mmc detect works. This enables several works to be executed simultaneously and thus also cards to be detected like so. Tests on UX500, which holds two eMMC cards and an SD-card (actually also an SDIO card, currently not detected), shows a significant improved behaviour due to this change. Before this change, both the eMMC cards waited for the SD card to be initialized as its detect work entered the workqueue first. In some cases, depending on the characteristic of the SD-card, they got delayed 1-1.5 s. Additionally for the second eMMC, it needed to wait for the first eMMC to be initialized which added another 120-190 ms. Converting to the system_freezable_wq, removed these delays and made both the eMMC cards available far earlier in the boot sequence. Selecting the system_freezable_wq, in favour of for example the system_wq, is because we need card detection mechanism to be disabled once userspace are frozen during system PM. Currently the mmc core deal with this via PM notifiers, but following patches may utilize the behaviour of the system_freezable_wq, to simplify the use of the PM notifiers. Signed-off-by: Ulf Hansson --- drivers/mmc/core/core.c | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 910aa25..f95d41f 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -55,7 +55,6 @@ */ #define MMC_BKOPS_MAX_TIMEOUT (4 * 60 * 1000) /* max time to wait in ms */ -static struct workqueue_struct *workqueue; static const unsigned freqs[] = { 400000, 300000, 200000, 100000 }; /* @@ -66,21 +65,16 @@ static const unsigned freqs[] = { 400000, 300000, 200000, 100000 }; bool use_spi_crc = 1; module_param(use_spi_crc, bool, 0); -/* - * Internal function. Schedule delayed work in the MMC work queue. - */ static int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay) { - return queue_delayed_work(workqueue, work, delay); -} - -/* - * Internal function. Flush all scheduled work from the MMC work queue. - */ -static void mmc_flush_scheduled_work(void) -{ - flush_workqueue(workqueue); + /* + * We use the system_freezable_wq, because of two reasons. + * First, it allows several works (not the same work item) to be + * executed simultaneously. Second, the queue becomes frozen when + * userspace becomes frozen during system PM. + */ + return queue_delayed_work(system_freezable_wq, work, delay); } #ifdef CONFIG_FAIL_MMC_REQUEST @@ -2669,7 +2663,6 @@ void mmc_stop_host(struct mmc_host *host) host->rescan_disable = 1; cancel_delayed_work_sync(&host->detect); - mmc_flush_scheduled_work(); /* clear pm flags now and let card drivers set them as needed */ host->pm_flags = 0; @@ -2852,13 +2845,9 @@ static int __init mmc_init(void) { int ret; - workqueue = alloc_ordered_workqueue("kmmcd", 0); - if (!workqueue) - return -ENOMEM; - ret = mmc_register_bus(); if (ret) - goto destroy_workqueue; + return ret; ret = mmc_register_host_class(); if (ret) @@ -2874,9 +2863,6 @@ unregister_host_class: mmc_unregister_host_class(); unregister_bus: mmc_unregister_bus(); -destroy_workqueue: - destroy_workqueue(workqueue); - return ret; } @@ -2885,7 +2871,6 @@ static void __exit mmc_exit(void) sdio_unregister_bus(); mmc_unregister_host_class(); mmc_unregister_bus(); - destroy_workqueue(workqueue); } subsys_initcall(mmc_init);