【Linux4.1.12源码分析】收包软中断和NAPI

本文深入剖析Linux4.1.12版本中收包软中断的处理,通过`net_rx_action`和`napi_poll`函数探讨内核如何注册backlog到软中断。讲解了`enqueue_to_backlog`函数的工作原理,并指出虽然内核自带的backlog能将中断处理分段,但仍然存在大量中断消耗CPU的问题。文章强调,NAPI驱动通过自定义软中断和poll函数,实现了中断与轮询结合,有效降低了中断次数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

不讲概念,直接上收包软中断处理代码。

 net_rx_action函数

static void net_rx_action(struct softirq_action *h)
{
	struct softnet_data *sd = this_cpu_ptr(&softnet_data);
	unsigned long time_limit = jiffies + 2;		//定义了处理skb的时间不能超过2个时钟中断时间,即2/HZ 秒
	int budget = netdev_budget;	//定义了一次处理skb的数目,系统默认为300
	LIST_HEAD(list);
	LIST_HEAD(repoll);

	local_irq_disable();
	list_splice_init(&sd->poll_list, &list);	//poll链表合并到list,并初始化poll_list
	local_irq_enable();

	for (;;) {
		struct napi_struct *n;

		if (list_empty(&list)) {
			if (!sd_has_rps_ipi_waiting(sd) && list_empty(&repoll))	 
				return;
			break;
		}

		n = list_first_entry(&list, struct napi_struct, poll_list);	//得到第一个napi_struct对象
		budget -= napi_poll(n, &repoll);	//开始poll收包

		/* If softirq window is exhausted then punt.
		 * Allow this to run for 2 jiffies since which will allow
		 * an average latency of 1.5/HZ.
		 */
		if (unlikely(budget <= 0 ||		
			     time_after_eq(jiffies, time_limit))) {	//超过时间或收取的报文数则退出
			sd->time_squeeze++;
			break;
		}
	}

	local_irq_disable();	

	list_splice_tail_init(&sd->poll_list, &list);
	list_splice_tail(&repoll, &list);
	list_splice(&list, &sd->poll_list);
	if (!list_empty(&sd->poll_list))	//如果pol
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值