VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   30 Branches   50 Tags
author: Sebastian Andrzej Siewior <bigeasy@linutronix.de> 2021-10-21 11:59:19 +0200 committer: Minda Chen <minda.chen@starfivetech.com> 2023-11-06 19:24:41 +0800 commit: 49fb2135758539bd8eab4bd98114553ad51d42a1 parent: 5492024383cd0f51f4b30937517d8ebe601fbaa0
Commit Summary:
net: stats: Read the statistics in ___gnet_stats_copy_basic() instead of adding.
Diffstat:
1 file changed, 33 insertions, 5 deletions
diff --git a/net/core/gen_stats.c b/net/core/gen_stats.c
index 15c270e22c5e..a10335b4ba2d 100644
--- a/net/core/gen_stats.c
+++ b/net/core/gen_stats.c
@@ -171,20 +171,51 @@ void gnet_stats_add_basic(struct gnet_stats_basic_sync *bstats,
 }
 EXPORT_SYMBOL(gnet_stats_add_basic);
 
+static void gnet_stats_read_basic(u64 *ret_bytes, u64 *ret_packets,
+				  struct gnet_stats_basic_sync __percpu *cpu,
+				  struct gnet_stats_basic_sync *b, bool running)
+{
+	unsigned int start;
+
+	if (cpu) {
+		u64 t_bytes = 0, t_packets = 0;
+		int i;
+
+		for_each_possible_cpu(i) {
+			struct gnet_stats_basic_sync *bcpu = per_cpu_ptr(cpu, i);
+			unsigned int start;
+			u64 bytes, packets;
+
+			do {
+				start = u64_stats_fetch_begin_irq(&bcpu->syncp);
+				bytes = u64_stats_read(&bcpu->bytes);
+				packets = u64_stats_read(&bcpu->packets);
+			} while (u64_stats_fetch_retry_irq(&bcpu->syncp, start));
+
+			t_bytes += bytes;
+			t_packets += packets;
+		}
+		*ret_bytes = t_bytes;
+		*ret_packets = t_packets;
+		return;
+	}
+	do {
+		if (running)
+			start = u64_stats_fetch_begin_irq(&b->syncp);
+		*ret_bytes = u64_stats_read(&b->bytes);
+		*ret_packets = u64_stats_read(&b->packets);
+	} while (running && u64_stats_fetch_retry_irq(&b->syncp, start));
+}
+
 static int
 ___gnet_stats_copy_basic(struct gnet_dump *d,
 			 struct gnet_stats_basic_sync __percpu *cpu,
 			 struct gnet_stats_basic_sync *b,
 			 int type, bool running)
 {
-	struct gnet_stats_basic_sync bstats;
 	u64 bstats_bytes, bstats_packets;
 
-	gnet_stats_basic_sync_init(&bstats);
-	gnet_stats_add_basic(&bstats, cpu, b, running);
-
-	bstats_bytes = u64_stats_read(&bstats.bytes);
-	bstats_packets = u64_stats_read(&bstats.packets);
+	gnet_stats_read_basic(&bstats_bytes, &bstats_packets, cpu, b, running);
 
 	if (d->compat_tc_stats && type == TCA_STATS_BASIC) {
 		d->tc_stats.bytes = bstats_bytes;