From patchwork Tue Nov 25 11:36:20 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Krzysztof Kozlowski X-Patchwork-Id: 5377061 Return-Path: X-Original-To: patchwork-linux-mmc@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 9DEBBC11AC for ; Tue, 25 Nov 2014 11:36:52 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B56CB2015D for ; Tue, 25 Nov 2014 11:36:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A12062012D for ; Tue, 25 Nov 2014 11:36:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755007AbaKYLgf (ORCPT ); Tue, 25 Nov 2014 06:36:35 -0500 Received: from mailout3.w1.samsung.com ([210.118.77.13]:23540 "EHLO mailout3.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754644AbaKYLgc (ORCPT ); Tue, 25 Nov 2014 06:36:32 -0500 Received: from eucpsbgm1.samsung.com (unknown [203.254.199.244]) by mailout3.w1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0NFL00FCSF1M6Q40@mailout3.w1.samsung.com>; Tue, 25 Nov 2014 11:39:22 +0000 (GMT) X-AuditID: cbfec7f4-b7f126d000001e9a-c4-547469bd810c Received: from eusync2.samsung.com ( [203.254.199.212]) by eucpsbgm1.samsung.com (EUCPMTA) with SMTP id 74.DB.07834.DB964745; Tue, 25 Nov 2014 11:36:29 +0000 (GMT) Received: from AMDC1943.digital.local ([106.116.151.171]) by eusync2.samsung.com (Oracle Communications Messaging Server 7u4-23.01(7.0.4.23.0) 64bit (built Aug 10 2011)) with ESMTPA id <0NFL00EB0EWQM650@eusync2.samsung.com>; Tue, 25 Nov 2014 11:36:29 +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: [PATCH] mmc: sdhci: Fix sleep in atomic after inserting SD card Date: Tue, 25 Nov 2014 12:36:20 +0100 Message-id: <1416915380-29291-1-git-send-email-k.kozlowski@samsung.com> X-Mailer: git-send-email 1.9.1 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrAJMWRmVeSWpSXmKPExsVy+t/xK7p7M0tCDLYt1raYcHk7o8XrF4YW l3fNYbM48r+f0WLBxkeMFsfXhjuwedy5tofN48arhUwefVtWMXp83iQXwBLFZZOSmpNZllqk b5fAldG2VaXgokrF0aenWRsYH8p1MXJwSAiYSLz5Y9PFyAlkiklcuLeerYuRi0NIYCmjxNXv V9khnD4mic57z1hAqtgEjCU2L1/CBmKLCDQxSkz/6AtiMwt4Srz7+5AdxBYW8JD4sPUcE4jN IqAqMa1xMyuIzSvgLrF05QU2iG1yEiePTWadwMi9gJFhFaNoamlyQXFSeq6hXnFibnFpXrpe cn7uJkZIKHzZwbj4mNUhRgEORiUeXoPEkhAh1sSy4srcQ4wSHMxKIrxPkoFCvCmJlVWpRfnx RaU5qcWHGJk4OKUaGP3fnuTLXX7zYcK5O0vnTRf35tyzkbnYRt59SdPm+Md3L1RLFTJLOPh8 0thZ5F1vN/lmTWaej5n+XuW4G9vzij7qHW36vq7v9L2itFJfR5nuoNptJxrXa3cJFMhE+nxb WF0dsf3cZbmnUvtzLsYb3p83zyPJqedohF7MxdezplXbyq149HN6gBJLcUaioRZzUXEiAE1e jkTjAQAA 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: [ 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 [ 42.043663] mmcblk1: mmc0:1234 SA32G 29.3 GiB [ 42.054667] mmcblk1: p1 p2 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 73de62a58d70..8ac79d085869 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",