* [PATCH net-next v2 0/2] net: airoha: Use u64_stats_t with u64_stats_sync properly
@ 2026-01-25 22:07 David Yang
2026-01-25 22:07 ` [PATCH net-next v2 1/2] u64_stats: Allow u64_stats_add() to accept s64 David Yang
2026-01-25 22:07 ` [PATCH net-next v2 2/2] net: airoha: Use u64_stats_t with u64_stats_sync properly David Yang
0 siblings, 2 replies; 5+ messages in thread
From: David Yang @ 2026-01-25 22:07 UTC (permalink / raw)
To: netdev
Cc: David Yang, Lorenzo Bianconi, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, linux-arm-kernel,
linux-mediatek, linux-kernel
v1: https://lore.kernel.org/r/20260122185255.2761568-1-mmyangfl@gmail.com
- fix u64_stats_add()
David Yang (2):
u64_stats: Allow u64_stats_add() to accept s64
net: airoha: Use u64_stats_t with u64_stats_sync properly
drivers/net/ethernet/airoha/airoha_eth.c | 153 +++++++++++++----------
drivers/net/ethernet/airoha/airoha_eth.h | 34 ++---
include/linux/u64_stats_sync.h | 4 +-
3 files changed, 104 insertions(+), 87 deletions(-)
--
2.51.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH net-next v2 1/2] u64_stats: Allow u64_stats_add() to accept s64
2026-01-25 22:07 [PATCH net-next v2 0/2] net: airoha: Use u64_stats_t with u64_stats_sync properly David Yang
@ 2026-01-25 22:07 ` David Yang
2026-01-25 22:38 ` David Laight
2026-01-25 22:07 ` [PATCH net-next v2 2/2] net: airoha: Use u64_stats_t with u64_stats_sync properly David Yang
1 sibling, 1 reply; 5+ messages in thread
From: David Yang @ 2026-01-25 22:07 UTC (permalink / raw)
To: netdev
Cc: David Yang, Lorenzo Bianconi, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, linux-arm-kernel,
linux-mediatek, linux-kernel
The current u64_stats_add() accepts only unsigned long, which makes no
sense as u64_stats_set() accepts u64 already, and causes unnecessary
narrowing on 32-bit architectures.
Moreover, since there's no u64_stats_sub(), users may be tempted to
reuse it for decrements, which already happened on nft_counter_reset()
in net/netfilter/nft_counter.c .
Change to s64 to allow both positive and negative values.
Signed-off-by: David Yang <mmyangfl@gmail.com>
---
include/linux/u64_stats_sync.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/linux/u64_stats_sync.h b/include/linux/u64_stats_sync.h
index 457879938fc1..e77f2b30bac7 100644
--- a/include/linux/u64_stats_sync.h
+++ b/include/linux/u64_stats_sync.h
@@ -84,7 +84,7 @@ static inline void u64_stats_set(u64_stats_t *p, u64 val)
local64_set(&p->v, val);
}
-static inline void u64_stats_add(u64_stats_t *p, unsigned long val)
+static inline void u64_stats_add(u64_stats_t *p, s64 val)
{
local64_add(val, &p->v);
}
@@ -125,7 +125,7 @@ static inline void u64_stats_set(u64_stats_t *p, u64 val)
p->v = val;
}
-static inline void u64_stats_add(u64_stats_t *p, unsigned long val)
+static inline void u64_stats_add(u64_stats_t *p, s64 val)
{
p->v += val;
}
--
2.51.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH net-next v2 2/2] net: airoha: Use u64_stats_t with u64_stats_sync properly
2026-01-25 22:07 [PATCH net-next v2 0/2] net: airoha: Use u64_stats_t with u64_stats_sync properly David Yang
2026-01-25 22:07 ` [PATCH net-next v2 1/2] u64_stats: Allow u64_stats_add() to accept s64 David Yang
@ 2026-01-25 22:07 ` David Yang
2026-01-26 0:35 ` Jakub Kicinski
1 sibling, 1 reply; 5+ messages in thread
From: David Yang @ 2026-01-25 22:07 UTC (permalink / raw)
To: netdev
Cc: David Yang, Lorenzo Bianconi, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, linux-arm-kernel,
linux-mediatek, linux-kernel
On 64bit arches, struct u64_stats_sync is empty and provides no help
against load/store tearing. Convert to u64_stats_t to ensure atomic
operations.
Signed-off-by: David Yang <mmyangfl@gmail.com>
Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 153 +++++++++++++----------
drivers/net/ethernet/airoha/airoha_eth.h | 34 ++---
2 files changed, 102 insertions(+), 85 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 62bcbbbe2a95..fe53aa93a003 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1466,137 +1466,154 @@ static void airoha_update_hw_stats(struct airoha_gdm_port *port)
{
struct airoha_eth *eth = port->qdma->eth;
u32 val, i = 0;
+ u64 val64;
spin_lock(&port->stats.lock);
u64_stats_update_begin(&port->stats.syncp);
/* TX */
val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_PKT_CNT_H(port->id));
- port->stats.tx_ok_pkts += ((u64)val << 32);
+ val64 = (u64)val << 32;
val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_PKT_CNT_L(port->id));
- port->stats.tx_ok_pkts += val;
+ val64 += val;
+ u64_stats_add(&port->stats.tx_ok_pkts, val64);
val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_BYTE_CNT_H(port->id));
- port->stats.tx_ok_bytes += ((u64)val << 32);
+ val64 = (u64)val << 32;
val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_BYTE_CNT_L(port->id));
- port->stats.tx_ok_bytes += val;
+ val64 += val;
+ u64_stats_add(&port->stats.tx_ok_bytes, val64);
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_DROP_CNT(port->id));
- port->stats.tx_drops += val;
+ u64_stats_add(&port->stats.tx_drops, val);
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_BC_CNT(port->id));
- port->stats.tx_broadcast += val;
+ u64_stats_add(&port->stats.tx_broadcast, val);
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_MC_CNT(port->id));
- port->stats.tx_multicast += val;
+ u64_stats_add(&port->stats.tx_multicast, val);
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_RUNT_CNT(port->id));
- port->stats.tx_len[i] += val;
+ val64 = val;
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_E64_CNT_H(port->id));
- port->stats.tx_len[i] += ((u64)val << 32);
+ val64 += (u64)val << 32;
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_E64_CNT_L(port->id));
- port->stats.tx_len[i++] += val;
+ val64 += val;
+ u64_stats_add(&port->stats.tx_len[i++], val64);
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L64_CNT_H(port->id));
- port->stats.tx_len[i] += ((u64)val << 32);
+ val64 = (u64)val << 32;
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L64_CNT_L(port->id));
- port->stats.tx_len[i++] += val;
+ val64 += val;
+ u64_stats_add(&port->stats.tx_len[i++], val64);
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L127_CNT_H(port->id));
- port->stats.tx_len[i] += ((u64)val << 32);
+ val64 = (u64)val << 32;
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L127_CNT_L(port->id));
- port->stats.tx_len[i++] += val;
+ val64 += val;
+ u64_stats_add(&port->stats.tx_len[i++], val64);
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L255_CNT_H(port->id));
- port->stats.tx_len[i] += ((u64)val << 32);
+ val64 = (u64)val << 32;
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L255_CNT_L(port->id));
- port->stats.tx_len[i++] += val;
+ val64 += val;
+ u64_stats_add(&port->stats.tx_len[i++], val64);
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L511_CNT_H(port->id));
- port->stats.tx_len[i] += ((u64)val << 32);
+ val64 = (u64)val << 32;
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L511_CNT_L(port->id));
- port->stats.tx_len[i++] += val;
+ val64 += val;
+ u64_stats_add(&port->stats.tx_len[i++], val64);
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L1023_CNT_H(port->id));
- port->stats.tx_len[i] += ((u64)val << 32);
+ val64 = (u64)val << 32;
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L1023_CNT_L(port->id));
- port->stats.tx_len[i++] += val;
+ val64 += val;
+ u64_stats_add(&port->stats.tx_len[i++], val64);
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_LONG_CNT(port->id));
- port->stats.tx_len[i++] += val;
+ u64_stats_add(&port->stats.tx_len[i++], val);
/* RX */
val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_PKT_CNT_H(port->id));
- port->stats.rx_ok_pkts += ((u64)val << 32);
+ val64 = (u64)val << 32;
val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_PKT_CNT_L(port->id));
- port->stats.rx_ok_pkts += val;
+ val64 += val;
+ u64_stats_add(&port->stats.rx_ok_pkts, val64);
val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_BYTE_CNT_H(port->id));
- port->stats.rx_ok_bytes += ((u64)val << 32);
+ val64 = (u64)val << 32;
val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_BYTE_CNT_L(port->id));
- port->stats.rx_ok_bytes += val;
+ val64 += val;
+ u64_stats_add(&port->stats.rx_ok_bytes, val64);
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_DROP_CNT(port->id));
- port->stats.rx_drops += val;
+ u64_stats_add(&port->stats.rx_drops, val);
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_BC_CNT(port->id));
- port->stats.rx_broadcast += val;
+ u64_stats_add(&port->stats.rx_broadcast, val);
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_MC_CNT(port->id));
- port->stats.rx_multicast += val;
+ u64_stats_add(&port->stats.rx_multicast, val);
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ERROR_DROP_CNT(port->id));
- port->stats.rx_errors += val;
+ u64_stats_add(&port->stats.rx_errors, val);
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_CRC_ERR_CNT(port->id));
- port->stats.rx_crc_error += val;
+ u64_stats_add(&port->stats.rx_crc_error, val);
val = airoha_fe_rr(eth, REG_FE_GDM_RX_OVERFLOW_DROP_CNT(port->id));
- port->stats.rx_over_errors += val;
+ u64_stats_add(&port->stats.rx_over_errors, val);
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_FRAG_CNT(port->id));
- port->stats.rx_fragment += val;
+ u64_stats_add(&port->stats.rx_fragment, val);
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_JABBER_CNT(port->id));
- port->stats.rx_jabber += val;
+ u64_stats_add(&port->stats.rx_jabber, val);
i = 0;
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_RUNT_CNT(port->id));
- port->stats.rx_len[i] += val;
+ val64 = val;
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_E64_CNT_H(port->id));
- port->stats.rx_len[i] += ((u64)val << 32);
+ val64 += (u64)val << 32;
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_E64_CNT_L(port->id));
- port->stats.rx_len[i++] += val;
+ val64 += val;
+ u64_stats_add(&port->stats.rx_len[i++], val64);
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L64_CNT_H(port->id));
- port->stats.rx_len[i] += ((u64)val << 32);
+ val64 = (u64)val << 32;
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L64_CNT_L(port->id));
- port->stats.rx_len[i++] += val;
+ val64 += val;
+ u64_stats_add(&port->stats.rx_len[i++], val64);
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L127_CNT_H(port->id));
- port->stats.rx_len[i] += ((u64)val << 32);
+ val64 = (u64)val << 32;
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L127_CNT_L(port->id));
- port->stats.rx_len[i++] += val;
+ val64 += val;
+ u64_stats_add(&port->stats.rx_len[i++], val64);
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L255_CNT_H(port->id));
- port->stats.rx_len[i] += ((u64)val << 32);
+ val64 = (u64)val << 32;
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L255_CNT_L(port->id));
- port->stats.rx_len[i++] += val;
+ val64 += val;
+ u64_stats_add(&port->stats.rx_len[i++], val64);
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L511_CNT_H(port->id));
- port->stats.rx_len[i] += ((u64)val << 32);
+ val64 = (u64)val << 32;
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L511_CNT_L(port->id));
- port->stats.rx_len[i++] += val;
+ val64 += val;
+ u64_stats_add(&port->stats.rx_len[i++], val64);
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L1023_CNT_H(port->id));
- port->stats.rx_len[i] += ((u64)val << 32);
+ val64 = (u64)val << 32;
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L1023_CNT_L(port->id));
- port->stats.rx_len[i++] += val;
+ val64 += val;
+ u64_stats_add(&port->stats.rx_len[i++], val64);
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_LONG_CNT(port->id));
- port->stats.rx_len[i++] += val;
+ u64_stats_add(&port->stats.rx_len[i++], val);
/* reset mib counters */
airoha_fe_set(eth, REG_FE_GDM_MIB_CLEAR(port->id),
@@ -1795,16 +1812,16 @@ static void airoha_dev_get_stats64(struct net_device *dev,
airoha_update_hw_stats(port);
do {
start = u64_stats_fetch_begin(&port->stats.syncp);
- storage->rx_packets = port->stats.rx_ok_pkts;
- storage->tx_packets = port->stats.tx_ok_pkts;
- storage->rx_bytes = port->stats.rx_ok_bytes;
- storage->tx_bytes = port->stats.tx_ok_bytes;
- storage->multicast = port->stats.rx_multicast;
- storage->rx_errors = port->stats.rx_errors;
- storage->rx_dropped = port->stats.rx_drops;
- storage->tx_dropped = port->stats.tx_drops;
- storage->rx_crc_errors = port->stats.rx_crc_error;
- storage->rx_over_errors = port->stats.rx_over_errors;
+ storage->rx_packets = u64_stats_read(&port->stats.rx_ok_pkts);
+ storage->tx_packets = u64_stats_read(&port->stats.tx_ok_pkts);
+ storage->rx_bytes = u64_stats_read(&port->stats.rx_ok_bytes);
+ storage->tx_bytes = u64_stats_read(&port->stats.tx_ok_bytes);
+ storage->multicast = u64_stats_read(&port->stats.rx_multicast);
+ storage->rx_errors = u64_stats_read(&port->stats.rx_errors);
+ storage->rx_dropped = u64_stats_read(&port->stats.rx_drops);
+ storage->tx_dropped = u64_stats_read(&port->stats.tx_drops);
+ storage->rx_crc_errors = u64_stats_read(&port->stats.rx_crc_error);
+ storage->rx_over_errors = u64_stats_read(&port->stats.rx_over_errors);
} while (u64_stats_fetch_retry(&port->stats.syncp, start));
}
@@ -2057,13 +2074,13 @@ static void airoha_ethtool_get_mac_stats(struct net_device *dev,
airoha_update_hw_stats(port);
do {
start = u64_stats_fetch_begin(&port->stats.syncp);
- stats->FramesTransmittedOK = port->stats.tx_ok_pkts;
- stats->OctetsTransmittedOK = port->stats.tx_ok_bytes;
- stats->MulticastFramesXmittedOK = port->stats.tx_multicast;
- stats->BroadcastFramesXmittedOK = port->stats.tx_broadcast;
- stats->FramesReceivedOK = port->stats.rx_ok_pkts;
- stats->OctetsReceivedOK = port->stats.rx_ok_bytes;
- stats->BroadcastFramesReceivedOK = port->stats.rx_broadcast;
+ stats->FramesTransmittedOK = u64_stats_read(&port->stats.tx_ok_pkts);
+ stats->OctetsTransmittedOK = u64_stats_read(&port->stats.tx_ok_bytes);
+ stats->MulticastFramesXmittedOK = u64_stats_read(&port->stats.tx_multicast);
+ stats->BroadcastFramesXmittedOK = u64_stats_read(&port->stats.tx_broadcast);
+ stats->FramesReceivedOK = u64_stats_read(&port->stats.rx_ok_pkts);
+ stats->OctetsReceivedOK = u64_stats_read(&port->stats.rx_ok_bytes);
+ stats->BroadcastFramesReceivedOK = u64_stats_read(&port->stats.rx_broadcast);
} while (u64_stats_fetch_retry(&port->stats.syncp, start));
}
@@ -2098,12 +2115,12 @@ airoha_ethtool_get_rmon_stats(struct net_device *dev,
int i;
start = u64_stats_fetch_begin(&port->stats.syncp);
- stats->fragments = hw_stats->rx_fragment;
- stats->jabbers = hw_stats->rx_jabber;
+ stats->fragments = u64_stats_read(&hw_stats->rx_fragment);
+ stats->jabbers = u64_stats_read(&hw_stats->rx_jabber);
for (i = 0; i < ARRAY_SIZE(airoha_ethtool_rmon_ranges) - 1;
i++) {
- stats->hist[i] = hw_stats->rx_len[i];
- stats->hist_tx[i] = hw_stats->tx_len[i];
+ stats->hist[i] = u64_stats_read(&hw_stats->rx_len[i]);
+ stats->hist_tx[i] = u64_stats_read(&hw_stats->tx_len[i]);
}
} while (u64_stats_fetch_retry(&port->stats.syncp, start));
}
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index 20e602d61e61..b2e9bd849f8b 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -215,24 +215,24 @@ struct airoha_hw_stats {
struct u64_stats_sync syncp;
/* get_stats64 */
- u64 rx_ok_pkts;
- u64 tx_ok_pkts;
- u64 rx_ok_bytes;
- u64 tx_ok_bytes;
- u64 rx_multicast;
- u64 rx_errors;
- u64 rx_drops;
- u64 tx_drops;
- u64 rx_crc_error;
- u64 rx_over_errors;
+ u64_stats_t rx_ok_pkts;
+ u64_stats_t tx_ok_pkts;
+ u64_stats_t rx_ok_bytes;
+ u64_stats_t tx_ok_bytes;
+ u64_stats_t rx_multicast;
+ u64_stats_t rx_errors;
+ u64_stats_t rx_drops;
+ u64_stats_t tx_drops;
+ u64_stats_t rx_crc_error;
+ u64_stats_t rx_over_errors;
/* ethtool stats */
- u64 tx_broadcast;
- u64 tx_multicast;
- u64 tx_len[7];
- u64 rx_broadcast;
- u64 rx_fragment;
- u64 rx_jabber;
- u64 rx_len[7];
+ u64_stats_t tx_broadcast;
+ u64_stats_t tx_multicast;
+ u64_stats_t tx_len[7];
+ u64_stats_t rx_broadcast;
+ u64_stats_t rx_fragment;
+ u64_stats_t rx_jabber;
+ u64_stats_t rx_len[7];
};
enum {
--
2.51.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH net-next v2 1/2] u64_stats: Allow u64_stats_add() to accept s64
2026-01-25 22:07 ` [PATCH net-next v2 1/2] u64_stats: Allow u64_stats_add() to accept s64 David Yang
@ 2026-01-25 22:38 ` David Laight
0 siblings, 0 replies; 5+ messages in thread
From: David Laight @ 2026-01-25 22:38 UTC (permalink / raw)
To: David Yang
Cc: netdev, Lorenzo Bianconi, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, linux-arm-kernel,
linux-mediatek, linux-kernel
On Mon, 26 Jan 2026 06:07:49 +0800
David Yang <mmyangfl@gmail.com> wrote:
> The current u64_stats_add() accepts only unsigned long, which makes no
> sense as u64_stats_set() accepts u64 already, and causes unnecessary
> narrowing on 32-bit architectures.
Isn't is a chicken/egg?
A value over 2^31 could just be a very large value that needs to be added.
Where the add is being done 'just in time' so avoid overflow.
David
>
> Moreover, since there's no u64_stats_sub(), users may be tempted to
> reuse it for decrements, which already happened on nft_counter_reset()
> in net/netfilter/nft_counter.c .
>
> Change to s64 to allow both positive and negative values.
>
> Signed-off-by: David Yang <mmyangfl@gmail.com>
> ---
> include/linux/u64_stats_sync.h | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/u64_stats_sync.h b/include/linux/u64_stats_sync.h
> index 457879938fc1..e77f2b30bac7 100644
> --- a/include/linux/u64_stats_sync.h
> +++ b/include/linux/u64_stats_sync.h
> @@ -84,7 +84,7 @@ static inline void u64_stats_set(u64_stats_t *p, u64 val)
> local64_set(&p->v, val);
> }
>
> -static inline void u64_stats_add(u64_stats_t *p, unsigned long val)
> +static inline void u64_stats_add(u64_stats_t *p, s64 val)
> {
> local64_add(val, &p->v);
> }
> @@ -125,7 +125,7 @@ static inline void u64_stats_set(u64_stats_t *p, u64 val)
> p->v = val;
> }
>
> -static inline void u64_stats_add(u64_stats_t *p, unsigned long val)
> +static inline void u64_stats_add(u64_stats_t *p, s64 val)
> {
> p->v += val;
> }
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net-next v2 2/2] net: airoha: Use u64_stats_t with u64_stats_sync properly
2026-01-25 22:07 ` [PATCH net-next v2 2/2] net: airoha: Use u64_stats_t with u64_stats_sync properly David Yang
@ 2026-01-26 0:35 ` Jakub Kicinski
0 siblings, 0 replies; 5+ messages in thread
From: Jakub Kicinski @ 2026-01-26 0:35 UTC (permalink / raw)
To: David Yang
Cc: netdev, Lorenzo Bianconi, Andrew Lunn, David S. Miller,
Eric Dumazet, Paolo Abeni, linux-arm-kernel, linux-mediatek,
linux-kernel
On Mon, 26 Jan 2026 06:07:50 +0800 David Yang wrote:
> On 64bit arches, struct u64_stats_sync is empty and provides no help
> against load/store tearing. Convert to u64_stats_t to ensure atomic
> operations.
The driver takes a spin lock over the very expensive series
of register reads and then drops out to copy the just read
values? Just move the readers under the spinlock?
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-01-26 0:35 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-25 22:07 [PATCH net-next v2 0/2] net: airoha: Use u64_stats_t with u64_stats_sync properly David Yang
2026-01-25 22:07 ` [PATCH net-next v2 1/2] u64_stats: Allow u64_stats_add() to accept s64 David Yang
2026-01-25 22:38 ` David Laight
2026-01-25 22:07 ` [PATCH net-next v2 2/2] net: airoha: Use u64_stats_t with u64_stats_sync properly David Yang
2026-01-26 0:35 ` Jakub Kicinski
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox