Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'u64_stats-introduce-u64_stats_copy'

David Yang says:

====================
u64_stats: Introduce u64_stats_copy()

On 64bit arches, struct u64_stats_sync is empty and provides no help
against load/store tearing. memcpy() should not be considered atomic
against u64 values. Use u64_stats_copy() instead.
====================

Link: https://patch.msgid.link/20260120092137.2161162-1-mmyangfl@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+20 -5
+3 -3
drivers/net/macsec.c
··· 2806 2806 stats = per_cpu_ptr(rx_sc->stats, cpu); 2807 2807 do { 2808 2808 start = u64_stats_fetch_begin(&stats->syncp); 2809 - memcpy(&tmp, &stats->stats, sizeof(tmp)); 2809 + u64_stats_copy(&tmp, &stats->stats, sizeof(tmp)); 2810 2810 } while (u64_stats_fetch_retry(&stats->syncp, start)); 2811 2811 2812 2812 sum->InOctetsValidated += tmp.InOctetsValidated; ··· 2887 2887 stats = per_cpu_ptr(macsec_priv(dev)->secy.tx_sc.stats, cpu); 2888 2888 do { 2889 2889 start = u64_stats_fetch_begin(&stats->syncp); 2890 - memcpy(&tmp, &stats->stats, sizeof(tmp)); 2890 + u64_stats_copy(&tmp, &stats->stats, sizeof(tmp)); 2891 2891 } while (u64_stats_fetch_retry(&stats->syncp, start)); 2892 2892 2893 2893 sum->OutPktsProtected += tmp.OutPktsProtected; ··· 2943 2943 stats = per_cpu_ptr(macsec_priv(dev)->stats, cpu); 2944 2944 do { 2945 2945 start = u64_stats_fetch_begin(&stats->syncp); 2946 - memcpy(&tmp, &stats->stats, sizeof(tmp)); 2946 + u64_stats_copy(&tmp, &stats->stats, sizeof(tmp)); 2947 2947 } while (u64_stats_fetch_retry(&stats->syncp, start)); 2948 2948 2949 2949 sum->OutPktsUntagged += tmp.OutPktsUntagged;
+1 -1
drivers/net/vxlan/vxlan_vnifilter.c
··· 126 126 pstats = per_cpu_ptr(vninode->stats, i); 127 127 do { 128 128 start = u64_stats_fetch_begin(&pstats->syncp); 129 - memcpy(&temp, &pstats->stats, sizeof(temp)); 129 + u64_stats_copy(&temp, &pstats->stats, sizeof(temp)); 130 130 } while (u64_stats_fetch_retry(&pstats->syncp, start)); 131 131 132 132 dest->rx_packets += temp.rx_packets;
+15
include/linux/u64_stats_sync.h
··· 79 79 return local64_read(&p->v); 80 80 } 81 81 82 + static inline void *u64_stats_copy(void *dst, const void *src, size_t len) 83 + { 84 + BUILD_BUG_ON(len % sizeof(u64_stats_t)); 85 + for (size_t i = 0; i < len / sizeof(u64_stats_t); i++) 86 + ((u64 *)dst)[i] = local64_read(&((local64_t *)src)[i]); 87 + return dst; 88 + } 89 + 82 90 static inline void u64_stats_set(u64_stats_t *p, u64 val) 83 91 { 84 92 local64_set(&p->v, val); ··· 118 110 } 119 111 120 112 #else /* 64 bit */ 113 + #include <linux/string.h> 121 114 122 115 typedef struct { 123 116 u64 v; ··· 127 118 static inline u64 u64_stats_read(const u64_stats_t *p) 128 119 { 129 120 return p->v; 121 + } 122 + 123 + static inline void *u64_stats_copy(void *dst, const void *src, size_t len) 124 + { 125 + BUILD_BUG_ON(len % sizeof(u64_stats_t)); 126 + return memcpy(dst, src, len); 130 127 } 131 128 132 129 static inline void u64_stats_set(u64_stats_t *p, u64 val)
+1 -1
net/bridge/br_multicast.c
··· 5201 5201 5202 5202 do { 5203 5203 start = u64_stats_fetch_begin(&cpu_stats->syncp); 5204 - memcpy(&temp, &cpu_stats->mstats, sizeof(temp)); 5204 + u64_stats_copy(&temp, &cpu_stats->mstats, sizeof(temp)); 5205 5205 } while (u64_stats_fetch_retry(&cpu_stats->syncp, start)); 5206 5206 5207 5207 mcast_stats_add_dir(tdst.igmp_v1queries, temp.igmp_v1queries);