Patch "net: enetc: avoid deadlock in enetc_tx_onestep_tstamp()" has been added to the 6.1-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    net: enetc: avoid deadlock in enetc_tx_onestep_tstamp()

to the 6.1-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     net-enetc-avoid-deadlock-in-enetc_tx_onestep_tstamp.patch
and it can be found in the queue-6.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit ceff3aa1409f30233f976b1fd4b9c788b0b68b76
Author: Vladimir Oltean <vladimir.oltean@xxxxxxx>
Date:   Thu Jan 12 12:54:40 2023 +0200

    net: enetc: avoid deadlock in enetc_tx_onestep_tstamp()
    
    [ Upstream commit 3c463721a73bdb57a913e0d3124677a3758886fc ]
    
    This lockdep splat says it better than I could:
    
    ================================
    WARNING: inconsistent lock state
    6.2.0-rc2-07010-ga9b9500ffaac-dirty #967 Not tainted
    --------------------------------
    inconsistent {IN-SOFTIRQ-W} -> {SOFTIRQ-ON-W} usage.
    kworker/1:3/179 [HC0[0]:SC0[0]:HE1:SE1] takes:
    ffff3ec4036ce098 (_xmit_ETHER#2){+.?.}-{3:3}, at: netif_freeze_queues+0x5c/0xc0
    {IN-SOFTIRQ-W} state was registered at:
      _raw_spin_lock+0x5c/0xc0
      sch_direct_xmit+0x148/0x37c
      __dev_queue_xmit+0x528/0x111c
      ip6_finish_output2+0x5ec/0xb7c
      ip6_finish_output+0x240/0x3f0
      ip6_output+0x78/0x360
      ndisc_send_skb+0x33c/0x85c
      ndisc_send_rs+0x54/0x12c
      addrconf_rs_timer+0x154/0x260
      call_timer_fn+0xb8/0x3a0
      __run_timers.part.0+0x214/0x26c
      run_timer_softirq+0x3c/0x74
      __do_softirq+0x14c/0x5d8
      ____do_softirq+0x10/0x20
      call_on_irq_stack+0x2c/0x5c
      do_softirq_own_stack+0x1c/0x30
      __irq_exit_rcu+0x168/0x1a0
      irq_exit_rcu+0x10/0x40
      el1_interrupt+0x38/0x64
    irq event stamp: 7825
    hardirqs last  enabled at (7825): [<ffffdf1f7200cae4>] exit_to_kernel_mode+0x34/0x130
    hardirqs last disabled at (7823): [<ffffdf1f708105f0>] __do_softirq+0x550/0x5d8
    softirqs last  enabled at (7824): [<ffffdf1f7081050c>] __do_softirq+0x46c/0x5d8
    softirqs last disabled at (7811): [<ffffdf1f708166e0>] ____do_softirq+0x10/0x20
    
    other info that might help us debug this:
     Possible unsafe locking scenario:
    
           CPU0
           ----
      lock(_xmit_ETHER#2);
      <Interrupt>
        lock(_xmit_ETHER#2);
    
     *** DEADLOCK ***
    
    3 locks held by kworker/1:3/179:
     #0: ffff3ec400004748 ((wq_completion)events){+.+.}-{0:0}, at: process_one_work+0x1f4/0x6c0
     #1: ffff80000a0bbdc8 ((work_completion)(&priv->tx_onestep_tstamp)){+.+.}-{0:0}, at: process_one_work+0x1f4/0x6c0
     #2: ffff3ec4036cd438 (&dev->tx_global_lock){+.+.}-{3:3}, at: netif_tx_lock+0x1c/0x34
    
    Workqueue: events enetc_tx_onestep_tstamp
    Call trace:
     print_usage_bug.part.0+0x208/0x22c
     mark_lock+0x7f0/0x8b0
     __lock_acquire+0x7c4/0x1ce0
     lock_acquire.part.0+0xe0/0x220
     lock_acquire+0x68/0x84
     _raw_spin_lock+0x5c/0xc0
     netif_freeze_queues+0x5c/0xc0
     netif_tx_lock+0x24/0x34
     enetc_tx_onestep_tstamp+0x20/0x100
     process_one_work+0x28c/0x6c0
     worker_thread+0x74/0x450
     kthread+0x118/0x11c
    
    but I'll say it anyway: the enetc_tx_onestep_tstamp() work item runs in
    process context, therefore with softirqs enabled (i.o.w., it can be
    interrupted by a softirq). If we hold the netif_tx_lock() when there is
    an interrupt, and the NET_TX softirq then gets scheduled, this will take
    the netif_tx_lock() a second time and deadlock the kernel.
    
    To solve this, use netif_tx_lock_bh(), which blocks softirqs from
    running.
    
    Fixes: 7294380c5211 ("enetc: support PTP Sync packet one-step timestamping")
    Signed-off-by: Vladimir Oltean <vladimir.oltean@xxxxxxx>
    Reviewed-by: Alexander Duyck <alexanderduyck@xxxxxx>
    Link: https://lore.kernel.org/r/20230112105440.1786799-1-vladimir.oltean@xxxxxxx
    Signed-off-by: Jakub Kicinski <kuba@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
index 3a79ead5219a..e96449eedfb5 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc.c
@@ -2290,14 +2290,14 @@ static void enetc_tx_onestep_tstamp(struct work_struct *work)
 
 	priv = container_of(work, struct enetc_ndev_priv, tx_onestep_tstamp);
 
-	netif_tx_lock(priv->ndev);
+	netif_tx_lock_bh(priv->ndev);
 
 	clear_bit_unlock(ENETC_TX_ONESTEP_TSTAMP_IN_PROGRESS, &priv->flags);
 	skb = skb_dequeue(&priv->tx_skbs);
 	if (skb)
 		enetc_start_xmit(skb, priv->ndev);
 
-	netif_tx_unlock(priv->ndev);
+	netif_tx_unlock_bh(priv->ndev);
 }
 
 static void enetc_tx_onestep_tstamp_init(struct enetc_ndev_priv *priv)



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux