net: use an atomic_long_t for queue->trans_timeout
authorEric Dumazet <edumazet@google.com>
Wed, 17 Nov 2021 03:29:21 +0000 (19:29 -0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 17 Nov 2021 14:56:16 +0000 (14:56 +0000)
tx_timeout_show() assumed dev_watchdog() would stop all
the queues, to fetch queue->trans_timeout under protection
of the queue->_xmit_lock.

As we want to no longer disrupt transmits, we use an
atomic_long_t instead.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: david decotigny <david.decotigny@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/netdevice.h
net/core/net-sysfs.c
net/sched/sch_generic.c

index dd32836..1d22483 100644 (file)
@@ -592,7 +592,7 @@ struct netdev_queue {
         * Number of TX timeouts for this queue
         * (/sys/class/net/DEV/Q/trans_timeout)
         */
-       unsigned long           trans_timeout;
+       atomic_long_t           trans_timeout;
 
        /* Subordinate device that the queue has been assigned to */
        struct net_device       *sb_dev;
index 9c01c64..addbef5 100644 (file)
@@ -1201,11 +1201,7 @@ static const struct sysfs_ops netdev_queue_sysfs_ops = {
 
 static ssize_t tx_timeout_show(struct netdev_queue *queue, char *buf)
 {
-       unsigned long trans_timeout;
-
-       spin_lock_irq(&queue->_xmit_lock);
-       trans_timeout = queue->trans_timeout;
-       spin_unlock_irq(&queue->_xmit_lock);
+       unsigned long trans_timeout = atomic_long_read(&queue->trans_timeout);
 
        return sprintf(buf, fmt_ulong, trans_timeout);
 }
index 3b0f620..1b4328b 100644 (file)
@@ -467,7 +467,7 @@ static void dev_watchdog(struct timer_list *t)
                                    time_after(jiffies, (trans_start +
                                                         dev->watchdog_timeo))) {
                                        some_queue_timedout = 1;
-                                       txq->trans_timeout++;
+                                       atomic_long_inc(&txq->trans_timeout);
                                        break;
                                }
                        }