aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/proc.c
diff options
context:
space:
mode:
authorJia He <hejianet@gmail.com>2016-09-29 23:29:00 -0400
committerDavid S. Miller <davem@davemloft.net>2016-09-30 01:50:44 -0400
commit4a4857b1c81ef39a9dc719af6b498cd39d1c1eb0 (patch)
treea69e8313270b72e664467324532def60db621c11 /net/ipv6/proc.c
parentf22d5c490990ecb6f4eb70c4ed478fc8cea78fe1 (diff)
proc: Reduce cache miss in snmp6_seq_show
This is to use the generic interfaces snmp_get_cpu_field{,64}_batch to aggregate the data by going through all the items of each cpu sequentially. Signed-off-by: Jia He <hejianet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/proc.c')
-rw-r--r--net/ipv6/proc.c30
1 files changed, 22 insertions, 8 deletions
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index 679253d0af84..cc8e3ae9ca73 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -30,6 +30,11 @@
30#include <net/transp_v6.h> 30#include <net/transp_v6.h>
31#include <net/ipv6.h> 31#include <net/ipv6.h>
32 32
33#define MAX4(a, b, c, d) \
34 max_t(u32, max_t(u32, a, b), max_t(u32, c, d))
35#define SNMP_MIB_MAX MAX4(UDP_MIB_MAX, TCP_MIB_MAX, \
36 IPSTATS_MIB_MAX, ICMP_MIB_MAX)
37
33static int sockstat6_seq_show(struct seq_file *seq, void *v) 38static int sockstat6_seq_show(struct seq_file *seq, void *v)
34{ 39{
35 struct net *net = seq->private; 40 struct net *net = seq->private;
@@ -191,25 +196,34 @@ static void snmp6_seq_show_item(struct seq_file *seq, void __percpu *pcpumib,
191 atomic_long_t *smib, 196 atomic_long_t *smib,
192 const struct snmp_mib *itemlist) 197 const struct snmp_mib *itemlist)
193{ 198{
199 unsigned long buff[SNMP_MIB_MAX];
194 int i; 200 int i;
195 unsigned long val;
196 201
197 for (i = 0; itemlist[i].name; i++) { 202 if (pcpumib) {
198 val = pcpumib ? 203 memset(buff, 0, sizeof(unsigned long) * SNMP_MIB_MAX);
199 snmp_fold_field(pcpumib, itemlist[i].entry) : 204
200 atomic_long_read(smib + itemlist[i].entry); 205 snmp_get_cpu_field_batch(buff, itemlist, pcpumib);
201 seq_printf(seq, "%-32s\t%lu\n", itemlist[i].name, val); 206 for (i = 0; itemlist[i].name; i++)
207 seq_printf(seq, "%-32s\t%lu\n",
208 itemlist[i].name, buff[i]);
209 } else {
210 for (i = 0; itemlist[i].name; i++)
211 seq_printf(seq, "%-32s\t%lu\n", itemlist[i].name,
212 atomic_long_read(smib + itemlist[i].entry));
202 } 213 }
203} 214}
204 215
205static void snmp6_seq_show_item64(struct seq_file *seq, void __percpu *mib, 216static void snmp6_seq_show_item64(struct seq_file *seq, void __percpu *mib,
206 const struct snmp_mib *itemlist, size_t syncpoff) 217 const struct snmp_mib *itemlist, size_t syncpoff)
207{ 218{
219 u64 buff64[SNMP_MIB_MAX];
208 int i; 220 int i;
209 221
222 memset(buff64, 0, sizeof(unsigned long) * SNMP_MIB_MAX);
223
224 snmp_get_cpu_field64_batch(buff64, itemlist, mib, syncpoff);
210 for (i = 0; itemlist[i].name; i++) 225 for (i = 0; itemlist[i].name; i++)
211 seq_printf(seq, "%-32s\t%llu\n", itemlist[i].name, 226 seq_printf(seq, "%-32s\t%llu\n", itemlist[i].name, buff64[i]);
212 snmp_fold_field64(mib, itemlist[i].entry, syncpoff));
213} 227}
214 228
215static int snmp6_seq_show(struct seq_file *seq, void *v) 229static int snmp6_seq_show(struct seq_file *seq, void *v)