| From f09a77d4fb46651e4ea38e7b1843aa92f8d41c27 Mon Sep 17 00:00:00 2001 |
| From: Thomas Gleixner <tglx@linutronix.de> |
| Date: Tue, 27 Apr 2010 10:05:28 +0200 |
| Subject: [PATCH] net: Fix iptables get_counters() |
| |
| commit 863c3ad87b10617464fc52c21fc7e31987910559 in tip. |
| |
| The preempt-rt changes to iptables get_counters() left the counters |
| array uninitialized which results in random packet statistic numbers. |
| |
| Reported-by: prd.gtt@operamail.com |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| |
| diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c |
| index 1c33431..5f6042e 100644 |
| --- a/net/ipv4/netfilter/ip_tables.c |
| +++ b/net/ipv4/netfilter/ip_tables.c |
| @@ -906,7 +906,7 @@ get_counters(const struct xt_table_info *t, |
| struct ipt_entry *iter; |
| unsigned int cpu; |
| unsigned int i; |
| - unsigned int curcpu = NR_CPUS; |
| + unsigned int curcpu; |
| |
| /* Instead of clearing (by a previous call to memset()) |
| * the counters and using adds, we set the counters |
| @@ -916,16 +916,17 @@ get_counters(const struct xt_table_info *t, |
| * if new softirq were to run and call ipt_do_table |
| */ |
| local_bh_disable(); |
| -#ifndef CONFIG_PREEMPT_RT |
| - curcpu = smp_processor_id(); |
| + curcpu = raw_smp_processor_id(); |
| |
| i = 0; |
| + xt_info_wrlock(curcpu); |
| xt_entry_foreach(iter, t->entries[curcpu], t->size) { |
| SET_COUNTER(counters[i], iter->counters.bcnt, |
| iter->counters.pcnt); |
| ++i; |
| } |
| -#endif |
| + xt_info_wrunlock(curcpu); |
| + |
| for_each_possible_cpu(cpu) { |
| if (cpu == curcpu) |
| continue; |
| diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c |
| index 6d5b78b..ff7ce7b 100644 |
| --- a/net/ipv6/netfilter/ip6_tables.c |
| +++ b/net/ipv6/netfilter/ip6_tables.c |
| @@ -936,7 +936,7 @@ get_counters(const struct xt_table_info *t, |
| struct ip6t_entry *iter; |
| unsigned int cpu; |
| unsigned int i; |
| - unsigned int curcpu = NR_CPUS; |
| + unsigned int curcpu; |
| |
| /* Instead of clearing (by a previous call to memset()) |
| * the counters and using adds, we set the counters |
| @@ -946,17 +946,17 @@ get_counters(const struct xt_table_info *t, |
| * if new softirq were to run and call ipt_do_table |
| */ |
| local_bh_disable(); |
| - |
| -#ifndef CONFIG_PREEMPT_RT |
| - curcpu = smp_processor_id(); |
| + curcpu = raw_smp_processor_id(); |
| |
| i = 0; |
| + xt_info_wrlock(curcpu); |
| xt_entry_foreach(iter, t->entries[curcpu], t->size) { |
| SET_COUNTER(counters[i], iter->counters.bcnt, |
| iter->counters.pcnt); |
| ++i; |
| } |
| -#endif |
| + xt_info_wrunlock(curcpu); |
| + |
| for_each_possible_cpu(cpu) { |
| if (cpu == curcpu) |
| continue; |
| -- |
| 1.7.1.1 |
| |