免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5573 | 回复: 6

netif_rx_schedule(&queue->backlog_dev) 疑问 [复制链接]

论坛徽章:
0
发表于 2011-10-17 20:24 |显示全部楼层
当设备第一次注册到poll_list 时,在netif_rx 调用了netif_rx_schedule(&queue->backlog_dev) ,
问: queue->backlog_dev 是什么时候初始化的,它怎么跟对应的sk_buff 联系?

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
发表于 2011-10-18 07:52 |显示全部楼层
回复 1# kgatheko
从你描述的情况看,你所用的内核应该是比较老的内核。
所有先说明你所使用的内核版本,别人才会帮你解决啊。。。

论坛徽章:
0
发表于 2011-10-18 08:42 |显示全部楼层
回复 2# 瀚海书香

2.6.12
我找到不它关联的,望兄台指点

论坛徽章:
0
发表于 2011-10-18 11:26 |显示全部楼层
这里queue->backlog_dev并不是一个实际上存在的网络设备,netif_rx_schedule()只是利用了其中的poll函数而已。

一、问题的背景
这个问题是《深入理解Linux网络技术内幕》中第三部分第九、第十章提到的“在终中断期间处理多帧”的方法netif_rx。
内核代码2.6.12。

二、初始化
net/core/dev.c
3275 static int __init net_dev_init(void)
3303         for (i = 0; i < NR_CPUS; i++) {
3304                 struct softnet_data *queue;
3305
3306                 queue = &per_cpu(softnet_data, i);
3307                 skb_queue_head_init(&queue->input_pkt_queue);
3308                 queue->throttle = 0;
3309                 queue->cng_level = 0;
3310                 queue->avg_blog = 10; /* arbitrary non-zero */
3311                 queue->completion_queue = NULL;
3312                 INIT_LIST_HEAD(&queue->poll_list);
3313                 set_bit(__LINK_STATE_START, &queue->backlog_dev.state);
3314                 queue->backlog_dev.weight = weight_p;
3315                 queue->backlog_dev.poll = process_backlog;
3316                 atomic_set(&queue->backlog_dev.refcnt, 1);
3317         }

这里的意思是有几个CPU,就分配几个softnet_data结构,而每个softnet_data结构都包含一个net_device结构。
所以说这里的backlog_dev并不是实际上存在的网络设备,这里最重要的是初始化backlog_dev的状态:__LINK_STATE_START,
以及poll:process_backlog。

三、netif_rx处理过程
第一次因为接收包发生中断后,关闭中断,进入中断处理函数,此时连续处理接收到的包(这也是在中断期间处理多帧的本质),通过netif_rx()函数将新接收的包链入softdata->input_pkt_data队列上。当没有新包时,中断处理结束,开中断。

当net_rx_action()运行时,调用dev->poll()函数处理接收的包,而因为在net_dev_init()中已经将dev->poll()初始化成process_backlog函数,故转入process_backlog()函数,再调用netif_receive_skb()根据包的类型送入上一层的协议栈。

四、一点题外话——为什么NAPI更好一些?
粗略分起来,一共有四种接收数据包的方法:
1 轮询
2 中断
3 在中断期间处理多帧netif_rx
4 NAPI
其中轮询和中断就是一般操作系统或计算机原理中介绍的方法,他们的优缺点这里就不再重复。
但是网络设备有其自己的特点,它接收数据包的频率有时很高,有时有比较低,这样有必要将中断和轮询的方法结合起来,
当接收数据包频率很高时,主要采用轮询方法,这样可以避免过多的中断影响系统的性能;
当接收数据包频率很低时,主要采用中断方法,这样可以避免轮询消耗太多CPU时间。
可以说是各取其长,各避其短,这是netif_rx和NAPI这两种方法之所以比单纯使用轮询或中断好的原因。
但是为什么NAPI会比netif_rx更好一些呢?
关键在关中断持续的时间长短上。
注意这里的前提是Linux中中断处理函数是非抢占的,不可重入的,也就是说在处理一个中断时,会将本地CPU的所有中断全部关掉。
使用netif_rx方法时,连续处理多个包的操作(操作主要是链入input_pkt_queue队列)是在中断处理函数中进行的,在这期间CPU的中断是关闭的。
而使用NAPI时,连续处理多个包的操作也是在中断处理函数中进行的,但是此时进行的操作很简单,就是将该网络设备加入softnet_data->poll_list中,
并且即使对多个包也只需进行一次。而具体的接收包的操作是在net_rx_action()-->netif_receive_skb()中进行的,此时的执行上下文是软中断,而CPU的中断此时是开启的。所以说NAPI关闭CPU中断持续的时间比netif_rx方法要少一些。

如有不对的地方,请大家指正。

评分

参与人数 1可用积分 +4 收起 理由
瀚海书香 + 4 多谢分享!

查看全部评分

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
发表于 2011-10-18 13:07 |显示全部楼层
回复 3# kgatheko
可以看一下这个帖子http://bbs.chinaunix.net/thread-1960601-1-1.html

论坛徽章:
0
发表于 2011-10-18 13:51 |显示全部楼层
回复 4# panweiping


    多谢!刚刚想明白了,重点是对skb_buff处理!
 backlog_dev这个虚拟设备只是个辅助,决定什么时候调用处理封包函数提交给上层。

论坛徽章:
0
发表于 2011-10-18 13:52 |显示全部楼层
回复 5# 瀚海书香


    多谢大神!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP