824
技术社区[云栖]
网络子系统12_邻居子系统垃圾回收
// 邻居子系统垃圾回收机制:
// 1.异步回收机制:通过定时器,定期检测邻居缓存使用的内存阈值
// 2.同步回收机制:无法分配新neighbour实例时,同步回收内存。
// 同步,异步回收机制的区别:
// 1.同步回收比异步回收更加严格:
// 1.1 回收的数量:同步回收遍历每一个bucket;
// 异步回收接着上次清理的bucket开始,只清理一个bucket
// 1.2 回收的条件:同步回收视没有被引用,非静态配置的邻居项均视为可回收项;
// 异步回收见下3.1
// 2.回收时机不同:
// 2.1 同步回收在分配新邻居项失败时,进行;异步回收定期进行
// 3.任务不同:
// 3.1异步回收机制负责随机化neigh_parms->reachable_time
// 异步回收机制:
// 1.每300HZ随机化邻居协议参数的reachable_time
// 2.使用tbl->hash_chain_gc记录下次gc清理的bucket
// 3.遍历需要清理的bucket
// 3.1 选择合适的清理对象:
// 3.1.1 非用户配置的永久邻居项,没有定时器在运行的邻居项
// 3.1.2 没有被其他子系统引用
// 3.1.3 solicitation请求失败,或者在一段时间内没有被使用过
// 3.2 标记邻居项为dead,释放邻居项
// 4.更新下次gc的到期时间
1.1 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;
//在协议锁的保护下清理
write_lock(&tbl->lock);
//每300HZ随机化邻居参数的reachable_time
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)//与邻居协议相关的调整参数保存在tbl->parms链表中
p->reachable_time =
neigh_rand_reach_time(p->base_reachable_time);
}
//tbl->hash_chain_gc用于记录当前gc运行的bucket链表头
np = &tbl->hash_buckets[tbl->hash_chain_gc];
//更新下次gc运行的bucket链表头号
tbl->hash_chain_gc = ((tbl->hash_chain_gc + 1) & tbl->hash_mask);
while ((n = *np) != NULL) {
unsigned int state;
write_lock(&n->lock);
//当前neighbour的状态
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;//上一次使用时间为上一次确认时间
if (atomic_read(&n->refcnt) == 1 &&//只有hash表引用此邻居项
(state == NUD_FAILED ||//该邻居项solicitation请求失败,邻居项为不可达
time_after(now, n->used + n->parms->gc_staletime))) {//或者邻居项已近一段时间没有被使用过
*np = n->next;
n->dead = 1;//标记该邻居项将被删除,不在使用
write_unlock(&n->lock);
neigh_release(n);//递减当前引用计数,释放邻居项
continue;
}
//解锁neighbour
write_unlock(&n->lock);
next_elt:
np = &n->next;
}
//计算下一次到期时间 expire = (base_reachable_time/2)/(bucket size)
expire = tbl->parms.base_reachable_time >> 1;
expire /= (tbl->hash_mask + 1);
if (!expire)
expire = 1;
//更新gc到期时间
mod_timer(&tbl->gc_timer, now + expire);
write_unlock(&tbl->lock);
}
// 同步回收机制:
// 1.遍历每个bucket
// 1.1 如果邻居项非静态配置,并且没有被其他子系统引用,释放邻居项
// 2.更新neigh_forced_gc时间戳
1.2 static int neigh_forced_gc(struct neigh_table *tbl)
{
int shrunk = 0;
int i;
//在协议表锁的保护下,清理
write_lock_bh(&tbl->lock);
//遍历每一个bucket
for (i = 0; i <= tbl->hash_mask; i++) {
struct neighbour *n, **np;
np = &tbl->hash_buckets[i];
while ((n = *np) != NULL) {
//获取neighbour的锁
write_lock(&n->lock);
//邻居项没有被其他子系统引用
if (atomic_read(&n->refcnt) == 1 &&
!(n->nud_state & NUD_PERMANENT)) {//并且l2地址并非静态配置
*np = n->next;
n->dead = 1;//标记当前neighbour将被删除,不在使用
shrunk = 1;
write_unlock(&n->lock);
neigh_release(n);
continue;
}
write_unlock(&n->lock);
np = &n->next;//下一个
}
}
//更新neigh_forced_gc时间戳
tbl->last_flush = jiffies;
write_unlock_bh(&tbl->lock);
return shrunk;//返回是否有neighbour被释放
}
最后更新:2017-04-03 15:21:56
上一篇:
网络子系统13_邻居子系统状态机
下一篇:
网络子系统11_arp子系统初始化
云栖大会马云成立达摩院,微软携亚马逊发布新AI工具
苹果要求分享SkyDrive应用三成营收 微软不给
一个修行人的故事,梦回 Las Vegas(二)
[Android实例] android多点触摸demo .
《Servlet、JSP和Spring MVC初学指南》——1.11 使用部署描述符
亚云邮件营销软件背后的阿里云平台支持
城市大脑三项技术论文同时入选国际顶级学术会议ACM MM
HTAP数据库 PostgreSQL 场景与性能测试之 43 - (OLTP+OLAP) unlogged table 含索引多表批量写入
《HttpClient官方文档》1.7. Redirect handling 翻译
别了微软Surface