Skip to content

Commit

Permalink
[SOCK][NETNS]: Add the percpu prot_inuse counter in the struct net.
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
xemul authored and davem330 committed Apr 1, 2008
1 parent c29a0bc commit 70ee115
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 0 deletions.
3 changes: 3 additions & 0 deletions include/net/netns/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@
#define __NETNS_CORE_H__

struct ctl_table_header;
struct prot_inuse;

struct netns_core {
/* core sysctls */
struct ctl_table_header *sysctl_hdr;

int sysctl_somaxconn;

struct prot_inuse *inuse;
};

#endif
48 changes: 48 additions & 0 deletions net/core/sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
{
Expand Down

0 comments on commit 70ee115

Please sign in to comment.