aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2008-03-31 22:42:16 -0400
committerDavid S. Miller <davem@davemloft.net>2008-03-31 22:42:16 -0400
commit70ee115942be6ce52ff10e5e813fb4da82cdb25a (patch)
treeaa3a22dfece765ead70df8f07974e398766b0104
parentc29a0bc4dfc4d833eb702b1929cec96a3eeb9f7a (diff)
[SOCK][NETNS]: Add the percpu prot_inuse counter in the struct net.
Such an accounting would cost us two more dereferences to get the percpu variable from the struct net, so I make sock_prot_inuse_get and _add calls work differently depending on CONFIG_NET_NS - without it old optimized routines are used. The per-cpu counter for init_net is prepared in core_initcall, so that even af_inet, that starts as fs_initcall, will already have the init_net prepared. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/netns/core.h3
-rw-r--r--net/core/sock.c48
2 files changed, 51 insertions, 0 deletions
diff --git a/include/net/netns/core.h b/include/net/netns/core.h
index 0e8c0f8435d4..24d4be76bbd1 100644
--- a/include/net/netns/core.h
+++ b/include/net/netns/core.h
@@ -2,12 +2,15 @@
2#define __NETNS_CORE_H__ 2#define __NETNS_CORE_H__
3 3
4struct ctl_table_header; 4struct ctl_table_header;
5struct prot_inuse;
5 6
6struct netns_core { 7struct netns_core {
7 /* core sysctls */ 8 /* core sysctls */
8 struct ctl_table_header *sysctl_hdr; 9 struct ctl_table_header *sysctl_hdr;
9 10
10 int sysctl_somaxconn; 11 int sysctl_somaxconn;
12
13 struct prot_inuse *inuse;
11}; 14};
12 15
13#endif 16#endif
diff --git a/net/core/sock.c b/net/core/sock.c
index 6f36ab91bb59..83e11f7260ff 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1947,6 +1947,53 @@ struct prot_inuse {
1947}; 1947};
1948 1948
1949static DECLARE_BITMAP(proto_inuse_idx, PROTO_INUSE_NR); 1949static DECLARE_BITMAP(proto_inuse_idx, PROTO_INUSE_NR);
1950
1951#ifdef CONFIG_NET_NS
1952void sock_prot_inuse_add(struct net *net, struct proto *prot, int val)
1953{
1954 int cpu = smp_processor_id();
1955 per_cpu_ptr(net->core.inuse, cpu)->val[prot->inuse_idx] += val;
1956}
1957EXPORT_SYMBOL_GPL(sock_prot_inuse_add);
1958
1959int sock_prot_inuse_get(struct net *net, struct proto *prot)
1960{
1961 int cpu, idx = prot->inuse_idx;
1962 int res = 0;
1963
1964 for_each_possible_cpu(cpu)
1965 res += per_cpu_ptr(net->core.inuse, cpu)->val[idx];
1966
1967 return res >= 0 ? res : 0;
1968}
1969EXPORT_SYMBOL_GPL(sock_prot_inuse_get);
1970
1971static int sock_inuse_init_net(struct net *net)
1972{
1973 net->core.inuse = alloc_percpu(struct prot_inuse);
1974 return net->core.inuse ? 0 : -ENOMEM;
1975}
1976
1977static void sock_inuse_exit_net(struct net *net)
1978{
1979 free_percpu(net->core.inuse);
1980}
1981
1982static struct pernet_operations net_inuse_ops = {
1983 .init = sock_inuse_init_net,
1984 .exit = sock_inuse_exit_net,
1985};
1986
1987static __init int net_inuse_init(void)
1988{
1989 if (register_pernet_subsys(&net_inuse_ops))
1990 panic("Cannot initialize net inuse counters");
1991
1992 return 0;
1993}
1994
1995core_initcall(net_inuse_init);
1996#else
1950static DEFINE_PER_CPU(struct prot_inuse, prot_inuse); 1997static DEFINE_PER_CPU(struct prot_inuse, prot_inuse);
1951 1998
1952void sock_prot_inuse_add(struct net *net, struct proto *prot, int val) 1999void 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)
1966 return res >= 0 ? res : 0; 2013 return res >= 0 ? res : 0;
1967} 2014}
1968EXPORT_SYMBOL_GPL(sock_prot_inuse_get); 2015EXPORT_SYMBOL_GPL(sock_prot_inuse_get);
2016#endif
1969 2017
1970static void assign_proto_idx(struct proto *prot) 2018static void assign_proto_idx(struct proto *prot)
1971{ 2019{