• G
    dmaengine: rcar-dmac: Disable interrupts while stopping channels · 45c9a603
    Geert Uytterhoeven 提交于
    During system reboot or halt, with lockdep enabled:
    
        ================================
        WARNING: inconsistent lock state
        4.18.0-rc1-salvator-x-00002-g9203dbec #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-g9203dbec #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: 9203dbec ("dmaengine: rcar-dmac: don't use DMAC error interrupt")
    Signed-off-by: NGeert Uytterhoeven <geert+renesas@glider.be>
    Signed-off-by: NVinod Koul <vkoul@kernel.org>
    45c9a603
rcar-dmac.c 51.4 KB