|
@@ -1947,6 +1947,53 @@ struct prot_inuse {
|
|
|
};
|
|
|
|
|
|
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)
|
|
@@ -1966,6 +2013,7 @@ int sock_prot_inuse_get(struct net *net, struct proto *prot)
|
|
|
return res >= 0 ? res : 0;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(sock_prot_inuse_get);
|
|
|
+#endif
|
|
|
|
|
|
static void assign_proto_idx(struct proto *prot)
|
|
|
{
|