[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250625034021.3650359-4-dqfext@gmail.com>
Date: Wed, 25 Jun 2025 11:40:20 +0800
From: Qingfang Deng <dqfext@...il.com>
To: Andrew Lunn <andrew+netdev@...n.ch>,
"David S. Miller" <davem@...emloft.net>,
Eric Dumazet <edumazet@...gle.com>,
Jakub Kicinski <kuba@...nel.org>,
Paolo Abeni <pabeni@...hat.com>,
linux-ppp@...r.kernel.org,
netdev@...r.kernel.org,
linux-kernel@...r.kernel.org
Cc: Guillaume Nault <gnault@...hat.com>
Subject: [PATCH net-next 3/3] ppp: synchronize netstats updates
The PPP receive path can now run concurrently across CPUs (after converting
rlock to rwlock in an earlier patch). This may lead to data races on
net_device->stats.
Convert all stats updates in both transmit and receive paths to use the
DEV_STATS_INC() macro, which updates stats atomically.
Signed-off-by: Qingfang Deng <dqfext@...il.com>
---
drivers/net/ppp/ppp_generic.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index f0f8a75e3aef..4e787d1823c1 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -1478,7 +1478,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;
}
@@ -1851,7 +1851,7 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
drop:
kfree_skb(skb);
- ++ppp->dev->stats.tx_errors;
+ DEV_STATS_INC(ppp->dev, tx_errors);
}
/*
@@ -2134,7 +2134,7 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
spin_unlock(&pch->downl);
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 */
}
@@ -2296,7 +2296,7 @@ ppp_input(struct ppp_channel *chan, struct sk_buff *skb)
if (!ppp_decompress_proto(skb)) {
kfree_skb(skb);
if (pch->ppp) {
- ++pch->ppp->dev->stats.rx_length_errors;
+ DEV_STATS_INC(pch->ppp->dev, rx_length_errors);
ppp_receive_error(pch->ppp);
}
goto done;
@@ -2367,7 +2367,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);
}
@@ -2634,7 +2634,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;
}
@@ -2670,7 +2670,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);
}
@@ -2776,7 +2776,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);
@@ -2831,7 +2831,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);
}
--
2.43.0
Powered by blists - more mailing lists