转:http://blog.csdn.net/nerdx/article/details/12884185
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
1.1 static int rt_garbage_collect(void)
-
{
-
-
static unsigned long expire = RT_GC_TIMEOUT;
-
static unsigned long last_gc;
-
static int rover;
-
static int equilibrium;
-
struct rtable *rth, **rthp;
-
unsigned long now = jiffies;
-
int goal;
-
-
-
-
if (now - last_gc < ip_rt_gc_min_interval &&
-
atomic_read(&ipv4_dst_ops.entries) < ip_rt_max_size) {
-
RT_CACHE_STAT_INC(gc_ignored);
-
goto out;
-
}
-
-
-
goal = atomic_read(&ipv4_dst_ops.entries) -
-
(ip_rt_gc_elasticity << rt_hash_log);
-
-
-
if (goal <= 0) {
-
if (equilibrium < ipv4_dst_ops.gc_thresh)
-
equilibrium = ipv4_dst_ops.gc_thresh;
-
-
goal = atomic_read(&ipv4_dst_ops.entries) - equilibrium;
-
-
if (goal > 0) {
-
-
equilibrium += min_t(unsigned int, goal / 2, rt_hash_mask + 1);
-
-
goal = atomic_read(&ipv4_dst_ops.entries) - equilibrium;
-
}
-
-
} else {
-
-
goal = max_t(unsigned int, goal / 2, rt_hash_mask + 1);
-
-
equilibrium = atomic_read(&ipv4_dst_ops.entries) - goal;
-
}
-
-
if (now - last_gc >= ip_rt_gc_min_interval)
-
last_gc = now;
-
-
-
if (goal <= 0) {
-
equilibrium += goal;
-
goto work_done;
-
}
-
-
do {
-
int i, k;
-
-
for (i = rt_hash_mask, k = rover; i >= 0; i--) {
-
-
-
unsigned long tmo = expire;
-
-
k = (k + 1) & rt_hash_mask;
-
-
rthp = &rt_hash_table[k].chain;
-
spin_lock_bh(&rt_hash_table[k].lock);
-
while ((rth = *rthp) != NULL) {
-
-
if (!rt_may_expire(rth, tmo, expire)) {
-
-
tmo >>= 1;
-
rthp = &rth->u.rt_next;
-
continue;
-
}
-
*rthp = rth->u.rt_next;
-
rt_free(rth);
-
goal--;
-
}
-
spin_unlock_bh(&rt_hash_table[k].lock);
-
if (goal <= 0)
-
break;
-
}
-
rover = k;
-
-
if (goal <= 0)
-
goto work_done;
-
-
if (expire == 0)
-
break;
-
-
expire >>= 1;
-
-
-
if (atomic_read(&ipv4_dst_ops.entries) < ip_rt_max_size)
-
goto out;
-
} while (!in_softirq() && time_before_eq(jiffies, now));
-
-
if (atomic_read(&ipv4_dst_ops.entries) < ip_rt_max_size)
-
goto out;
-
return 1;
-
-
work_done:
-
expire += ip_rt_gc_min_interval;
-
if (expire > ip_rt_gc_timeout ||
-
atomic_read(&ipv4_dst_ops.entries) < ipv4_dst_ops.gc_thresh)
-
expire = ip_rt_gc_timeout;
-
-
out: return 0;
-
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
2.1 static void rt_check_expire(unsigned long dummy)
-
{
-
static int rover;
-
int i = rover, t;
-
struct rtable *rth, **rthp;
-
unsigned long now = jiffies;
-
-
for (t = ip_rt_gc_interval << rt_hash_log; t >= 0;
-
-
t -= ip_rt_gc_timeout) {
-
unsigned long tmo = ip_rt_gc_timeout;
-
-
i = (i + 1) & rt_hash_mask;
-
rthp = &rt_hash_table[i].chain;
-
-
spin_lock(&rt_hash_table[i].lock);
-
while ((rth = *rthp) != NULL) {
-
-
if (rth->u.dst.expires) {
-
-
if (time_before_eq(now, rth->u.dst.expires)) {
-
-
tmo >>= 1;
-
rthp = &rth->u.rt_next;
-
continue;
-
}
-
-
} else if (!rt_may_expire(rth, tmo, ip_rt_gc_timeout)) {
-
tmo >>= 1;
-
rthp = &rth->u.rt_next;
-
continue;
-
}
-
-
-
*rthp = rth->u.rt_next;
-
rt_free(rth);
-
}
-
spin_unlock(&rt_hash_table[i].lock);
-
-
if (time_after(jiffies, now))
-
break;
-
}
-
rover = i;
-
-
mod_timer(&rt_periodic_timer, now + ip_rt_gc_interval);
-
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
3.1 static int rt_may_expire(struct rtable *rth, unsigned long tmo1, unsigned long tmo2)
-
{
-
unsigned long age;
-
int ret = 0;
-
-
if (atomic_read(&rth->u.dst.__refcnt))
-
goto out;
-
-
ret = 1;
-
if (rth->u.dst.expires &&
-
time_after_eq(jiffies, rth->u.dst.expires))
-
goto out;
-
-
age = jiffies - rth->u.dst.lastuse;
-
ret = 0;
-
if ((age <= tmo1 && !rt_fast_clean(rth)) ||
-
(age <= tmo2 && rt_valuable(rth)))
-
goto out;
-
ret = 1;
-
out: return ret;
-
}
-
阅读(878) | 评论(0) | 转发(0) |