Skip to content

Commit

Permalink
[NETNS][IPV6] ip6_fib - gc timer per namespace
Browse files Browse the repository at this point in the history
Move the timer initialization at the network namespace creation and
store the network namespace in the timer argument.

That enables multiple timers (one per network namespace) to do garbage
collecting.

Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
Signed-off-by: Benjamin Thery <benjamin.thery@bull.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Daniel Lezcano authored and David S. Miller committed Mar 4, 2008
1 parent 450d19f commit 63152fc
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 30 deletions.
2 changes: 1 addition & 1 deletion include/net/ip6_route.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ extern struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
struct in6_addr *addr);
extern int icmp6_dst_gc(int *more);

extern void fib6_force_start_gc(void);
extern void fib6_force_start_gc(struct net *net);

extern struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
const struct in6_addr *addr,
Expand Down
1 change: 1 addition & 0 deletions include/net/netns/ipv6.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ struct netns_ipv6 {
struct xt_table *ip6table_mangle;
struct xt_table *ip6table_raw;
#endif
struct timer_list *ip6_fib_timer;
struct hlist_head *fib_table_hash;
struct fib6_table *fib6_main_tbl;
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
Expand Down
56 changes: 28 additions & 28 deletions net/ipv6/ip6_fib.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,6 @@ static __u32 rt_sernum;

static void fib6_gc_timer_cb(unsigned long arg);

static struct timer_list *ip6_fib_timer;

static struct fib6_walker_t fib6_walker_list = {
.prev = &fib6_walker_list,
.next = &fib6_walker_list,
Expand Down Expand Up @@ -663,19 +661,19 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
return 0;
}

static __inline__ void fib6_start_gc(struct rt6_info *rt)
static __inline__ void fib6_start_gc(struct net *net, struct rt6_info *rt)
{
if (ip6_fib_timer->expires == 0 &&
if (net->ipv6.ip6_fib_timer->expires == 0 &&
(rt->rt6i_flags & (RTF_EXPIRES|RTF_CACHE)))
mod_timer(ip6_fib_timer, jiffies +
init_net.ipv6.sysctl.ip6_rt_gc_interval);
mod_timer(net->ipv6.ip6_fib_timer, jiffies +
net->ipv6.sysctl.ip6_rt_gc_interval);
}

void fib6_force_start_gc(void)
void fib6_force_start_gc(struct net *net)
{
if (ip6_fib_timer->expires == 0)
mod_timer(ip6_fib_timer, jiffies +
init_net.ipv6.sysctl.ip6_rt_gc_interval);
if (net->ipv6.ip6_fib_timer->expires == 0)
mod_timer(net->ipv6.ip6_fib_timer, jiffies +
net->ipv6.sysctl.ip6_rt_gc_interval);
}

/*
Expand Down Expand Up @@ -762,7 +760,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nl_info *info)
err = fib6_add_rt2node(fn, rt, info);

if (err == 0) {
fib6_start_gc(rt);
fib6_start_gc(info->nl_net, rt);
if (!(rt->rt6i_flags&RTF_CACHE))
fib6_prune_clones(pn, rt);
}
Expand Down Expand Up @@ -1443,7 +1441,7 @@ void fib6_run_gc(unsigned long expires, struct net *net)
} else {
local_bh_disable();
if (!spin_trylock(&fib6_gc_lock)) {
mod_timer(ip6_fib_timer, jiffies + HZ);
mod_timer(net->ipv6.ip6_fib_timer, jiffies + HZ);
local_bh_enable();
return;
}
Expand All @@ -1456,11 +1454,11 @@ void fib6_run_gc(unsigned long expires, struct net *net)
fib6_clean_all(net, fib6_age, 0, NULL);

if (gc_args.more)
mod_timer(ip6_fib_timer, jiffies +
mod_timer(net->ipv6.ip6_fib_timer, jiffies +
net->ipv6.sysctl.ip6_rt_gc_interval);
else {
del_timer(ip6_fib_timer);
ip6_fib_timer->expires = 0;
del_timer(net->ipv6.ip6_fib_timer);
net->ipv6.ip6_fib_timer->expires = 0;
}
spin_unlock_bh(&fib6_gc_lock);
}
Expand All @@ -1473,13 +1471,21 @@ static void fib6_gc_timer_cb(unsigned long arg)
static int fib6_net_init(struct net *net)
{
int ret;
struct timer_list *timer;

ret = -ENOMEM;
timer = kzalloc(sizeof(*timer), GFP_KERNEL);
if (!timer)
goto out;

setup_timer(timer, fib6_gc_timer_cb, (unsigned long)net);
net->ipv6.ip6_fib_timer = timer;

net->ipv6.fib_table_hash =
kzalloc(sizeof(*net->ipv6.fib_table_hash)*FIB_TABLE_HASHSZ,
GFP_KERNEL);
if (!net->ipv6.fib_table_hash)
goto out;
goto out_timer;

net->ipv6.fib6_main_tbl = kzalloc(sizeof(*net->ipv6.fib6_main_tbl),
GFP_KERNEL);
Expand Down Expand Up @@ -1513,11 +1519,15 @@ static int fib6_net_init(struct net *net)
#endif
out_fib_table_hash:
kfree(net->ipv6.fib_table_hash);
out_timer:
kfree(timer);
goto out;
}

static void fib6_net_exit(struct net *net)
{
del_timer(net->ipv6.ip6_fib_timer);
kfree(net->ipv6.ip6_fib_timer);
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
kfree(net->ipv6.fib6_local_tbl);
#endif
Expand All @@ -1533,23 +1543,17 @@ static struct pernet_operations fib6_net_ops = {
int __init fib6_init(void)
{
int ret = -ENOMEM;

fib6_node_kmem = kmem_cache_create("fib6_nodes",
sizeof(struct fib6_node),
0, SLAB_HWCACHE_ALIGN,
NULL);
if (!fib6_node_kmem)
goto out;

ret = -ENOMEM;
ip6_fib_timer = kzalloc(sizeof(*ip6_fib_timer), GFP_KERNEL);
if (!ip6_fib_timer)
goto out_kmem_cache_create;

setup_timer(ip6_fib_timer, fib6_gc_timer_cb, (unsigned long)&init_net);

ret = register_pernet_subsys(&fib6_net_ops);
if (ret)
goto out_timer;
goto out_kmem_cache_create;

ret = __rtnl_register(PF_INET6, RTM_GETROUTE, NULL, inet6_dump_fib);
if (ret)
Expand All @@ -1559,17 +1563,13 @@ int __init fib6_init(void)

out_unregister_subsys:
unregister_pernet_subsys(&fib6_net_ops);
out_timer:
kfree(ip6_fib_timer);
out_kmem_cache_create:
kmem_cache_destroy(fib6_node_kmem);
goto out;
}

void fib6_gc_cleanup(void)
{
del_timer(ip6_fib_timer);
kfree(ip6_fib_timer);
unregister_pernet_subsys(&fib6_net_ops);
kmem_cache_destroy(fib6_node_kmem);
}
5 changes: 4 additions & 1 deletion net/ipv6/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -952,7 +952,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
icmp6_dst_gc_list = &rt->u.dst;
spin_unlock_bh(&icmp6_dst_lock);

fib6_force_start_gc();
fib6_force_start_gc(dev->nd_net);

out:
return &rt->u.dst;
Expand Down Expand Up @@ -1230,6 +1230,9 @@ int ip6_route_add(struct fib6_config *cfg)
rt->u.dst.dev = dev;
rt->rt6i_idev = idev;
rt->rt6i_table = table;

cfg->fc_nlinfo.nl_net = dev->nd_net;

return __ip6_ins_rt(rt, &cfg->fc_nlinfo);

out:
Expand Down

0 comments on commit 63152fc

Please sign in to comment.