In order to fix the data-race found by KCSAN, we can use the new u64_stats_t type and its accessors instead of plain u64 fields. This will still generate optimal code for both 32 and 64 bit platforms.
Unified · Split
| @@ -106,8 +106,8 @@ void dev_lstats_read(struct net_device *dev, u64 *packets, u64 *bytes) · 105 unmodified lines | ||
| 106 | 106 | lb_stats = per_cpu_ptr(dev->lstats, i); |
| 107 | 107 | do { |
| 108 | 108 | start = u64_stats_fetch_begin_irq(&lb_stats->syncp); |
| 109 | − tpackets = lb_stats->packets; | |
| 110 | − tbytes = lb_stats->bytes; | |
| 109 | + tpackets = u64_stats_read(&lb_stats->packets); | |
| 110 | + tbytes = u64_stats_read(&lb_stats->bytes); | |
| 111 | 111 | } while (u64_stats_fetch_retry_irq(&lb_stats->syncp, start)); |
| 112 | 112 | *bytes += tbytes; |
| 113 | 113 | *packets += tpackets; |
| @@ -2396,8 +2396,8 @@ struct pcpu_sw_netstats { · 2395 unmodified lines | ||
| 2396 | 2396 | } __aligned(4 * sizeof(u64)); |
| 2397 | 2397 | |
| 2398 | 2398 | struct pcpu_lstats { |
| 2399 | − u64 packets; | |
| 2400 | − u64 bytes; | |
| 2399 | + u64_stats_t packets; | |
| 2400 | + u64_stats_t bytes; | |
| 2401 | 2401 | struct u64_stats_sync syncp; |
| 2402 | 2402 | } __aligned(2 * sizeof(u64)); |
| 2403 | 2403 | |
| @@ -2408,8 +2408,8 @@ static inline void dev_lstats_add(struct net_device *dev, unsigned int len) · 4 unmodified lines | ||
| 2408 | 2408 | struct pcpu_lstats *lstats = this_cpu_ptr(dev->lstats); |
| 2409 | 2409 | |
| 2410 | 2410 | u64_stats_update_begin(&lstats->syncp); |
| 2411 | − lstats->bytes += len; | |
| 2412 | − lstats->packets++; | |
| 2411 | + u64_stats_add(&lstats->bytes, len); | |
| 2412 | + u64_stats_inc(&lstats->packets); | |
| 2413 | 2413 | u64_stats_update_end(&lstats->syncp); |
| 2414 | 2414 | } |
| 2415 | 2415 | |