[Devel,RHEL7,COMMIT] net: Iterate only online cpus in __snmp6_fill_stats64()

Submitted by Konstantin Khorenko on Sept. 13, 2016, 11:39 a.m.

Details

Message ID 201609131139.u8DBdZn2024367@finist_cl7.x64_64.work.ct
State New
Series "Series without cover letter"
Headers show

Commit Message

Konstantin Khorenko Sept. 13, 2016, 11:39 a.m.
The commit is pushed to "branch-rh7-3.10.0-327.28.2.vz7.17.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-327.28.2.vz7.17.6
------>
commit 65ef8afa5d88966609a8bc650fa947f9597a1ef4
Author: Kirill Tkhai <ktkhai@virtuozzo.com>
Date:   Tue Sep 13 15:39:35 2016 +0400

    net: Iterate only online cpus in __snmp6_fill_stats64()
    
    Customers complain, they have a very slow getifaddrs() on their 32-cpu server
    comparing to a 4-cpu test machine. They provided a test for measuring of that
    (see https://jira.sw.ru/browse/PSBM-50993).
    
    Server has 32 online and 192 possible cpus:
    
    SMP: Allowing 192 CPUs, 160 hotplug CPUs
    ...
    NR_CPUS:4096 nr_cpumask_bits:192 nr_cpu_ids:192 nr_node_ids:2
    
    Investigation shows, using nr_cpus=32 boot parameter improves the results
    in 6.5 times. This parameter does not make a cpu offline, just decreases
    number of possible cpus.
    
    Since __snmp6_fill_stats64() calculated data are moved from offline cpu,
    we may iterate only online cpus here. The patch simply do that.
    
    This problem initially happend on 2.6.32, but 3.10 has the same logic,
    so we do the same patch for it.
    
    Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
    Reviewed-by: Andrei Vagin <avagin@virtuozzo.com>
---
 net/ipv6/addrconf.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 5015e41..f5068ba 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -4366,7 +4366,7 @@  static inline void __snmp6_fill_stats64(u64 *stats, void __percpu **mib,
 	/* Use put_unaligned() because stats may not be aligned for u64. */
 	put_unaligned(items, &stats[0]);
 	for (i = 1; i < items; i++)
-		put_unaligned(snmp_fold_field64(mib, i, syncpoff), &stats[i]);
+		put_unaligned(__snmp_fold_field64(mib, i, syncpoff, cpu_online_mask), &stats[i]);
 
 	memset(&stats[items], 0, pad);
 }