diff options
author | Lauri Hintsala <lauri.hintsala@bluegiga.com> | 2012-07-17 17:16:10 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-04-14 06:44:32 -0700 |
commit | 82d16b39266179ca80f6b81b4084631ade240219 (patch) | |
tree | 6440323afd6857eb0565acaacf5b963d2b48af30 /drivers/mmc | |
parent | faf100389a5479de77294b8ebe98ec4e775d6927 (diff) |
mmc: mxs-mmc: fix deadlock caused by recursion loop
commit fc108d24d3a6da63576a460e122fa1df0cbdea20 upstream.
Release the lock before mmc_signal_sdio_irq is called by
mxs_mmc_enable_sdio_irq.
Backtrace:
[ 65.470000] =============================================
[ 65.470000] [ INFO: possible recursive locking detected ]
[ 65.470000] 3.5.0-rc5 #2 Not tainted
[ 65.470000] ---------------------------------------------
[ 65.470000] ksdioirqd/mmc0/73 is trying to acquire lock:
[ 65.470000] (&(&host->lock)->rlock#2){-.-...}, at: [<bf054120>] mxs_mmc_enable_sdio_irq+0x18/0xdc [mxs_mmc]
[ 65.470000]
[ 65.470000] but task is already holding lock:
[ 65.470000] (&(&host->lock)->rlock#2){-.-...}, at: [<bf054120>] mxs_mmc_enable_sdio_irq+0x18/0xdc [mxs_mmc]
[ 65.470000]
[ 65.470000] other info that might help us debug this:
[ 65.470000] Possible unsafe locking scenario:
[ 65.470000]
[ 65.470000] CPU0
[ 65.470000] ----
[ 65.470000] lock(&(&host->lock)->rlock#2);
[ 65.470000] lock(&(&host->lock)->rlock#2);
[ 65.470000]
[ 65.470000] *** DEADLOCK ***
[ 65.470000]
[ 65.470000] May be due to missing lock nesting notation
[ 65.470000]
[ 65.470000] 1 lock held by ksdioirqd/mmc0/73:
[ 65.470000] #0: (&(&host->lock)->rlock#2){-.-...}, at: [<bf054120>] mxs_mmc_enable_sdio_irq+0x18/0xdc [mxs_mmc]
[ 65.470000]
[ 65.470000] stack backtrace:
[ 65.470000] [<c0014990>] (unwind_backtrace+0x0/0xf4) from [<c005ccb8>] (__lock_acquire+0x14f8/0x1b98)
[ 65.470000] [<c005ccb8>] (__lock_acquire+0x14f8/0x1b98) from [<c005d3f8>] (lock_acquire+0xa0/0x108)
[ 65.470000] [<c005d3f8>] (lock_acquire+0xa0/0x108) from [<c02f671c>] (_raw_spin_lock_irqsave+0x48/0x5c)
[ 65.470000] [<c02f671c>] (_raw_spin_lock_irqsave+0x48/0x5c) from [<bf054120>] (mxs_mmc_enable_sdio_irq+0x18/0xdc [mxs_mmc])
[ 65.470000] [<bf054120>] (mxs_mmc_enable_sdio_irq+0x18/0xdc [mxs_mmc]) from [<bf0541d0>] (mxs_mmc_enable_sdio_irq+0xc8/0xdc [mxs_mmc])
[ 65.470000] [<bf0541d0>] (mxs_mmc_enable_sdio_irq+0xc8/0xdc [mxs_mmc]) from [<c0219b38>] (sdio_irq_thread+0x1bc/0x274)
[ 65.470000] [<c0219b38>] (sdio_irq_thread+0x1bc/0x274) from [<c003c324>] (kthread+0x8c/0x98)
[ 65.470000] [<c003c324>] (kthread+0x8c/0x98) from [<c00101ac>] (kernel_thread_exit+0x0/0x8)
[ 65.470000] BUG: spinlock lockup suspected on CPU#0, ksdioirqd/mmc0/73
[ 65.470000] lock: 0xc3358724, .magic: dead4ead, .owner: ksdioirqd/mmc0/73, .owner_cpu: 0
[ 65.470000] [<c0014990>] (unwind_backtrace+0x0/0xf4) from [<c01b46b0>] (do_raw_spin_lock+0x100/0x144)
[ 65.470000] [<c01b46b0>] (do_raw_spin_lock+0x100/0x144) from [<c02f6724>] (_raw_spin_lock_irqsave+0x50/0x5c)
[ 65.470000] [<c02f6724>] (_raw_spin_lock_irqsave+0x50/0x5c) from [<bf054120>] (mxs_mmc_enable_sdio_irq+0x18/0xdc [mxs_mmc])
[ 65.470000] [<bf054120>] (mxs_mmc_enable_sdio_irq+0x18/0xdc [mxs_mmc]) from [<bf0541d0>] (mxs_mmc_enable_sdio_irq+0xc8/0xdc [mxs_mmc])
[ 65.470000] [<bf0541d0>] (mxs_mmc_enable_sdio_irq+0xc8/0xdc [mxs_mmc]) from [<c0219b38>] (sdio_irq_thread+0x1bc/0x274)
[ 65.470000] [<c0219b38>] (sdio_irq_thread+0x1bc/0x274) from [<c003c324>] (kthread+0x8c/0x98)
[ 65.470000] [<c003c324>] (kthread+0x8c/0x98) from [<c00101ac>] (kernel_thread_exit+0x0/0x8)
Reported-by: Attila Kinali <attila@kinali.ch>
Signed-off-by: Lauri Hintsala <lauri.hintsala@bluegiga.com>
Acked-by: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Chris Ball <cjb@laptop.org>
[bwh: Backported to 3.2:
- Adjust context
- HW_SSP_STATUS is a simple rather than function-like macro]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Cc: Qiang Huang <h.huangqiang@huawei.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/host/mxs-mmc.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index b6def202bf4..13ce63b38a9 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c @@ -639,10 +639,6 @@ static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) host->base + HW_SSP_CTRL0 + MXS_SET_ADDR); writel(BM_SSP_CTRL1_SDIO_IRQ_EN, host->base + HW_SSP_CTRL1 + MXS_SET_ADDR); - - if (readl(host->base + HW_SSP_STATUS) & BM_SSP_STATUS_SDIO_IRQ) - mmc_signal_sdio_irq(host->mmc); - } else { writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK, host->base + HW_SSP_CTRL0 + MXS_CLR_ADDR); @@ -651,6 +647,10 @@ static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) } spin_unlock_irqrestore(&host->lock, flags); + + if (enable && readl(host->base + HW_SSP_STATUS) & BM_SSP_STATUS_SDIO_IRQ) + mmc_signal_sdio_irq(host->mmc); + } static const struct mmc_host_ops mxs_mmc_ops = { |