mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 12:58:12 -04:00
mmc: core: Fix clk scaling deadlock with irqsave
Consider the following dump stack : do_raw_spin_lock+0xf0 _raw_spin_lock_irqsave+0x80 mmc_request_done+0x48 sdhci_irq+0x954 __handle_irq_event_percpu+0x9c handle_irq_event+0x60 handle_fasteoi_irq+0x140 __handle_domain_irq+0xc0 gic_handle_irq+0xcc el1_irq+0x108 ktime_get+0xc0 mmc_cqe_clk_scaling_stop_busy+0x58 mmc_blk_cqe_complete_rq+0x138 mmc_blk_mq_complete+0x24 blk_done_softirq+0xe0 Here mmc_cqe_clk_scaling_stop_busy is being called from the soft irq context and it acquires the clock_scaling lock. Before it could unlock, a H/W irq gets triggered on the same core which switches the context and starts execution but since lock is already held in the softirq context, irq context ends up waiting for the same lock, leading to a deadlock. Use spin_lock_irqsave to avoid above explained deadlock. Change-Id: I7684f4e349648414038cd6601cca58ac11b9409b Signed-off-by: Sarthak Garg <sartgarg@codeaurora.org> Signed-off-by: Ram Prakash Gupta <rampraka@codeaurora.org>
This commit is contained in:
parent
5b47848843
commit
9c6d556e10
1 changed files with 3 additions and 6 deletions
|
|
@ -217,18 +217,15 @@ void mmc_cqe_clk_scaling_stop_busy(struct mmc_host *host,
|
|||
bool lock_needed, bool is_cqe_dcmd)
|
||||
{
|
||||
unsigned int cqe_active_reqs = 0;
|
||||
unsigned long flags;
|
||||
|
||||
if (!host->clk_scaling.enable)
|
||||
return;
|
||||
|
||||
cqe_active_reqs = atomic_read(&host->active_reqs);
|
||||
|
||||
/*
|
||||
* This gets invoked from CQE completion path which is hard IRQ context
|
||||
* So use spin_lock() instread of spin_lock_irqsave()
|
||||
*/
|
||||
if (lock_needed)
|
||||
spin_lock(&host->clk_scaling.lock);
|
||||
spin_lock_irqsave(&host->clk_scaling.lock, flags);
|
||||
|
||||
/*
|
||||
* For CQ mode: In completion of DCMD request, start busy time in
|
||||
|
|
@ -254,7 +251,7 @@ void mmc_cqe_clk_scaling_stop_busy(struct mmc_host *host,
|
|||
}
|
||||
out:
|
||||
if (lock_needed)
|
||||
spin_unlock(&host->clk_scaling.lock);
|
||||
spin_unlock_irqrestore(&host->clk_scaling.lock, flags);
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(mmc_cqe_clk_scaling_stop_busy);
|
||||
|
|
|
|||
Loading…
Reference in a new issue