网络子系统53_ip协议分片重组_内存阈值

//调用路径:ip_defrag->ip_evictor

//	分片重组时,可使用内存上下限:

//		1.sysctl_ipfrag_high_thresh 可用内存上限

//		2.sysctl_ipfrag_low_thresh 内存超过上限后,需要释放内存到此限

1.1 static void ip_evictor(void)

{

	struct ipq *qp;

	struct list_head *tmp;

	int work;

	//计算需要释放的内存

	work = atomic_read(&ip_frag_mem) - sysctl_ipfrag_low_thresh;

	if (work <= 0)

		return;



	while (work > 0) {

		read_lock(&ipfrag_lock);

		if (list_empty(&ipq_lru_list)) {//最近最久没有没有被使用的链表,链表头的ipq最久没有被使用

			read_unlock(&ipfrag_lock);

			return;

		}

		//在获取锁的情况下,释放ipq

		tmp = ipq_lru_list.next;

		qp = list_entry(tmp, struct ipq, lru_list);

		atomic_inc(&qp->refcnt);//增加ipq的引用计数,防止其突然消失

		read_unlock(&ipfrag_lock);



		spin_lock(&qp->lock);

		if (!(qp->last_in&COMPLETE))//ipq没有接收完全

			ipq_kill(qp);//

		spin_unlock(&qp->lock);



		ipq_put(qp, &work);

		IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS);

	}

}

//调用路径:ip_evictor->ipq_kill

1.2 static void ipq_kill(struct ipq *ipq)

{

	if (del_timer(&ipq->timer))//删除ipq的定时器

		atomic_dec(&ipq->refcnt);//递减定时器持有的引用计数



	if (!(ipq->last_in & COMPLETE)) {//ipq没有接收完全

		ipq_unlink(ipq);//将ipq从ipq hash表bucket的链表上摘下来

		atomic_dec(&ipq->refcnt);//递减ipq hash表bucket对其持有的引用计数

		ipq->last_in |= COMPLETE;//标记ipq接收完全,防止其被更新

	}

}



1.3 static __inline__ void ipq_put(struct ipq *ipq, int *work)

{

	if (atomic_dec_and_test(&ipq->refcnt))//递减在ip_evictor中对ipq的引用

		ip_frag_destroy(ipq, work);//释放关联到此ipq的skb

}



1.4 static void ip_frag_destroy(struct ipq *qp, int *work)

{

	struct sk_buff *fp;

	//此ipq接收到的所有分片

	fp = qp->fragments;

	while (fp) {

		struct sk_buff *xp = fp->next;



		frag_kfree_skb(fp, work);//释放skb,从work中减去此skb的大小

		fp = xp;

	}



	frag_free_queue(qp, work);//释放ipq结构

}


你可能感兴趣的:(内存)