};
 
 static DECLARE_BITMAP(proto_inuse_idx, PROTO_INUSE_NR);
+
+#ifdef CONFIG_NET_NS
+void sock_prot_inuse_add(struct net *net, struct proto *prot, int val)
+{
+       int cpu = smp_processor_id();
+       per_cpu_ptr(net->core.inuse, cpu)->val[prot->inuse_idx] += val;
+}
+EXPORT_SYMBOL_GPL(sock_prot_inuse_add);
+
+int sock_prot_inuse_get(struct net *net, struct proto *prot)
+{
+       int cpu, idx = prot->inuse_idx;
+       int res = 0;
+
+       for_each_possible_cpu(cpu)
+               res += per_cpu_ptr(net->core.inuse, cpu)->val[idx];
+
+       return res >= 0 ? res : 0;
+}
+EXPORT_SYMBOL_GPL(sock_prot_inuse_get);
+
+static int sock_inuse_init_net(struct net *net)
+{
+       net->core.inuse = alloc_percpu(struct prot_inuse);
+       return net->core.inuse ? 0 : -ENOMEM;
+}
+
+static void sock_inuse_exit_net(struct net *net)
+{
+       free_percpu(net->core.inuse);
+}
+
+static struct pernet_operations net_inuse_ops = {
+       .init = sock_inuse_init_net,
+       .exit = sock_inuse_exit_net,
+};
+
+static __init int net_inuse_init(void)
+{
+       if (register_pernet_subsys(&net_inuse_ops))
+               panic("Cannot initialize net inuse counters");
+
+       return 0;
+}
+
+core_initcall(net_inuse_init);
+#else
 static DEFINE_PER_CPU(struct prot_inuse, prot_inuse);
 
 void sock_prot_inuse_add(struct net *net, struct proto *prot, int val)
        return res >= 0 ? res : 0;
 }
 EXPORT_SYMBOL_GPL(sock_prot_inuse_get);
+#endif
 
 static void assign_proto_idx(struct proto *prot)
 {