DMA Engine development
 help / color / mirror / Atom feed
* dmaengine: rcar-dmac: Disable interrupts while stopping channels
@ 2018-07-09 16:51 Vinod Koul
  0 siblings, 0 replies; 2+ messages in thread
From: Vinod Koul @ 2018-07-09 16:51 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Dan Williams, Kuninori Morimoto, Yoshihiro Shimoda, dmaengine,
	linux-renesas-soc

On 02-07-18, 17:02, Geert Uytterhoeven wrote:
> During system reboot or halt, with lockdep enabled:
> 
>     ================================
>     WARNING: inconsistent lock state
>     4.18.0-rc1-salvator-x-00002-g9203dbec90a68103 #41 Tainted: G        W
>     --------------------------------
>     inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage.
>     reboot/2779 [HC0[0]:SC0[0]:HE1:SE1] takes:
>     0000000098ae4ad3 (&(&rchan->lock)->rlock){?.-.}, at: rcar_dmac_shutdown+0x58/0x6c
>     {IN-HARDIRQ-W} state was registered at:
>       lock_acquire+0x208/0x238
>       _raw_spin_lock+0x40/0x54
>       rcar_dmac_isr_channel+0x28/0x200
>       __handle_irq_event_percpu+0x1c0/0x3c8
>       handle_irq_event_percpu+0x34/0x88
>       handle_irq_event+0x48/0x78
>       handle_fasteoi_irq+0xc4/0x12c
>       generic_handle_irq+0x18/0x2c
>       __handle_domain_irq+0xa8/0xac
>       gic_handle_irq+0x78/0xbc
>       el1_irq+0xec/0x1c0
>       arch_cpu_idle+0xe8/0x1bc
>       default_idle_call+0x2c/0x30
>       do_idle+0x144/0x234
>       cpu_startup_entry+0x20/0x24
>       rest_init+0x27c/0x290
>       start_kernel+0x430/0x45c
>     irq event stamp: 12177
>     hardirqs last  enabled at (12177): [<ffffff800881d804>] _raw_spin_unlock_irq+0x2c/0x4c
>     hardirqs last disabled at (12176): [<ffffff800881d638>] _raw_spin_lock_irq+0x1c/0x60
>     softirqs last  enabled at (11948): [<ffffff8008081da8>] __do_softirq+0x160/0x4ec
>     softirqs last disabled at (11935): [<ffffff80080ec948>] irq_exit+0xa0/0xfc
> 
>     other info that might help us debug this:
>      Possible unsafe locking scenario:
> 
> 	   CPU0
> 	   ----
>       lock(&(&rchan->lock)->rlock);
>       <Interrupt>
> 	lock(&(&rchan->lock)->rlock);
> 
>      *** DEADLOCK ***
> 
>     3 locks held by reboot/2779:
>      #0: 00000000bfabfa74 (reboot_mutex){+.+.}, at: sys_reboot+0xdc/0x208
>      #1: 00000000c75d8c3a (&dev->mutex){....}, at: device_shutdown+0xc8/0x1c4
>      #2: 00000000ebec58ec (&dev->mutex){....}, at: device_shutdown+0xd8/0x1c4
> 
>     stack backtrace:
>     CPU: 6 PID: 2779 Comm: reboot Tainted: G        W         4.18.0-rc1-salvator-x-00002-g9203dbec90a68103 #41
>     Hardware name: Renesas Salvator-X 2nd version board based on r8a7795 ES2.0+ (DT)
>     Call trace:
>      dump_backtrace+0x0/0x148
>      show_stack+0x14/0x1c
>      dump_stack+0xb0/0xf0
>      print_usage_bug.part.26+0x1c4/0x27c
>      mark_lock+0x38c/0x610
>      __lock_acquire+0x3fc/0x14d4
>      lock_acquire+0x208/0x238
>      _raw_spin_lock+0x40/0x54
>      rcar_dmac_shutdown+0x58/0x6c
>      platform_drv_shutdown+0x20/0x2c
>      device_shutdown+0x160/0x1c4
>      kernel_restart_prepare+0x34/0x3c
>      kernel_restart+0x14/0x5c
>      sys_reboot+0x160/0x208
>      el0_svc_naked+0x30/0x34
> 
> rcar_dmac_stop_all_chan() takes the channel lock while stopping a
> channel, but does not disable interrupts, leading to a deadlock when a
> DMAC interrupt comes in.  Before, the same code block was called from an
> interrupt handler, hence taking the spinlock was sufficient.
> 
> Fix this by disabling local interrupts while taking the spinlock.

Applied, thanks

^ permalink raw reply	[flat|nested] 2+ messages in thread
* dmaengine: rcar-dmac: Disable interrupts while stopping channels
@ 2018-07-02 15:02 Geert Uytterhoeven
  0 siblings, 0 replies; 2+ messages in thread
From: Geert Uytterhoeven @ 2018-07-02 15:02 UTC (permalink / raw)
  To: Vinod Koul, Dan Williams, Kuninori Morimoto, Yoshihiro Shimoda
  Cc: dmaengine, linux-renesas-soc, Geert Uytterhoeven

During system reboot or halt, with lockdep enabled:

    ================================
    WARNING: inconsistent lock state
    4.18.0-rc1-salvator-x-00002-g9203dbec90a68103 #41 Tainted: G        W
    --------------------------------
    inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage.
    reboot/2779 [HC0[0]:SC0[0]:HE1:SE1] takes:
    0000000098ae4ad3 (&(&rchan->lock)->rlock){?.-.}, at: rcar_dmac_shutdown+0x58/0x6c
    {IN-HARDIRQ-W} state was registered at:
      lock_acquire+0x208/0x238
      _raw_spin_lock+0x40/0x54
      rcar_dmac_isr_channel+0x28/0x200
      __handle_irq_event_percpu+0x1c0/0x3c8
      handle_irq_event_percpu+0x34/0x88
      handle_irq_event+0x48/0x78
      handle_fasteoi_irq+0xc4/0x12c
      generic_handle_irq+0x18/0x2c
      __handle_domain_irq+0xa8/0xac
      gic_handle_irq+0x78/0xbc
      el1_irq+0xec/0x1c0
      arch_cpu_idle+0xe8/0x1bc
      default_idle_call+0x2c/0x30
      do_idle+0x144/0x234
      cpu_startup_entry+0x20/0x24
      rest_init+0x27c/0x290
      start_kernel+0x430/0x45c
    irq event stamp: 12177
    hardirqs last  enabled at (12177): [<ffffff800881d804>] _raw_spin_unlock_irq+0x2c/0x4c
    hardirqs last disabled at (12176): [<ffffff800881d638>] _raw_spin_lock_irq+0x1c/0x60
    softirqs last  enabled at (11948): [<ffffff8008081da8>] __do_softirq+0x160/0x4ec
    softirqs last disabled at (11935): [<ffffff80080ec948>] irq_exit+0xa0/0xfc

    other info that might help us debug this:
     Possible unsafe locking scenario:

	   CPU0
	   ----
      lock(&(&rchan->lock)->rlock);
      <Interrupt>
	lock(&(&rchan->lock)->rlock);

     *** DEADLOCK ***

    3 locks held by reboot/2779:
     #0: 00000000bfabfa74 (reboot_mutex){+.+.}, at: sys_reboot+0xdc/0x208
     #1: 00000000c75d8c3a (&dev->mutex){....}, at: device_shutdown+0xc8/0x1c4
     #2: 00000000ebec58ec (&dev->mutex){....}, at: device_shutdown+0xd8/0x1c4

    stack backtrace:
    CPU: 6 PID: 2779 Comm: reboot Tainted: G        W         4.18.0-rc1-salvator-x-00002-g9203dbec90a68103 #41
    Hardware name: Renesas Salvator-X 2nd version board based on r8a7795 ES2.0+ (DT)
    Call trace:
     dump_backtrace+0x0/0x148
     show_stack+0x14/0x1c
     dump_stack+0xb0/0xf0
     print_usage_bug.part.26+0x1c4/0x27c
     mark_lock+0x38c/0x610
     __lock_acquire+0x3fc/0x14d4
     lock_acquire+0x208/0x238
     _raw_spin_lock+0x40/0x54
     rcar_dmac_shutdown+0x58/0x6c
     platform_drv_shutdown+0x20/0x2c
     device_shutdown+0x160/0x1c4
     kernel_restart_prepare+0x34/0x3c
     kernel_restart+0x14/0x5c
     sys_reboot+0x160/0x208
     el0_svc_naked+0x30/0x34

rcar_dmac_stop_all_chan() takes the channel lock while stopping a
channel, but does not disable interrupts, leading to a deadlock when a
DMAC interrupt comes in.  Before, the same code block was called from an
interrupt handler, hence taking the spinlock was sufficient.

Fix this by disabling local interrupts while taking the spinlock.

Fixes: 9203dbec90a68103 ("dmaengine: rcar-dmac: don't use DMAC error interrupt")
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 drivers/dma/sh/rcar-dmac.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c
index 279c930c4a7635e0..4e4d183190bd0c9c 100644
--- a/drivers/dma/sh/rcar-dmac.c
+++ b/drivers/dma/sh/rcar-dmac.c
@@ -823,9 +823,9 @@ static void rcar_dmac_stop_all_chan(struct rcar_dmac *dmac)
 		struct rcar_dmac_chan *chan = &dmac->channels[i];
 
 		/* Stop and reinitialize the channel. */
-		spin_lock(&chan->lock);
+		spin_lock_irq(&chan->lock);
 		rcar_dmac_chan_halt(chan);
-		spin_unlock(&chan->lock);
+		spin_unlock_irq(&chan->lock);
 	}
 }
 

^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2018-07-09 16:51 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-07-09 16:51 dmaengine: rcar-dmac: Disable interrupts while stopping channels Vinod Koul
  -- strict thread matches above, loose matches on Subject: below --
2018-07-02 15:02 Geert Uytterhoeven

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox