ppp: annotate concurrent dev->stats accesses

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: 1da177e4c3 ("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>
This commit is contained in:
Eric Dumazet 2026-07-15 05:55:41 +00:00 committed by Jakub Kicinski
parent 0ab78ead24
commit ba712ecfd9

View 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;