drivers/net/ethernet/alacritech/slic.h | 50 +++++++++++------------ drivers/net/ethernet/alacritech/slicoss.c | 8 ++-- 2 files changed, 29 insertions(+), 29 deletions(-)
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>
---
drivers/net/ethernet/alacritech/slic.h | 50 +++++++++++------------
drivers/net/ethernet/alacritech/slicoss.c | 8 ++--
2 files changed, 29 insertions(+), 29 deletions(-)
diff --git a/drivers/net/ethernet/alacritech/slic.h b/drivers/net/ethernet/alacritech/slic.h
index 82071d0e5f7f..f5bb2d9a61be 100644
--- a/drivers/net/ethernet/alacritech/slic.h
+++ b/drivers/net/ethernet/alacritech/slic.h
@@ -284,7 +284,7 @@
#define SLIC_INC_STATS_COUNTER(st, counter) \
do { \
u64_stats_update_begin(&(st)->syncp); \
- (st)->counter++; \
+ u64_stats_inc(&(st)->counter); \
u64_stats_update_end(&(st)->syncp); \
} while (0)
@@ -293,7 +293,7 @@ do { \
unsigned int start; \
do { \
start = u64_stats_fetch_begin(&(st)->syncp); \
- newst = (st)->counter; \
+ newst = u64_stats_read(&(st)->counter); \
} while (u64_stats_fetch_retry(&(st)->syncp, start)); \
}
@@ -407,34 +407,34 @@ struct slic_oasis_eeprom {
};
struct slic_stats {
- u64 rx_packets;
- u64 rx_bytes;
- u64 rx_mcasts;
- u64 rx_errors;
- u64 tx_packets;
- u64 tx_bytes;
+ u64_stats_t rx_packets;
+ u64_stats_t rx_bytes;
+ u64_stats_t rx_mcasts;
+ u64_stats_t rx_errors;
+ u64_stats_t tx_packets;
+ u64_stats_t tx_bytes;
/* HW STATS */
- u64 rx_buff_miss;
- u64 tx_dropped;
- u64 irq_errs;
+ u64_stats_t rx_buff_miss;
+ u64_stats_t tx_dropped;
+ u64_stats_t irq_errs;
/* transport layer */
- u64 rx_tpcsum;
- u64 rx_tpoflow;
- u64 rx_tphlen;
+ u64_stats_t rx_tpcsum;
+ u64_stats_t rx_tpoflow;
+ u64_stats_t rx_tphlen;
/* ip layer */
- u64 rx_ipcsum;
- u64 rx_iplen;
- u64 rx_iphlen;
+ u64_stats_t rx_ipcsum;
+ u64_stats_t rx_iplen;
+ u64_stats_t rx_iphlen;
/* link layer */
- u64 rx_early;
- u64 rx_buffoflow;
- u64 rx_lcode;
- u64 rx_drbl;
- u64 rx_crc;
- u64 rx_oflow802;
- u64 rx_uflow802;
+ u64_stats_t rx_early;
+ u64_stats_t rx_buffoflow;
+ u64_stats_t rx_lcode;
+ u64_stats_t rx_drbl;
+ u64_stats_t rx_crc;
+ u64_stats_t rx_oflow802;
+ u64_stats_t rx_uflow802;
/* oasis only */
- u64 tx_carrier;
+ u64_stats_t tx_carrier;
struct u64_stats_sync syncp;
};
diff --git a/drivers/net/ethernet/alacritech/slicoss.c b/drivers/net/ethernet/alacritech/slicoss.c
index f62851708d4f..7488fb6ace0b 100644
--- a/drivers/net/ethernet/alacritech/slicoss.c
+++ b/drivers/net/ethernet/alacritech/slicoss.c
@@ -378,8 +378,8 @@ static void slic_xmit_complete(struct slic_device *sdev)
smp_wmb();
u64_stats_update_begin(&sdev->stats.syncp);
- sdev->stats.tx_bytes += bytes;
- sdev->stats.tx_packets += frames;
+ u64_stats_add(&sdev->stats.tx_bytes, bytes);
+ u64_stats_add(&sdev->stats.tx_packets, frames);
u64_stats_update_end(&sdev->stats.syncp);
netif_tx_lock(dev);
@@ -615,8 +615,8 @@ static void slic_handle_receive(struct slic_device *sdev, unsigned int todo,
}
u64_stats_update_begin(&sdev->stats.syncp);
- sdev->stats.rx_bytes += bytes;
- sdev->stats.rx_packets += frames;
+ u64_stats_add(&sdev->stats.rx_bytes, bytes);
+ u64_stats_add(&sdev->stats.rx_packets, frames);
u64_stats_update_end(&sdev->stats.syncp);
slic_refill_rx_queue(sdev, GFP_ATOMIC);
--
2.51.0
On Fri, 23 Jan 2026 02:51:07 +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. Eric, could you comment if this matters? I expect David may send a non-trivial number of these, I want to make sure we're making good use of everyone's time here. 64b accesses are not torn on 64b arches, and never used for control flow.
On Mon, Jan 26, 2026 at 12:23 AM Jakub Kicinski <kuba@kernel.org> wrote: > > On Fri, 23 Jan 2026 02:51:07 +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. > > Eric, could you comment if this matters? I expect David may send a > non-trivial number of these, I want to make sure we're making good > use of everyone's time here. 64b accesses are not torn on 64b arches, > and never used for control flow. I added u64_stats_add()/u64_stats_inc() back in 2019, and never bothered sending dozens of patches. Presumably compilers could be really dumb back then, I am not sure this is still the case today.
On Mon, 26 Jan 2026 11:11:09 +0100 Eric Dumazet <edumazet@google.com> wrote: > On Mon, Jan 26, 2026 at 12:23 AM Jakub Kicinski <kuba@kernel.org> wrote: > > > > On Fri, 23 Jan 2026 02:51:07 +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. > > > > Eric, could you comment if this matters? I expect David may send a > > non-trivial number of these, I want to make sure we're making good > > use of everyone's time here. 64b accesses are not torn on 64b arches, > > and never used for control flow. > > I added u64_stats_add()/u64_stats_inc() back in 2019, and never bothered > sending dozens of patches. > > Presumably compilers could be really dumb back then, I am not sure > this is still the case today. > gcc still generates 'crap code' for var_64 += var_32 on x86-32. Basically it zero-extends then does a 64bit add rather than using 'adc $0, %reg_hi', the extra register is likely to force a spill to stack. But that is 'fixed' by using add_u64_u32(). Oh and you really don't want to support adding a signed 32bit value for one place that wants to do a subtract. David
© 2016 - 2026 Red Hat, Inc.