diff options
author | Pavel Emelyanov <xemul@openvz.org> | 2008-03-31 22:42:16 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-03-31 22:42:16 -0400 |
commit | 70ee115942be6ce52ff10e5e813fb4da82cdb25a (patch) | |
tree | aa3a22dfece765ead70df8f07974e398766b0104 /net/core/sock.c | |
parent | c29a0bc4dfc4d833eb702b1929cec96a3eeb9f7a (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>
Diffstat (limited to 'net/core/sock.c')
-rw-r--r-- | net/core/sock.c | 48 |
1 files changed, 48 insertions, 0 deletions
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 | ||
1949 | static DECLARE_BITMAP(proto_inuse_idx, PROTO_INUSE_NR); | 1949 | static DECLARE_BITMAP(proto_inuse_idx, PROTO_INUSE_NR); |
1950 | |||
1951 | #ifdef CONFIG_NET_NS | ||
1952 | void 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 | } | ||
1957 | EXPORT_SYMBOL_GPL(sock_prot_inuse_add); | ||
1958 | |||
1959 | int 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 | } | ||
1969 | EXPORT_SYMBOL_GPL(sock_prot_inuse_get); | ||
1970 | |||
1971 | static 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 | |||
1977 | static void sock_inuse_exit_net(struct net *net) | ||
1978 | { | ||
1979 | free_percpu(net->core.inuse); | ||
1980 | } | ||
1981 | |||
1982 | static struct pernet_operations net_inuse_ops = { | ||
1983 | .init = sock_inuse_init_net, | ||
1984 | .exit = sock_inuse_exit_net, | ||
1985 | }; | ||
1986 | |||
1987 | static __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 | |||
1995 | core_initcall(net_inuse_init); | ||
1996 | #else | ||
1950 | static DEFINE_PER_CPU(struct prot_inuse, prot_inuse); | 1997 | static DEFINE_PER_CPU(struct prot_inuse, prot_inuse); |
1951 | 1998 | ||
1952 | void sock_prot_inuse_add(struct net *net, struct proto *prot, int val) | 1999 | 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) | |||
1966 | return res >= 0 ? res : 0; | 2013 | return res >= 0 ? res : 0; |
1967 | } | 2014 | } |
1968 | EXPORT_SYMBOL_GPL(sock_prot_inuse_get); | 2015 | EXPORT_SYMBOL_GPL(sock_prot_inuse_get); |
2016 | #endif | ||
1969 | 2017 | ||
1970 | static void assign_proto_idx(struct proto *prot) | 2018 | static void assign_proto_idx(struct proto *prot) |
1971 | { | 2019 | { |