Skip to content

Commit 5337824

Browse files
edumazetdavem330
authored andcommitted
net: annotate accesses to queue->trans_start
In following patches, dev_watchdog() will no longer stop all queues. It will read queue->trans_start locklessly. Signed-off-by: Eric Dumazet <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 8160fb4 commit 5337824

File tree

14 files changed

+33
-23
lines changed

14 files changed

+33
-23
lines changed

drivers/net/ethernet/apm/xgene/xgene_enet_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -869,7 +869,7 @@ static void xgene_enet_timeout(struct net_device *ndev, unsigned int txqueue)
869869

870870
for (i = 0; i < pdata->txq_cnt; i++) {
871871
txq = netdev_get_tx_queue(ndev, i);
872-
txq->trans_start = jiffies;
872+
txq_trans_cond_update(txq);
873873
netif_tx_start_queue(txq);
874874
}
875875
}

drivers/net/ethernet/atheros/ag71xx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,7 @@ static bool ag71xx_check_dma_stuck(struct ag71xx *ag)
766766
unsigned long timestamp;
767767
u32 rx_sm, tx_sm, rx_fd;
768768

769-
timestamp = netdev_get_tx_queue(ag->ndev, 0)->trans_start;
769+
timestamp = READ_ONCE(netdev_get_tx_queue(ag->ndev, 0)->trans_start);
770770
if (likely(time_before(jiffies, timestamp + HZ / 10)))
771771
return false;
772772

drivers/net/ethernet/freescale/dpaa/dpaa_eth.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2325,7 +2325,7 @@ dpaa_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
23252325
txq = netdev_get_tx_queue(net_dev, queue_mapping);
23262326

23272327
/* LLTX requires to do our own update of trans_start */
2328-
txq->trans_start = jiffies;
2328+
txq_trans_cond_update(txq);
23292329

23302330
if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) {
23312331
fd.cmd |= cpu_to_be32(FM_FD_CMD_UPD);
@@ -2531,7 +2531,7 @@ static int dpaa_xdp_xmit_frame(struct net_device *net_dev,
25312531

25322532
/* Bump the trans_start */
25332533
txq = netdev_get_tx_queue(net_dev, smp_processor_id());
2534-
txq->trans_start = jiffies;
2534+
txq_trans_cond_update(txq);
25352535

25362536
err = dpaa_xmit(priv, percpu_stats, smp_processor_id(), &fd);
25372537
if (err) {

drivers/net/ethernet/hisilicon/hns3/hns3_enet.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2679,7 +2679,7 @@ static bool hns3_get_tx_timeo_queue_info(struct net_device *ndev)
26792679
unsigned long trans_start;
26802680

26812681
q = netdev_get_tx_queue(ndev, i);
2682-
trans_start = q->trans_start;
2682+
trans_start = READ_ONCE(q->trans_start);
26832683
if (netif_xmit_stopped(q) &&
26842684
time_after(jiffies,
26852685
(trans_start + ndev->watchdog_timeo))) {

drivers/net/ethernet/ibm/ibmvnic.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2058,7 +2058,7 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
20582058

20592059
tx_packets++;
20602060
tx_bytes += skb->len;
2061-
txq->trans_start = jiffies;
2061+
txq_trans_cond_update(txq);
20622062
ret = NETDEV_TX_OK;
20632063
goto out;
20642064

drivers/net/ethernet/intel/igb/igb_main.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2927,7 +2927,7 @@ static int igb_xdp_xmit_back(struct igb_adapter *adapter, struct xdp_buff *xdp)
29272927
nq = txring_txq(tx_ring);
29282928
__netif_tx_lock(nq, cpu);
29292929
/* Avoid transmit queue timeout since we share it with the slow path */
2930-
nq->trans_start = jiffies;
2930+
txq_trans_cond_update(nq);
29312931
ret = igb_xmit_xdp_ring(adapter, tx_ring, xdpf);
29322932
__netif_tx_unlock(nq);
29332933

@@ -2961,7 +2961,7 @@ static int igb_xdp_xmit(struct net_device *dev, int n,
29612961
__netif_tx_lock(nq, cpu);
29622962

29632963
/* Avoid transmit queue timeout since we share it with the slow path */
2964-
nq->trans_start = jiffies;
2964+
txq_trans_cond_update(nq);
29652965

29662966
for (i = 0; i < n; i++) {
29672967
struct xdp_frame *xdpf = frames[i];

drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,7 @@ int mlx5e_reporter_tx_timeout(struct mlx5e_txqsq *sq)
565565
snprintf(err_str, sizeof(err_str),
566566
"TX timeout on queue: %d, SQ: 0x%x, CQ: 0x%x, SQ Cons: 0x%x SQ Prod: 0x%x, usecs since last trans: %u",
567567
sq->ch_ix, sq->sqn, sq->cq.mcq.cqn, sq->cc, sq->pc,
568-
jiffies_to_usecs(jiffies - sq->txq->trans_start));
568+
jiffies_to_usecs(jiffies - READ_ONCE(sq->txq->trans_start)));
569569

570570
mlx5e_health_report(priv, priv->tx_reporter, err_str, &err_ctx);
571571
return to_ctx.status;

drivers/net/ethernet/stmicro/stmmac/stmmac_main.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2356,7 +2356,7 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
23562356
bool work_done = true;
23572357

23582358
/* Avoids TX time-out as we are sharing with slow path */
2359-
nq->trans_start = jiffies;
2359+
txq_trans_cond_update(nq->trans_start);
23602360

23612361
budget = min(budget, stmmac_tx_avail(priv, queue));
23622362

@@ -4657,7 +4657,7 @@ static int stmmac_xdp_xmit_back(struct stmmac_priv *priv,
46574657

46584658
__netif_tx_lock(nq, cpu);
46594659
/* Avoids TX time-out as we are sharing with slow path */
4660-
nq->trans_start = jiffies;
4660+
txq_trans_cond_update(nq->trans_start);
46614661

46624662
res = stmmac_xdp_xmit_xdpf(priv, queue, xdpf, false);
46634663
if (res == STMMAC_XDP_TX)
@@ -6293,7 +6293,7 @@ static int stmmac_xdp_xmit(struct net_device *dev, int num_frames,
62936293

62946294
__netif_tx_lock(nq, cpu);
62956295
/* Avoids TX time-out as we are sharing with slow path */
6296-
nq->trans_start = jiffies;
6296+
txq_trans_cond_update(nq);
62976297

62986298
for (i = 0; i < num_frames; i++) {
62996299
int res;

drivers/net/ethernet/ti/am65-cpsw-nuss.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ static void am65_cpsw_nuss_ndo_host_tx_timeout(struct net_device *ndev,
345345

346346
netif_txq = netdev_get_tx_queue(ndev, txqueue);
347347
tx_chn = &common->tx_chns[txqueue];
348-
trans_start = netif_txq->trans_start;
348+
trans_start = READ_ONCE(netif_txq->trans_start);
349349

350350
netdev_err(ndev, "txq:%d DRV_XOFF:%d tmo:%u dql_avail:%d free_desc:%zu\n",
351351
txqueue,

drivers/net/virtio_net.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2694,7 +2694,7 @@ static void virtnet_tx_timeout(struct net_device *dev, unsigned int txqueue)
26942694

26952695
netdev_err(dev, "TX timeout on queue: %u, sq: %s, vq: 0x%x, name: %s, %u usecs ago\n",
26962696
txqueue, sq->name, sq->vq->index, sq->vq->name,
2697-
jiffies_to_usecs(jiffies - txq->trans_start));
2697+
jiffies_to_usecs(jiffies - READ_ONCE(txq->trans_start)));
26982698
}
26992699

27002700
static const struct net_device_ops virtnet_netdev = {

drivers/net/wireless/marvell/mwifiex/init.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ void mwifiex_set_trans_start(struct net_device *dev)
332332
int i;
333333

334334
for (i = 0; i < dev->num_tx_queues; i++)
335-
netdev_get_tx_queue(dev, i)->trans_start = jiffies;
335+
txq_trans_cond_update(netdev_get_tx_queue(dev, i));
336336

337337
netif_trans_update(dev);
338338
}

drivers/staging/rtl8192e/rtllib_softmac.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2515,7 +2515,7 @@ void rtllib_stop_all_queues(struct rtllib_device *ieee)
25152515
unsigned int i;
25162516

25172517
for (i = 0; i < ieee->dev->num_tx_queues; i++)
2518-
netdev_get_tx_queue(ieee->dev, i)->trans_start = jiffies;
2518+
txq_trans_cond_update(netdev_get_tx_queue(ieee->dev, i));
25192519

25202520
netif_tx_stop_all_queues(ieee->dev);
25212521
}

include/linux/netdevice.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4095,19 +4095,29 @@ static inline void __netif_tx_unlock_bh(struct netdev_queue *txq)
40954095
spin_unlock_bh(&txq->_xmit_lock);
40964096
}
40974097

4098+
/*
4099+
* txq->trans_start can be read locklessly from dev_watchdog()
4100+
*/
40984101
static inline void txq_trans_update(struct netdev_queue *txq)
40994102
{
41004103
if (txq->xmit_lock_owner != -1)
4101-
txq->trans_start = jiffies;
4104+
WRITE_ONCE(txq->trans_start, jiffies);
4105+
}
4106+
4107+
static inline void txq_trans_cond_update(struct netdev_queue *txq)
4108+
{
4109+
unsigned long now = jiffies;
4110+
4111+
if (READ_ONCE(txq->trans_start) != now)
4112+
WRITE_ONCE(txq->trans_start, now);
41024113
}
41034114

41044115
/* legacy drivers only, netdev_start_xmit() sets txq->trans_start */
41054116
static inline void netif_trans_update(struct net_device *dev)
41064117
{
41074118
struct netdev_queue *txq = netdev_get_tx_queue(dev, 0);
41084119

4109-
if (txq->trans_start != jiffies)
4110-
txq->trans_start = jiffies;
4120+
txq_trans_cond_update(txq);
41114121
}
41124122

41134123
/**

net/sched/sch_generic.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -434,9 +434,9 @@ unsigned long dev_trans_start(struct net_device *dev)
434434
dev = vlan_dev_real_dev(dev);
435435
else if (netif_is_macvlan(dev))
436436
dev = macvlan_dev_real_dev(dev);
437-
res = netdev_get_tx_queue(dev, 0)->trans_start;
437+
res = READ_ONCE(netdev_get_tx_queue(dev, 0)->trans_start);
438438
for (i = 1; i < dev->num_tx_queues; i++) {
439-
val = netdev_get_tx_queue(dev, i)->trans_start;
439+
val = READ_ONCE(netdev_get_tx_queue(dev, i)->trans_start);
440440
if (val && time_after(val, res))
441441
res = val;
442442
}
@@ -462,7 +462,7 @@ static void dev_watchdog(struct timer_list *t)
462462
struct netdev_queue *txq;
463463

464464
txq = netdev_get_tx_queue(dev, i);
465-
trans_start = txq->trans_start;
465+
trans_start = READ_ONCE(txq->trans_start);
466466
if (netif_xmit_stopped(txq) &&
467467
time_after(jiffies, (trans_start +
468468
dev->watchdog_timeo))) {
@@ -1148,7 +1148,7 @@ static void transition_one_qdisc(struct net_device *dev,
11481148

11491149
rcu_assign_pointer(dev_queue->qdisc, new_qdisc);
11501150
if (need_watchdog_p) {
1151-
dev_queue->trans_start = 0;
1151+
WRITE_ONCE(dev_queue->trans_start, 0);
11521152
*need_watchdog_p = 1;
11531153
}
11541154
}

0 commit comments

Comments
 (0)