lkml.org 
[lkml]   [2018]   [Apr]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL for 4.9 186/293] arcnet: change irq handler to lock irqsave
    Date
    From: Michael Grzeschik <m.grzeschik@pengutronix.de>

    [ Upstream commit 5b85840320151f61e04d83a23ef2567a07094503 ]

    This patch prevents the arcnet driver from the following deadlock.

    [ 41.273910] ======================================================
    [ 41.280397] [ INFO: SOFTIRQ-safe -> SOFTIRQ-unsafe lock order detected ]
    [ 41.287433] 4.4.0-00034-gc0ae784 #536 Not tainted
    [ 41.292366] ------------------------------------------------------
    [ 41.298863] arcecho/233 [HC0[0]:SC0[2]:HE0:SE0] is trying to acquire:
    [ 41.305628] (&(&lp->lock)->rlock){+.+...}, at: [<bf083bc8>] arcnet_send_packet+0x60/0x1c0 [arcnet]
    [ 41.315199]
    [ 41.315199] and this task is already holding:
    [ 41.321324] (_xmit_ARCNET#2){+.-...}, at: [<c06b934c>] packet_direct_xmit+0xfc/0x1c8
    [ 41.329593] which would create a new lock dependency:
    [ 41.334893] (_xmit_ARCNET#2){+.-...} -> (&(&lp->lock)->rlock){+.+...}
    [ 41.341801]
    [ 41.341801] but this new dependency connects a SOFTIRQ-irq-safe lock:
    [ 41.350108] (_xmit_ARCNET#2){+.-...}
    ... which became SOFTIRQ-irq-safe at:
    [ 41.357539] [<c06f8fc8>] _raw_spin_lock+0x30/0x40
    [ 41.362677] [<c063ab8c>] dev_watchdog+0x5c/0x264
    [ 41.367723] [<c0094edc>] call_timer_fn+0x6c/0xf4
    [ 41.372759] [<c00950b8>] run_timer_softirq+0x154/0x210
    [ 41.378340] [<c0036b30>] __do_softirq+0x144/0x298
    [ 41.383469] [<c0036fb4>] irq_exit+0xcc/0x130
    [ 41.388138] [<c0085c50>] __handle_domain_irq+0x60/0xb4
    [ 41.393728] [<c0014578>] __irq_svc+0x58/0x78
    [ 41.398402] [<c0010274>] arch_cpu_idle+0x24/0x3c
    [ 41.403443] [<c007127c>] cpu_startup_entry+0x1f8/0x25c
    [ 41.409029] [<c09adc90>] start_kernel+0x3c0/0x3cc
    [ 41.414170]
    [ 41.414170] to a SOFTIRQ-irq-unsafe lock:
    [ 41.419931] (&(&lp->lock)->rlock){+.+...}
    ... which became SOFTIRQ-irq-unsafe at:
    [ 41.427996] ... [<c06f8fc8>] _raw_spin_lock+0x30/0x40
    [ 41.433409] [<bf083d54>] arcnet_interrupt+0x2c/0x800 [arcnet]
    [ 41.439646] [<c0089120>] handle_nested_irq+0x8c/0xec
    [ 41.445063] [<c03c1170>] regmap_irq_thread+0x190/0x314
    [ 41.450661] [<c0087244>] irq_thread_fn+0x1c/0x34
    [ 41.455700] [<c0087548>] irq_thread+0x13c/0x1dc
    [ 41.460649] [<c0050f10>] kthread+0xe4/0xf8
    [ 41.465158] [<c000f810>] ret_from_fork+0x14/0x24
    [ 41.470207]
    [ 41.470207] other info that might help us debug this:
    [ 41.470207]
    [ 41.478627] Possible interrupt unsafe locking scenario:
    [ 41.478627]
    [ 41.485763] CPU0 CPU1
    [ 41.490521] ---- ----
    [ 41.495279] lock(&(&lp->lock)->rlock);
    [ 41.499414] local_irq_disable();
    [ 41.505636] lock(_xmit_ARCNET#2);
    [ 41.511967] lock(&(&lp->lock)->rlock);
    [ 41.518741] <Interrupt>
    [ 41.521490] lock(_xmit_ARCNET#2);
    [ 41.525356]
    [ 41.525356] *** DEADLOCK ***
    [ 41.525356]
    [ 41.531587] 1 lock held by arcecho/233:
    [ 41.535617] #0: (_xmit_ARCNET#2){+.-...}, at: [<c06b934c>] packet_direct_xmit+0xfc/0x1c8
    [ 41.544355]
    the dependencies between SOFTIRQ-irq-safe lock and the holding lock:
    [ 41.552362] -> (_xmit_ARCNET#2){+.-...} ops: 27 {
    [ 41.557357] HARDIRQ-ON-W at:
    [ 41.560664] [<c06f8fc8>] _raw_spin_lock+0x30/0x40
    [ 41.567445] [<c063ba28>] dev_deactivate_many+0x114/0x304
    [ 41.574866] [<c063bc3c>] dev_deactivate+0x24/0x38
    [ 41.581646] [<c0630374>] linkwatch_do_dev+0x40/0x74
    [ 41.588613] [<c06305d8>] __linkwatch_run_queue+0xec/0x140
    [ 41.596120] [<c0630658>] linkwatch_event+0x2c/0x34
    [ 41.602991] [<c004af30>] process_one_work+0x188/0x40c
    [ 41.610131] [<c004b200>] worker_thread+0x4c/0x480
    [ 41.616912] [<c0050f10>] kthread+0xe4/0xf8
    [ 41.623048] [<c000f810>] ret_from_fork+0x14/0x24
    [ 41.629735] IN-SOFTIRQ-W at:
    [ 41.633039] [<c06f8fc8>] _raw_spin_lock+0x30/0x40
    [ 41.639820] [<c063ab8c>] dev_watchdog+0x5c/0x264
    [ 41.646508] [<c0094edc>] call_timer_fn+0x6c/0xf4
    [ 41.653190] [<c00950b8>] run_timer_softirq+0x154/0x210
    [ 41.660425] [<c0036b30>] __do_softirq+0x144/0x298
    [ 41.667201] [<c0036fb4>] irq_exit+0xcc/0x130
    [ 41.673518] [<c0085c50>] __handle_domain_irq+0x60/0xb4
    [ 41.680754] [<c0014578>] __irq_svc+0x58/0x78
    [ 41.687077] [<c0010274>] arch_cpu_idle+0x24/0x3c
    [ 41.693769] [<c007127c>] cpu_startup_entry+0x1f8/0x25c
    [ 41.701006] [<c09adc90>] start_kernel+0x3c0/0x3cc
    [ 41.707791] INITIAL USE at:
    [ 41.711003] [<c06f8fc8>] _raw_spin_lock+0x30/0x40
    [ 41.717696] [<c063ba28>] dev_deactivate_many+0x114/0x304
    [ 41.725026] [<c063bc3c>] dev_deactivate+0x24/0x38
    [ 41.731718] [<c0630374>] linkwatch_do_dev+0x40/0x74
    [ 41.738593] [<c06305d8>] __linkwatch_run_queue+0xec/0x140
    [ 41.746011] [<c0630658>] linkwatch_event+0x2c/0x34
    [ 41.752789] [<c004af30>] process_one_work+0x188/0x40c
    [ 41.759847] [<c004b200>] worker_thread+0x4c/0x480
    [ 41.766541] [<c0050f10>] kthread+0xe4/0xf8
    [ 41.772596] [<c000f810>] ret_from_fork+0x14/0x24
    [ 41.779198] }
    [ 41.780945] ... key at: [<c124d620>] netdev_xmit_lock_key+0x38/0x1c8
    [ 41.788192] ... acquired at:
    [ 41.791309] [<c007bed8>] lock_acquire+0x70/0x90
    [ 41.796361] [<c06f9140>] _raw_spin_lock_irqsave+0x40/0x54
    [ 41.802324] [<bf083bc8>] arcnet_send_packet+0x60/0x1c0 [arcnet]
    [ 41.808844] [<c06b9380>] packet_direct_xmit+0x130/0x1c8
    [ 41.814622] [<c06bc7e4>] packet_sendmsg+0x3b8/0x680
    [ 41.820034] [<c05fe8b0>] sock_sendmsg+0x14/0x24
    [ 41.825091] [<c05ffd68>] SyS_sendto+0xb8/0xe0
    [ 41.829956] [<c05ffda8>] SyS_send+0x18/0x20
    [ 41.834638] [<c000f780>] ret_fast_syscall+0x0/0x1c
    [ 41.839954]
    [ 41.841514]
    the dependencies between the lock to be acquired and SOFTIRQ-irq-unsafe lock:
    [ 41.850302] -> (&(&lp->lock)->rlock){+.+...} ops: 5 {
    [ 41.855644] HARDIRQ-ON-W at:
    [ 41.858945] [<c06f8fc8>] _raw_spin_lock+0x30/0x40
    [ 41.865726] [<bf083d54>] arcnet_interrupt+0x2c/0x800 [arcnet]
    [ 41.873607] [<c0089120>] handle_nested_irq+0x8c/0xec
    [ 41.880666] [<c03c1170>] regmap_irq_thread+0x190/0x314
    [ 41.887901] [<c0087244>] irq_thread_fn+0x1c/0x34
    [ 41.894593] [<c0087548>] irq_thread+0x13c/0x1dc
    [ 41.901195] [<c0050f10>] kthread+0xe4/0xf8
    [ 41.907338] [<c000f810>] ret_from_fork+0x14/0x24
    [ 41.914025] SOFTIRQ-ON-W at:
    [ 41.917328] [<c06f8fc8>] _raw_spin_lock+0x30/0x40
    [ 41.924106] [<bf083d54>] arcnet_interrupt+0x2c/0x800 [arcnet]
    [ 41.931981] [<c0089120>] handle_nested_irq+0x8c/0xec
    [ 41.939028] [<c03c1170>] regmap_irq_thread+0x190/0x314
    [ 41.946264] [<c0087244>] irq_thread_fn+0x1c/0x34
    [ 41.952954] [<c0087548>] irq_thread+0x13c/0x1dc
    [ 41.959548] [<c0050f10>] kthread+0xe4/0xf8
    [ 41.965689] [<c000f810>] ret_from_fork+0x14/0x24
    [ 41.972379] INITIAL USE at:
    [ 41.975595] [<c06f8fc8>] _raw_spin_lock+0x30/0x40
    [ 41.982283] [<bf083d54>] arcnet_interrupt+0x2c/0x800 [arcnet]
    [ 41.990063] [<c0089120>] handle_nested_irq+0x8c/0xec
    [ 41.997027] [<c03c1170>] regmap_irq_thread+0x190/0x314
    [ 42.004172] [<c0087244>] irq_thread_fn+0x1c/0x34
    [ 42.010766] [<c0087548>] irq_thread+0x13c/0x1dc
    [ 42.017267] [<c0050f10>] kthread+0xe4/0xf8
    [ 42.023314] [<c000f810>] ret_from_fork+0x14/0x24
    [ 42.029903] }
    [ 42.031648] ... key at: [<bf0854cc>] __key.42091+0x0/0xfffff0f8 [arcnet]
    [ 42.039255] ... acquired at:
    [ 42.042372] [<c007bed8>] lock_acquire+0x70/0x90
    [ 42.047413] [<c06f9140>] _raw_spin_lock_irqsave+0x40/0x54
    [ 42.053364] [<bf083bc8>] arcnet_send_packet+0x60/0x1c0 [arcnet]
    [ 42.059872] [<c06b9380>] packet_direct_xmit+0x130/0x1c8
    [ 42.065634] [<c06bc7e4>] packet_sendmsg+0x3b8/0x680
    [ 42.071030] [<c05fe8b0>] sock_sendmsg+0x14/0x24
    [ 42.076069] [<c05ffd68>] SyS_sendto+0xb8/0xe0
    [ 42.080926] [<c05ffda8>] SyS_send+0x18/0x20
    [ 42.085601] [<c000f780>] ret_fast_syscall+0x0/0x1c
    [ 42.090918]
    [ 42.092481]
    [ 42.092481] stack backtrace:
    [ 42.097065] CPU: 0 PID: 233 Comm: arcecho Not tainted 4.4.0-00034-gc0ae784 #536
    [ 42.104751] Hardware name: Generic AM33XX (Flattened Device Tree)
    [ 42.111183] [<c0017ec8>] (unwind_backtrace) from [<c00139d0>] (show_stack+0x10/0x14)
    [ 42.119337] [<c00139d0>] (show_stack) from [<c02a82c4>] (dump_stack+0x8c/0x9c)
    [ 42.126937] [<c02a82c4>] (dump_stack) from [<c0078260>] (check_usage+0x4bc/0x63c)
    [ 42.134815] [<c0078260>] (check_usage) from [<c0078438>] (check_irq_usage+0x58/0xb0)
    [ 42.142964] [<c0078438>] (check_irq_usage) from [<c007aaa0>] (__lock_acquire+0x1524/0x20b0)
    [ 42.151740] [<c007aaa0>] (__lock_acquire) from [<c007bed8>] (lock_acquire+0x70/0x90)
    [ 42.159886] [<c007bed8>] (lock_acquire) from [<c06f9140>] (_raw_spin_lock_irqsave+0x40/0x54)
    [ 42.168768] [<c06f9140>] (_raw_spin_lock_irqsave) from [<bf083bc8>] (arcnet_send_packet+0x60/0x1c0 [arcnet])
    [ 42.179115] [<bf083bc8>] (arcnet_send_packet [arcnet]) from [<c06b9380>] (packet_direct_xmit+0x130/0x1c8)
    [ 42.189182] [<c06b9380>] (packet_direct_xmit) from [<c06bc7e4>] (packet_sendmsg+0x3b8/0x680)
    [ 42.198059] [<c06bc7e4>] (packet_sendmsg) from [<c05fe8b0>] (sock_sendmsg+0x14/0x24)
    [ 42.206199] [<c05fe8b0>] (sock_sendmsg) from [<c05ffd68>] (SyS_sendto+0xb8/0xe0)
    [ 42.213978] [<c05ffd68>] (SyS_sendto) from [<c05ffda8>] (SyS_send+0x18/0x20)
    [ 42.221388] [<c05ffda8>] (SyS_send) from [<c000f780>] (ret_fast_syscall+0x0/0x1c)

    Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>

    ---
    v1 -> v2: removed unneeded zero assignment of flags
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
    ---
    drivers/net/arcnet/arcnet.c | 7 ++++---
    1 file changed, 4 insertions(+), 3 deletions(-)

    diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
    index 6ea963e3b89a..915d55337e4c 100644
    --- a/drivers/net/arcnet/arcnet.c
    +++ b/drivers/net/arcnet/arcnet.c
    @@ -756,6 +756,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
    struct net_device *dev = dev_id;
    struct arcnet_local *lp;
    int recbuf, status, diagstatus, didsomething, boguscount;
    + unsigned long flags;
    int retval = IRQ_NONE;

    arc_printk(D_DURING, dev, "\n");
    @@ -765,7 +766,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
    lp = netdev_priv(dev);
    BUG_ON(!lp);

    - spin_lock(&lp->lock);
    + spin_lock_irqsave(&lp->lock, flags);

    /* RESET flag was enabled - if device is not running, we must
    * clear it right away (but nothing else).
    @@ -774,7 +775,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
    if (lp->hw.status(dev) & RESETflag)
    lp->hw.command(dev, CFLAGScmd | RESETclear);
    lp->hw.intmask(dev, 0);
    - spin_unlock(&lp->lock);
    + spin_unlock_irqrestore(&lp->lock, flags);
    return retval;
    }

    @@ -998,7 +999,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
    udelay(1);
    lp->hw.intmask(dev, lp->intmask);

    - spin_unlock(&lp->lock);
    + spin_unlock_irqrestore(&lp->lock, flags);
    return retval;
    }
    EXPORT_SYMBOL(arcnet_interrupt);
    --
    2.15.1
    \
     
     \ /
      Last update: 2018-04-09 04:05    [W:4.413 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site