cpumask: use percpu allocations instead of arrays in IPv4

Instead of allocating an nr_cpu_ids array, most places should be using
percpu_alloc().  This doesn't waste space if cpu numbers aren't
contiguous.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
 include/net/netns/ipv4.h |    2 +-
 net/ipv4/icmp.c          |   19 +++++++++----------
 2 files changed, 10 insertions(+), 11 deletions(-)

diff -r 88b5980eaf70 include/net/netns/ipv4.h
--- a/include/net/netns/ipv4.h	Thu Oct 23 00:39:36 2008 +1100
+++ b/include/net/netns/ipv4.h	Thu Oct 23 00:39:45 2008 +1100
@@ -28,7 +28,7 @@ struct netns_ipv4 {
 	struct hlist_head	*fib_table_hash;
 	struct sock		*fibnl;
 
-	struct sock		**icmp_sk;
+	struct sock		**icmp_sk_pcpu;
 	struct sock		*tcp_sock;
 
 	struct netns_frags	frags;
diff -r 88b5980eaf70 net/ipv4/icmp.c
--- a/net/ipv4/icmp.c	Thu Oct 23 00:39:36 2008 +1100
+++ b/net/ipv4/icmp.c	Thu Oct 23 00:39:45 2008 +1100
@@ -201,7 +201,7 @@ static const struct icmp_control icmp_po
  */
 static struct sock *icmp_sk(struct net *net)
 {
-	return net->ipv4.icmp_sk[smp_processor_id()];
+	return *percpu_ptr(net->ipv4.icmp_sk, smp_processor_id());
 }
 
 static inline struct sock *icmp_xmit_lock(struct net *net)
@@ -1136,18 +1136,17 @@ static void __net_exit icmp_sk_exit(stru
 	int i;
 
 	for_each_possible_cpu(i)
-		inet_ctl_sock_destroy(net->ipv4.icmp_sk[i]);
-	kfree(net->ipv4.icmp_sk);
-	net->ipv4.icmp_sk = NULL;
+		inet_ctl_sock_destroy(*percpu_ptr(net->ipv4.icmp_sk_pcpu, i));
+	free_percpu(net->ipv4.icmp_sk_pcpu);
+	net->ipv4.icmp_sk_pcpu = NULL;
 }
 
 static int __net_init icmp_sk_init(struct net *net)
 {
 	int i, err;
 
-	net->ipv4.icmp_sk =
-		kzalloc(nr_cpu_ids * sizeof(struct sock *), GFP_KERNEL);
-	if (net->ipv4.icmp_sk == NULL)
+	net->ipv4.icmp_sk_pcpu = alloc_percpu(struct sock **);
+	if (net->ipv4.icmp_sk_pcpu == NULL)
 		return -ENOMEM;
 
 	for_each_possible_cpu(i) {
@@ -1158,7 +1157,7 @@ static int __net_init icmp_sk_init(struc
 		if (err < 0)
 			goto fail;
 
-		net->ipv4.icmp_sk[i] = sk;
+		*percpu_ptr(net->ipv4.icmp_sk_pcpu, i) = sk;
 
 		/* Enough space for 2 64K ICMP packets, including
 		 * sk_buff struct overhead.
@@ -1196,8 +1195,8 @@ static int __net_init icmp_sk_init(struc
 
 fail:
 	for_each_possible_cpu(i)
-		inet_ctl_sock_destroy(net->ipv4.icmp_sk[i]);
-	kfree(net->ipv4.icmp_sk);
+		inet_ctl_sock_destroy(*percpu_ptr(net->ipv4.icmp_sk_pcpu, i));
+	free_percpu(net->ipv4.icmp_sk_pcpu);
 	return err;
 }
 
