Linux内核邻居子系统,linux协议栈之邻居子系统(垃圾回收七)

邻居项的垃圾回收

为了避免浪费不必要的存储空间,邻居子系统维护着一套垃圾回收机制,它将失效的或者是长时间末使用的邻居项删除。

回忆一下,在邻居表(neigh_table)中有一个定时器struct timer_list gc_timer结构,我们看它是怎么初始化的。

在neigh_table_init()中

{

….

init_timer(&tbl->gc_timer);

tbl->gc_timer.data= (unsigned long)tbl;

tbl->gc_timer.function = neigh_periodic_timer;

tbl->gc_timer.expires= now + 1;

add_timer(&tbl->gc_timer;

}

在一滴答之后,计时器超时,运行计时器处理函数neigh_periodic_timer()

static void neigh_periodic_timer(unsigned long arg)

{

struct neigh_table *tbl = (struct neigh_table *)arg;

struct neighbour *n, **np;

unsigned long expire, now = jiffies;

NEIGH_CACHE_STAT_INC(tbl, periodic_gc_runs);

write_lock(&tbl->lock);

/*

*periodically recompute ReachableTime from random function

*/

//每300HZ随机初始化REACHABLE状态超时时间

if (time_after(now, tbl->last_rand + 300 * HZ)) {

struct neigh_parms *p;

tbl->last_rand = now;

for (p = &tbl->parms; p; p = p->next)

p->reachable_time =

neigh_rand_reach_time(p->base_reachable_time);

}

//hash_chain_gc在初始化函数中并末处理

//所以,此处为零

np = &tbl->hash_buckets[tbl->hash_chain_gc];

//使hash_chain_gc指向下一项,如过超过最大值hash_mash

//则又返回到初始值

tbl->hash_chain_gc = ((tbl->hash_chain_gc + 1) & tbl->hash_mask);

while ((n = *np) != NULL) {

unsigned int state;

write_lock(&n->lock);

state = n->nud_state;

//如果对应的是静态项,或者正在被计时器初始状态

if (state & (NUD_PERMANENT | NUD_IN_TIMER)) {

write_unlock(&n->lock);

goto next_elt;

}

//如果使用时间超过了被证实时间

//则调整使用时间

if (time_before(n->used, n->confirmed))

n->used = n->confirmed;

//如果引用计数为1,且状态为FAILED,则状其删除,并

//释放其所占的空间

if (atomic_read(&n->refcnt) == 1 &&

(state == NUD_FAILED ||

time_after(now, n->used + n->parms->gc_staletime))) {

*np = n->next;

n->dead = 1;

write_unlock(&n->lock);

neigh_release(n);

continue;

}

write_unlock(&n->lock);

next_elt:

np = &n->next;

}

/* Cycle through all hash buckets every base_reachable_time/2 ticks.

* ARP entry timeouts range from 1/2 base_reachable_time to 3/2

* base_reachable_time.

*/

//调整定时器到时时间

expire = tbl->parms.base_reachable_time >> 1;

expire /= (tbl->hash_mask + 1);

if (!expire)

expire = 1;

//修改定时器

mod_timer(&tbl->gc_timer, now + expire);

write_unlock(&tbl->lock);

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值