Skip to content

Commit ef69d63

Browse files
committed
dmaengine: rcar-dmac: Fix inconsistent lock reported by PROVE_LOCKING
rcar_dmac_sleep_suspend uses the spin_lock/spin_unlock functions to acquire lock by commit 9d867d5 ("dmaengine: rcar-dmac: Support S2RAM"), the same lock is also acquired in rcar_dmac_isr_channel of the interrupt handler. But, rcar_dmac_sleep_suspend is called with the interrupt enabled from the suspend callback of the power manager interface, If an interrupt occurs while suspend is acquiring a lock, it may cause a deadlock. ================================= [ INFO: inconsistent lock state ] 4.9.0-yocto-standard #1 Not tainted --------------------------------- inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage. sh/2967 [HC0[0]:SC0[0]:HE1:SE1] takes: (&(&rchan->lock)->rlock){?.....}, at: [<ffff0000084cf1c0>] rcar_dmac_sleep_suspend+0x50/0x120 state was registered at: [<ffff000008109014>] mark_lock+0x1c4/0x6c8 [<ffff00000810a638>] __lock_acquire+0xba0/0x1728 [<ffff00000810b51c>] lock_acquire+0x4c/0x68 [<ffff0000089e67e8>] _raw_spin_lock+0x40/0x58 [<ffff0000084cf530>] rcar_dmac_isr_channel+0x20/0x1e8 [<ffff000008115e74>] __handle_irq_event_percpu+0x9c/0x128 [<ffff000008115f1c>] handle_irq_event_percpu+0x1c/0x58 [<ffff000008115fa0>] handle_irq_event+0x48/0x78 [<ffff0000081198d8>] handle_fasteoi_irq+0xb8/0x1b0 [<ffff000008114f14>] generic_handle_irq+0x24/0x38 [<ffff0000081155dc>] __handle_domain_irq+0x5c/0xb8 [<ffff000008081588>] gic_handle_irq+0x58/0xb0 [<ffff0000080827b4>] el1_irq+0xb4/0x12c [<ffff00000882b5f0>] cpuidle_enter_state+0x158/0x228 [<ffff00000882b6f8>] cpuidle_enter+0x18/0x20 [<ffff000008102948>] call_cpuidle+0x18/0x38 [<ffff000008102b84>] cpu_startup_entry+0x13c/0x1e0 [<ffff0000089dfea0>] rest_init+0x148/0x158 [<ffff000008e50b54>] start_kernel+0x38c/0x3a0 [<ffff000008e501d8>] __primary_switched+0x5c/0x64 irq event stamp: 41905 hardirqs last enabled at (41905): [<ffff0000089e2fac>] mutex_lock_nested+0x2ec/0x390 hardirqs last disabled at (41904): [<ffff0000089e2d38>] mutex_lock_nested+0x78/0x390 softirqs last enabled at (41496): [<ffff0000080c41c0>] __do_softirq+0x218/0x288 softirqs last disabled at (41489): [<ffff0000080c4594>] irq_exit+0xbc/0xf0 other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(&(&rchan->lock)->rlock); <Interrupt> lock(&(&rchan->lock)->rlock); *** DEADLOCK *** 5 locks held by sh/2967: #0: (sb_writers#4){.+.+.+}, at: [<ffff000008204400>] vfs_write+0x168/0x1b8 #1: (&of->mutex){+.+.+.}, at: [<ffff000008287600>] kernfs_fop_write+0x88/0x1e8 #2: (s_active#88){.+.+.+}, at: [<ffff000008287608>] kernfs_fop_write+0x90/0x1e8 xen-troops#3: (pm_mutex){+.+.+.}, at: [<ffff000008110e34>] pm_suspend+0x54/0x268 xen-troops#4: (&dev->mutex){......}, at: [<ffff0000085d8e84>] __device_suspend+0xcc/0x298 stack backtrace: CPU: 3 PID: 2967 Comm: sh Not tainted 4.9.0-yocto-standard-00002-g658096e81b08 #1 Hardware name: Renesas Salvator-X 2nd version board based on r8a7795 es2.0 (DT) Call trace: [<ffff000008088938>] dump_backtrace+0x0/0x1a8 [<ffff000008088af4>] show_stack+0x14/0x20 [<ffff0000083bc54c>] dump_stack+0xb4/0xf0 [<ffff000008187538>] print_usage_bug.part.24+0x264/0x27c [<ffff000008108fa0>] mark_lock+0x150/0x6c8 [<ffff00000810a100>] __lock_acquire+0x668/0x1728 [<ffff00000810b51c>] lock_acquire+0x4c/0x68 [<ffff0000089e67e8>] _raw_spin_lock+0x40/0x58 [<ffff0000084cf1c0>] rcar_dmac_sleep_suspend+0x50/0x120 [<ffff0000085d8440>] dpm_run_callback.isra.7+0x20/0x68 [<ffff0000085d8ec8>] __device_suspend+0x110/0x298 [<ffff0000085da13c>] dpm_suspend+0x114/0x248 [<ffff0000085da568>] dpm_suspend_start+0x70/0x80 [<ffff000008110a28>] suspend_devices_and_enter+0xb8/0x470 [<ffff000008110fd4>] pm_suspend+0x1f4/0x268 [<ffff00000810fbe0>] state_store+0x80/0x100 [<ffff0000083bec0c>] kobj_attr_store+0x14/0x28 [<ffff0000082884e0>] sysfs_kf_write+0x60/0x70 [<ffff000008287630>] kernfs_fop_write+0xb8/0x1e8 [<ffff000008203524>] __vfs_write+0x1c/0x110 [<ffff000008204338>] vfs_write+0xa0/0x1b8 [<ffff00000820572c>] SyS_write+0x44/0xa0 [<ffff000008082f4c>] __sys_trace_return+0x0/0x4 This patch replaces spin_lock/spin_unlock with spin_lock_irqsave/spin_unlock_irqrestore. Fixes: 9d867d5 ("dmaengine: rcar-dmac: Support S2RAM") Signed-off-by: Takeshi Kihara <[email protected]>
1 parent 2600be6 commit ef69d63

File tree

1 file changed

+3
-2
lines changed

1 file changed

+3
-2
lines changed

drivers/dma/sh/rcar-dmac.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1604,14 +1604,15 @@ static struct dma_chan *rcar_dmac_of_xlate(struct of_phandle_args *dma_spec,
16041604
static int rcar_dmac_sleep_suspend(struct device *dev)
16051605
{
16061606
struct rcar_dmac *dmac = dev_get_drvdata(dev);
1607+
unsigned long flags;
16071608
int i;
16081609

16091610
for (i = 0; i < dmac->n_channels; ++i) {
16101611
if (!dmac->channels[i].iomem)
16111612
continue;
16121613

16131614
pm_runtime_get_sync(dev);
1614-
spin_lock(&dmac->channels[i].lock);
1615+
spin_lock_irqsave(&dmac->channels[i].lock, flags);
16151616

16161617
if (rcar_dmac_chan_is_busy(&dmac->channels[i])) {
16171618
pm_runtime_put(dev);
@@ -1620,7 +1621,7 @@ static int rcar_dmac_sleep_suspend(struct device *dev)
16201621
}
16211622

16221623
rcar_dmac_chan_halt(&dmac->channels[i]);
1623-
spin_unlock(&dmac->channels[i].lock);
1624+
spin_unlock_irqrestore(&dmac->channels[i].lock, flags);
16241625
pm_runtime_put(dev);
16251626
}
16261627

0 commit comments

Comments
 (0)