mptcp: use batch snmp operations in mptcp_seq_show()
authorEric Dumazet <edumazet@google.com>
Thu, 30 Sep 2021 01:03:33 +0000 (18:03 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 30 Sep 2021 13:17:10 +0000 (14:17 +0100)
Using snmp_get_cpu_field_batch() allows for better cpu cache
utilization, especially on hosts with large number of cpus.

Also remove special handling when mptcp mibs where not yet
allocated.

I chose to use temporary storage on the stack to keep this patch simple.
We might in the future use the storage allocated in netstat_seq_show().

Combined with prior patch (inlining snmp_get_cpu_field)
time to fetch and output mptcp counters on a 256 cpu host [1]
goes from 75 usec to 16 usec.

[1] L1 cache size is 32KB, it is not big enough to hold all dataset.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/mptcp/mib.c

index b21ff9b..3240b72 100644 (file)
@@ -72,6 +72,7 @@ bool mptcp_mib_alloc(struct net *net)
 
 void mptcp_seq_show(struct seq_file *seq)
 {
+       unsigned long sum[ARRAY_SIZE(mptcp_snmp_list) - 1];
        struct net *net = seq->private;
        int i;
 
@@ -81,17 +82,13 @@ void mptcp_seq_show(struct seq_file *seq)
 
        seq_puts(seq, "\nMPTcpExt:");
 
-       if (!net->mib.mptcp_statistics) {
-               for (i = 0; mptcp_snmp_list[i].name; i++)
-                       seq_puts(seq, " 0");
-
-               seq_putc(seq, '\n');
-               return;
-       }
+       memset(sum, 0, sizeof(sum));
+       if (net->mib.mptcp_statistics)
+               snmp_get_cpu_field_batch(sum, mptcp_snmp_list,
+                                        net->mib.mptcp_statistics);
 
        for (i = 0; mptcp_snmp_list[i].name; i++)
-               seq_printf(seq, " %lu",
-                          snmp_fold_field(net->mib.mptcp_statistics,
-                                          mptcp_snmp_list[i].entry));
+               seq_printf(seq, " %lu", sum[i]);
+
        seq_putc(seq, '\n');
 }