歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> 關於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);

}
 

Copyright © Linux教程網 All Rights Reserved