net: napi: use READ_ONCE()/WRITE_ONCE()
authorEric Dumazet <edumazet@google.com>
Wed, 22 Apr 2020 16:13:28 +0000 (09:13 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 23 Apr 2020 19:43:20 +0000 (12:43 -0700)
gro_flush_timeout and napi_defer_hard_irqs can be read
from napi_complete_done() while other cpus write the value,
whithout explicit synchronization.

Use READ_ONCE()/WRITE_ONCE() to annotate the races.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/core/dev.c
net/core/net-sysfs.c

index 6758548..afff168 100644 (file)
@@ -6242,12 +6242,12 @@ bool napi_complete_done(struct napi_struct *n, int work_done)
 
        if (work_done) {
                if (n->gro_bitmask)
-                       timeout = n->dev->gro_flush_timeout;
-               n->defer_hard_irqs_count = n->dev->napi_defer_hard_irqs;
+                       timeout = READ_ONCE(n->dev->gro_flush_timeout);
+               n->defer_hard_irqs_count = READ_ONCE(n->dev->napi_defer_hard_irqs);
        }
        if (n->defer_hard_irqs_count > 0) {
                n->defer_hard_irqs_count--;
-               timeout = n->dev->gro_flush_timeout;
+               timeout = READ_ONCE(n->dev->gro_flush_timeout);
                if (timeout)
                        ret = false;
        }
index f3b650c..880e89c 100644 (file)
@@ -367,7 +367,7 @@ NETDEVICE_SHOW_RW(tx_queue_len, fmt_dec);
 
 static int change_gro_flush_timeout(struct net_device *dev, unsigned long val)
 {
-       dev->gro_flush_timeout = val;
+       WRITE_ONCE(dev->gro_flush_timeout, val);
        return 0;
 }
 
@@ -384,7 +384,7 @@ NETDEVICE_SHOW_RW(gro_flush_timeout, fmt_ulong);
 
 static int change_napi_defer_hard_irqs(struct net_device *dev, unsigned long val)
 {
-       dev->napi_defer_hard_irqs = val;
+       WRITE_ONCE(dev->napi_defer_hard_irqs, val);
        return 0;
 }