aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/af_inet.c36
-rw-r--r--net/ipv4/proc.c15
2 files changed, 45 insertions, 6 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 640db9b90330..3ceb025b16f2 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1427,6 +1427,42 @@ unsigned long snmp_fold_field(void __percpu *mib[], int offt)
1427} 1427}
1428EXPORT_SYMBOL_GPL(snmp_fold_field); 1428EXPORT_SYMBOL_GPL(snmp_fold_field);
1429 1429
1430#if BITS_PER_LONG==32
1431
1432u64 snmp_fold_field64(void __percpu *mib[], int offt, size_t syncp_offset)
1433{
1434 u64 res = 0;
1435 int cpu;
1436
1437 for_each_possible_cpu(cpu) {
1438 void *bhptr, *userptr;
1439 struct u64_stats_sync *syncp;
1440 u64 v_bh, v_user;
1441 unsigned int start;
1442
1443 /* first mib used by softirq context, we must use _bh() accessors */
1444 bhptr = per_cpu_ptr(SNMP_STAT_BHPTR(mib), cpu);
1445 syncp = (struct u64_stats_sync *)(bhptr + syncp_offset);
1446 do {
1447 start = u64_stats_fetch_begin_bh(syncp);
1448 v_bh = *(((u64 *) bhptr) + offt);
1449 } while (u64_stats_fetch_retry_bh(syncp, start));
1450
1451 /* second mib used in USER context */
1452 userptr = per_cpu_ptr(SNMP_STAT_USRPTR(mib), cpu);
1453 syncp = (struct u64_stats_sync *)(userptr + syncp_offset);
1454 do {
1455 start = u64_stats_fetch_begin(syncp);
1456 v_user = *(((u64 *) userptr) + offt);
1457 } while (u64_stats_fetch_retry(syncp, start));
1458
1459 res += v_bh + v_user;
1460 }
1461 return res;
1462}
1463EXPORT_SYMBOL_GPL(snmp_fold_field64);
1464#endif
1465
1430int snmp_mib_init(void __percpu *ptr[2], size_t mibsize, size_t align) 1466int snmp_mib_init(void __percpu *ptr[2], size_t mibsize, size_t align)
1431{ 1467{
1432 BUG_ON(ptr == NULL); 1468 BUG_ON(ptr == NULL);
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index e320ca6b3ef3..4ae1f203f7cb 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -343,10 +343,12 @@ static int snmp_seq_show(struct seq_file *seq, void *v)
343 IPV4_DEVCONF_ALL(net, FORWARDING) ? 1 : 2, 343 IPV4_DEVCONF_ALL(net, FORWARDING) ? 1 : 2,
344 sysctl_ip_default_ttl); 344 sysctl_ip_default_ttl);
345 345
346 BUILD_BUG_ON(offsetof(struct ipstats_mib, mibs) != 0);
346 for (i = 0; snmp4_ipstats_list[i].name != NULL; i++) 347 for (i = 0; snmp4_ipstats_list[i].name != NULL; i++)
347 seq_printf(seq, " %lu", 348 seq_printf(seq, " %llu",
348 snmp_fold_field((void __percpu **)net->mib.ip_statistics, 349 snmp_fold_field64((void __percpu **)net->mib.ip_statistics,
349 snmp4_ipstats_list[i].entry)); 350 snmp4_ipstats_list[i].entry,
351 offsetof(struct ipstats_mib, syncp)));
350 352
351 icmp_put(seq); /* RFC 2011 compatibility */ 353 icmp_put(seq); /* RFC 2011 compatibility */
352 icmpmsg_put(seq); 354 icmpmsg_put(seq);
@@ -432,9 +434,10 @@ static int netstat_seq_show(struct seq_file *seq, void *v)
432 434
433 seq_puts(seq, "\nIpExt:"); 435 seq_puts(seq, "\nIpExt:");
434 for (i = 0; snmp4_ipextstats_list[i].name != NULL; i++) 436 for (i = 0; snmp4_ipextstats_list[i].name != NULL; i++)
435 seq_printf(seq, " %lu", 437 seq_printf(seq, " %llu",
436 snmp_fold_field((void __percpu **)net->mib.ip_statistics, 438 snmp_fold_field64((void __percpu **)net->mib.ip_statistics,
437 snmp4_ipextstats_list[i].entry)); 439 snmp4_ipextstats_list[i].entry,
440 offsetof(struct ipstats_mib, syncp)));
438 441
439 seq_putc(seq, '\n'); 442 seq_putc(seq, '\n');
440 return 0; 443 return 0;