4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal fw@strlen.de
commit 4d31eef5176df06f218201bc9c0ce40babb41660 upstream.
On SMP we overload the packet counter (unsigned long) to contain percpu offset. Hide this from callers and pass xt_counters address instead.
Preparation patch to allocate the percpu counters in page-sized batch chunks.
Signed-off-by: Florian Westphal fw@strlen.de Acked-by: Eric Dumazet edumazet@google.com Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- include/linux/netfilter/x_tables.h | 6 +----- net/ipv4/netfilter/arp_tables.c | 4 ++-- net/ipv4/netfilter/ip_tables.c | 4 ++-- net/ipv6/netfilter/ip6_tables.c | 5 ++--- net/netfilter/x_tables.c | 9 +++++++++ 5 files changed, 16 insertions(+), 12 deletions(-)
--- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -395,11 +395,7 @@ static inline unsigned long xt_percpu_co
return 0; } -static inline void xt_percpu_counter_free(u64 pcnt) -{ - if (nr_cpu_ids > 1) - free_percpu((void __percpu *) (unsigned long) pcnt); -} +void xt_percpu_counter_free(struct xt_counters *cnt);
static inline struct xt_counters * xt_get_this_cpu_counter(struct xt_counters *cnt) --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -540,7 +540,7 @@ find_check_entry(struct arpt_entry *e, c err: module_put(t->u.kernel.target->me); out: - xt_percpu_counter_free(e->counters.pcnt); + xt_percpu_counter_free(&e->counters);
return ret; } @@ -628,7 +628,7 @@ static inline void cleanup_entry(struct if (par.target->destroy != NULL) par.target->destroy(&par); module_put(par.target->me); - xt_percpu_counter_free(e->counters.pcnt); + xt_percpu_counter_free(&e->counters); }
/* Checks and translates the user-supplied table segment (held in --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -701,7 +701,7 @@ find_check_entry(struct ipt_entry *e, st cleanup_match(ematch, net); }
- xt_percpu_counter_free(e->counters.pcnt); + xt_percpu_counter_free(&e->counters);
return ret; } @@ -797,7 +797,7 @@ cleanup_entry(struct ipt_entry *e, struc if (par.target->destroy != NULL) par.target->destroy(&par); module_put(par.target->me); - xt_percpu_counter_free(e->counters.pcnt); + xt_percpu_counter_free(&e->counters); }
/* Checks and translates the user-supplied table segment (held in --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -713,7 +713,7 @@ find_check_entry(struct ip6t_entry *e, s cleanup_match(ematch, net); }
- xt_percpu_counter_free(e->counters.pcnt); + xt_percpu_counter_free(&e->counters);
return ret; } @@ -808,8 +808,7 @@ static void cleanup_entry(struct ip6t_en if (par.target->destroy != NULL) par.target->destroy(&par); module_put(par.target->me); - - xt_percpu_counter_free(e->counters.pcnt); + xt_percpu_counter_free(&e->counters); }
/* Checks and translates the user-supplied table segment (held in --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c @@ -1592,6 +1592,15 @@ void xt_proto_fini(struct net *net, u_in } EXPORT_SYMBOL_GPL(xt_proto_fini);
+void xt_percpu_counter_free(struct xt_counters *counters) +{ + unsigned long pcnt = counters->pcnt; + + if (nr_cpu_ids > 1) + free_percpu((void __percpu *)pcnt); +} +EXPORT_SYMBOL_GPL(xt_percpu_counter_free); + static int __net_init xt_net_init(struct net *net) { int i;