]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ppp: annotate concurrent dev->stats accesses
authorEric Dumazet <edumazet@google.com>
Wed, 15 Jul 2026 05:55:41 +0000 (05:55 +0000)
committerJakub Kicinski <kuba@kernel.org>
Wed, 22 Jul 2026 01:45:36 +0000 (18:45 -0700)
dev->stats fields can be updated concurrently from multiple CPUs
without synchronization.

Use DEV_STATS_INC() for stats increments and DEV_STATS_READ()
when reading dev->stats in ppp_get_stats64() and ppp_get_stats()
to avoid data races.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Qingfang Deng <qingfang.deng@linux.dev>
Link: https://patch.msgid.link/20260715055541.1147542-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ppp/ppp_generic.c

index 717c1d3aa95380da64eb5ae6fc1da6e4dfaa9d87..ef54e0a0462a175bb989db8dda895e9ae755965f 100644 (file)
@@ -1482,7 +1482,7 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
  outf:
        kfree_skb(skb);
-       ++dev->stats.tx_dropped;
+       DEV_STATS_INC(dev, tx_dropped);
        return NETDEV_TX_OK;
 }
 
@@ -1532,11 +1532,11 @@ ppp_net_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
 static void
 ppp_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats64)
 {
-       stats64->rx_errors        = dev->stats.rx_errors;
-       stats64->tx_errors        = dev->stats.tx_errors;
-       stats64->rx_dropped       = dev->stats.rx_dropped;
-       stats64->tx_dropped       = dev->stats.tx_dropped;
-       stats64->rx_length_errors = dev->stats.rx_length_errors;
+       stats64->rx_errors        = DEV_STATS_READ(dev, rx_errors);
+       stats64->tx_errors        = DEV_STATS_READ(dev, tx_errors);
+       stats64->rx_dropped       = DEV_STATS_READ(dev, rx_dropped);
+       stats64->tx_dropped       = DEV_STATS_READ(dev, tx_dropped);
+       stats64->rx_length_errors = DEV_STATS_READ(dev, rx_length_errors);
        dev_fetch_sw_netstats(stats64, dev->tstats);
 }
 
@@ -1889,7 +1889,7 @@ ppp_prepare_tx_skb(struct ppp *ppp, struct sk_buff **pskb)
 
  drop:
        kfree_skb(skb);
-       ++ppp->dev->stats.tx_errors;
+       DEV_STATS_INC(ppp->dev, tx_errors);
        return 1;
 }
 
@@ -2156,7 +2156,7 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
  err_linearize:
        if (ppp->debug & 1)
                netdev_err(ppp->dev, "PPP: no memory (fragment)\n");
-       ++ppp->dev->stats.tx_errors;
+       DEV_STATS_INC(ppp->dev, tx_errors);
        ++ppp->nxseq;
        return 1;       /* abandon the frame */
 }
@@ -2329,7 +2329,7 @@ ppp_input(struct ppp_channel *chan, struct sk_buff *skb)
        if (!ppp_decompress_proto(skb)) {
                kfree_skb(skb);
                if (ppp) {
-                       ++ppp->dev->stats.rx_length_errors;
+                       DEV_STATS_INC(ppp->dev, rx_length_errors);
                        ppp_receive_error(ppp);
                }
                goto done;
@@ -2391,7 +2391,7 @@ ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
 static void
 ppp_receive_error(struct ppp *ppp)
 {
-       ++ppp->dev->stats.rx_errors;
+       DEV_STATS_INC(ppp->dev, rx_errors);
        if (ppp->vj)
                slhc_toss(ppp->vj);
 }
@@ -2658,7 +2658,7 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
         */
        if (seq_before(seq, ppp->nextseq)) {
                kfree_skb(skb);
-               ++ppp->dev->stats.rx_dropped;
+               DEV_STATS_INC(ppp->dev, rx_dropped);
                ppp_receive_error(ppp);
                return;
        }
@@ -2694,7 +2694,7 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
                if (pskb_may_pull(skb, 2))
                        ppp_receive_nonmp_frame(ppp, skb);
                else {
-                       ++ppp->dev->stats.rx_length_errors;
+                       DEV_STATS_INC(ppp->dev, rx_length_errors);
                        kfree_skb(skb);
                        ppp_receive_error(ppp);
                }
@@ -2800,7 +2800,7 @@ ppp_mp_reconstruct(struct ppp *ppp)
                if (lost == 0 && (PPP_MP_CB(p)->BEbits & E) &&
                    (PPP_MP_CB(head)->BEbits & B)) {
                        if (len > ppp->mrru + 2) {
-                               ++ppp->dev->stats.rx_length_errors;
+                               DEV_STATS_INC(ppp->dev, rx_length_errors);
                                netdev_printk(KERN_DEBUG, ppp->dev,
                                              "PPP: reconstructed packet"
                                              " is too long (%d)\n", len);
@@ -2855,7 +2855,7 @@ ppp_mp_reconstruct(struct ppp *ppp)
                                              "  missed pkts %u..%u\n",
                                              ppp->nextseq,
                                              PPP_MP_CB(head)->sequence-1);
-                       ++ppp->dev->stats.rx_dropped;
+                       DEV_STATS_INC(ppp->dev, rx_dropped);
                        ppp_receive_error(ppp);
                }
 
@@ -3322,8 +3322,8 @@ ppp_get_stats(struct ppp *ppp, struct ppp_stats *st)
                st->p.ppp_opackets += tx_packets;
                st->p.ppp_obytes += tx_bytes;
        }
-       st->p.ppp_ierrors = ppp->dev->stats.rx_errors;
-       st->p.ppp_oerrors = ppp->dev->stats.tx_errors;
+       st->p.ppp_ierrors = DEV_STATS_READ(ppp->dev, rx_errors);
+       st->p.ppp_oerrors = DEV_STATS_READ(ppp->dev, tx_errors);
        if (!vj)
                return;
        st->vj.vjs_packets = vj->sls_o_compressed + vj->sls_o_uncompressed;