From patchwork Mon Jan 5 09:50:15 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Krzysztof Kozlowski X-Patchwork-Id: 5566161 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 653149F4DC for ; Mon, 5 Jan 2015 09:50:33 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 52E752015A for ; Mon, 5 Jan 2015 09:50:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CF3E420142 for ; Mon, 5 Jan 2015 09:50:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751420AbbAEJu3 (ORCPT ); Mon, 5 Jan 2015 04:50:29 -0500 Received: from mailout4.w1.samsung.com ([210.118.77.14]:34532 "EHLO mailout4.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751133AbbAEJu2 (ORCPT ); Mon, 5 Jan 2015 04:50:28 -0500 Received: from eucpsbgm1.samsung.com (unknown [203.254.199.244]) by mailout4.w1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0NHP00IIY7IRMV70@mailout4.w1.samsung.com>; Mon, 05 Jan 2015 09:54:27 +0000 (GMT) X-AuditID: cbfec7f4-b7f126d000001e9a-c9-54aa5e618f8b Received: from eusync4.samsung.com ( [203.254.199.214]) by eucpsbgm1.samsung.com (EUCPMTA) with SMTP id 43.B3.07834.16E5AA45; Mon, 05 Jan 2015 09:50:25 +0000 (GMT) Received: from AMDC1943.digital.local ([106.116.151.171]) by eusync4.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0NHP00IPD7BWMQ20@eusync4.samsung.com>; Mon, 05 Jan 2015 09:50:25 +0000 (GMT) From: Krzysztof Kozlowski To: Chris Ball , Ulf Hansson , linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Krzysztof Kozlowski , stable@vger.kernel.org Subject: [RESEND PATCH] mmc: sdhci: Fix sleep in atomic after inserting SD card Date: Mon, 05 Jan 2015 10:50:15 +0100 Message-id: <1420451415-11828-1-git-send-email-k.kozlowski@samsung.com> X-Mailer: git-send-email 1.9.1 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrEJMWRmVeSWpSXmKPExsVy+t/xa7qJcatCDN4tZbOYcHk7o8XrF4YW l3fNYbM48r+f0WLBxkeMFsfXhjuwedy5tofN48arhUwefVtWMXp83iQXwBLFZZOSmpNZllqk b5fAlbGnaQ5bwXSVimldP9gbGLfJdTFyckgImEg8fTSdEcIWk7hwbz1bFyMXh5DAUkaJVXt/ MUI4fUwSbZNvsINUsQkYS2xevoQNxBYRaGKUmP7RF8RmFvCUePf3IViNsIC/xNOjz1lBbBYB VYmZk2aC2bwC7hLHflyG2iYncfLYZNYJjNwLGBlWMYqmliYXFCel5xrqFSfmFpfmpesl5+du YoSEw5cdjIuPWR1iFOBgVOLh9TixMkSINbGsuDL3EKMEB7OSCO+6W0Ah3pTEyqrUovz4otKc 1OJDjEwcnFINjI3bp8UxGBZ9Y1RrOG1gqj+5nn3XxkvvVbKWMS6LvPtjy+6bBsURTU5Z5yOV C6JnJ+95+f28HsOvWyGXd3kLF+Qy9Cw+179I8uBV1k6LVHfTSokV6Vbeqx3mWjId775e65y3 yuxTsWTSwk0S6gvifjuumWObsjuPWWu6kNWGzs2PE7pnPGuvVGIpzkg01GIuKk4EAJ4AGPPl AQAA 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.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable 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 Sleep in atomic context happened on Trats2 board after inserting or removing SD card because mmc_gpio_get_cd() was called under spin lock. Fix this by moving card detection earlier, before acquiring spin lock. The mmc_gpio_get_cd() call does not have to be protected by spin lock because it does not access any sdhci internal data. The sdhci_do_get_cd() call access host flags (SDHCI_DEVICE_DEAD). After moving it out side of spin lock it could theoretically race with driver removal but still there is no actual protection against manual card eject. Dmesg after inserting SD card: [ 41.663414] BUG: sleeping function called from invalid context at drivers/gpio/gpiolib.c:1511 [ 41.670469] in_atomic(): 1, irqs_disabled(): 128, pid: 30, name: kworker/u8:1 [ 41.677580] INFO: lockdep is turned off. [ 41.681486] irq event stamp: 61972 [ 41.684872] hardirqs last enabled at (61971): [] _raw_spin_unlock_irq+0x24/0x5c [ 41.693118] hardirqs last disabled at (61972): [] _raw_spin_lock_irq+0x18/0x54 [ 41.701190] softirqs last enabled at (61648): [] __do_softirq+0x234/0x2c8 [ 41.708914] softirqs last disabled at (61631): [] irq_exit+0xd0/0x114 [ 41.716206] Preemption disabled at:[< (null)>] (null) [ 41.721500] [ 41.722985] CPU: 3 PID: 30 Comm: kworker/u8:1 Tainted: G W 3.18.0-rc5-next-20141121 #883 [ 41.732111] Workqueue: kmmcd mmc_rescan [ 41.735945] [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [ 41.743661] [] (show_stack) from [] (dump_stack+0x70/0xbc) [ 41.750867] [] (dump_stack) from [] (gpiod_get_raw_value_cansleep+0x18/0x30) [ 41.759628] [] (gpiod_get_raw_value_cansleep) from [] (mmc_gpio_get_cd+0x38/0x58) [ 41.768821] [] (mmc_gpio_get_cd) from [] (sdhci_request+0x50/0x1a4) [ 41.776808] [] (sdhci_request) from [] (mmc_start_request+0x138/0x268) [ 41.785051] [] (mmc_start_request) from [] (mmc_wait_for_req+0x58/0x1a0) [ 41.793469] [] (mmc_wait_for_req) from [] (mmc_wait_for_cmd+0x58/0x78) [ 41.801714] [] (mmc_wait_for_cmd) from [] (mmc_io_rw_direct_host+0x98/0x124) [ 41.810480] [] (mmc_io_rw_direct_host) from [] (sdio_reset+0x2c/0x64) [ 41.818641] [] (sdio_reset) from [] (mmc_rescan+0x254/0x2e4) [ 41.826028] [] (mmc_rescan) from [] (process_one_work+0x180/0x3f4) [ 41.833920] [] (process_one_work) from [] (worker_thread+0x34/0x4b0) [ 41.841991] [] (worker_thread) from [] (kthread+0xe4/0x104) [ 41.849285] [] (kthread) from [] (ret_from_fork+0x14/0x2c) [ 42.038276] mmc0: new high speed SDHC card at address 1234 Signed-off-by: Krzysztof Kozlowski Fixes: 94144a465dd0 ("mmc: sdhci: add get_cd() implementation") Cc: --- drivers/mmc/host/sdhci.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index cbb245b58538..8a94c126c576 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1353,6 +1353,8 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) sdhci_runtime_pm_get(host); + present = mmc_gpio_get_cd(host->mmc); + spin_lock_irqsave(&host->lock, flags); WARN_ON(host->mrq != NULL); @@ -1381,7 +1383,6 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) * zero: cd-gpio is used, and card is removed * one: cd-gpio is used, and card is present */ - present = mmc_gpio_get_cd(host->mmc); if (present < 0) { /* If polling, assume that the card is always present. */ if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) @@ -2110,15 +2111,18 @@ static void sdhci_card_event(struct mmc_host *mmc) { struct sdhci_host *host = mmc_priv(mmc); unsigned long flags; + int present; /* First check if client has provided their own card event */ if (host->ops->card_event) host->ops->card_event(host); + present = sdhci_do_get_cd(host); + spin_lock_irqsave(&host->lock, flags); /* Check host->mrq first in case we are runtime suspended */ - if (host->mrq && !sdhci_do_get_cd(host)) { + if (host->mrq && !present) { pr_err("%s: Card removed during transfer!\n", mmc_hostname(host->mmc)); pr_err("%s: Resetting controller.\n",