免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5037 | 回复: 11
打印 上一主题 下一主题

[网络子系统] 请教netpoll_poll_dev()的流程和机制 [复制链接]

论坛徽章:
4
酉鸡
日期:2014-03-21 23:19:50狮子座
日期:2014-08-01 22:11:40酉鸡
日期:2015-01-10 21:31:442015年辞旧岁徽章
日期:2015-03-03 16:54:15
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-01-19 20:04 |只看该作者 |倒序浏览
10可用积分
本帖最后由 chishanmingshen 于 2013-01-26 16:01 编辑

请教netpoll_poll_dev()的流程和机制
代码没看明白...求教~~~

from 2.6.36

  1. void netpoll_poll_dev(struct net_device *dev)
  2. {
  3.         const struct net_device_ops *ops;

  4.         if (!dev || !netif_running(dev))
  5.                 return;

  6.         ops = dev->netdev_ops;
  7.         if (!ops->ndo_poll_controller)
  8.                 return;

  9.         /* Process pending work on NIC */
  10.         ops->ndo_poll_controller(dev);

  11.         poll_napi(dev);

  12.         service_arp_queue(dev->npinfo);

  13.         zap_completion_queue();
  14. }
复制代码

最佳答案

查看完整内容

回复 7# chishanmingshen netpoll_send_udp()主要实现的通过netpoll方式来发送netconsole的udp数据包,利用netpoll方法目的是让内核在网络和I/O子系统尚不能完整可用时,依然能发送和接收数据包。从接收队列里获取的是本地cpu通过完成发送且等待释放数据包队列sd->completion_queue(记住是发送的,不是接收的,只是sd数据结构里保存了这个队列)。

论坛徽章:
0
2 [报告]
发表于 2013-01-19 20:04 |只看该作者
回复 7# chishanmingshen
netpoll_send_udp()主要实现的通过netpoll方式来发送netconsole的udp数据包,利用netpoll方法目的是让内核在网络和I/O子系统尚不能完整可用时,依然能发送和接收数据包。从接收队列里获取的是本地cpu通过完成发送且等待释放数据包队列sd->completion_queue(记住是发送的,不是接收的,只是sd数据结构里保存了这个队列)。

论坛徽章:
0
3 [报告]
发表于 2013-01-22 15:21 |只看该作者
看不懂问题能给分么?呵呵。

论坛徽章:
4
酉鸡
日期:2014-03-21 23:19:50狮子座
日期:2014-08-01 22:11:40酉鸡
日期:2015-01-10 21:31:442015年辞旧岁徽章
日期:2015-03-03 16:54:15
4 [报告]
发表于 2013-01-22 15:56 |只看该作者
就是这个函数的这2行是什么意思/机制?
      
  ops->ndo_poll_controller(dev);
  poll_napi(dev);


回复 2# 灌水菜鸟


   

论坛徽章:
0
5 [报告]
发表于 2013-01-23 13:23 |只看该作者
ops->ndo_poll_controller(dev); // ---(1)
poll_napi(dev); // ---(2)
(1) 这里的ops->ndo_poll_controller()主要做网卡的poll工作,该操作一般都是在关中断的行为下进行的网卡收发中断处理、或者网卡状态统计等。可以进行网卡数据包的依赖于网卡的具体实现,可以在网卡驱动里找到相应的处理函数。
(2)实现网卡轮询网卡的发送队列链表。

论坛徽章:
4
酉鸡
日期:2014-03-21 23:19:50狮子座
日期:2014-08-01 22:11:40酉鸡
日期:2015-01-10 21:31:442015年辞旧岁徽章
日期:2015-03-03 16:54:15
6 [报告]
发表于 2013-01-23 13:41 |只看该作者
能结合netconsole阐述么?有2处被调用:
1. netpoll_send_udp()->netpoll_send_skb()->netpoll_send_skb_on_dev()->netpoll_poll_dev()
2. netpoll_send_udp()->find_skb()->netpoll_poll_dev()

我觉得构造好udp包直接发送不就行了,此处为何如此复杂?
求指点.没看懂...

回复 4# frogsu


   

论坛徽章:
0
7 [报告]
发表于 2013-01-24 00:02 |只看该作者
本帖最后由 frogsu 于 2013-01-24 00:09 编辑

Netconsole提供了一种通过网络监控调试信息的便捷的方法,它使用了工作队列的机制,可以安全的工作在中断上下文中。
netpoll_send_udp函数主要完成了网络监控调试信息的udp包的生成和发送。在这个函数里,两次调用利用到了netpoll_poll_dev()函数,以find_skb()函数进行如下分析:
  1. static struct sk_buff *find_skb(struct netpoll *np, int len, int reserve)
  2. {
  3.         int count = 0;
  4.         struct sk_buff *skb;
  5.         zap_completion_queue();  /*获取本地cpu的softnet_data结构,对完成发送的数据包等待释放的队列sd->completion_queue进行释放skb */
  6.         refill_skbs(); /* 确保skb缓冲池的长度不小于MAX_SKBS */
  7. repeat:
  8.         skb = alloc_skb(len, GFP_ATOMIC);
  9.         if (!skb)
  10.                 skb = skb_dequeue(&skb_pool); /*分配失败则从缓冲池里取*/
  11.         if (!skb) {
  12.                 if (++count < 10) {
  13.                         netpoll_poll_dev(np->dev);  /*缓冲池也空了,则调用netpoll_poll_dev()函数轮询并处理网卡的收发的数据,
  14.                                              * 并释放发送完成的skb,以便有更多的内存空间。*/
  15.                         goto repeat;
  16.                 }
  17.                 return NULL;
  18.         }
  19.         atomic_set(&skb->users, 1);
  20.         skb_reserve(skb, reserve);
  21.         return skb;
  22. }
复制代码
至于你觉得构造好udp包直接发送不就行了,此处为何如此复杂?
从代码里面也可以看到其实netpoll_send_udp()函数里,有很多是关于清skb空间以及netpoll方法来实现udp包的发送,这估计跟系统的netconsole有关吧,因为netconsole要经常发送监控且数据量较小的UDP数据包,并且得能工作于系统于系统crash或者中断不使能的情况下,而netpoll工作模式刚好适应这些特征,因而没有直接调用发送,而是加入了netpoll操作,最后才调用了dev->hard_start_xmit函数.如下图所示:

论坛徽章:
4
酉鸡
日期:2014-03-21 23:19:50狮子座
日期:2014-08-01 22:11:40酉鸡
日期:2015-01-10 21:31:442015年辞旧岁徽章
日期:2015-03-03 16:54:15
8 [报告]
发表于 2013-01-24 08:38 |只看该作者
你是说这里的复杂操作都是在保证能获取到skb空间?
加速发送,从而获得这部分空间可以理解.那为何还能从接收队列中获取?感觉加速接收会导致更快地耗尽skb空间啊?

请指点,谢谢!
回复 6# frogsu


   

论坛徽章:
0
9 [报告]
发表于 2013-01-25 11:09 |只看该作者
frogsu 说的很清楚了吧。

简单的说,你不用netpoll的话,网络包只是被加到队列里面去。并没有真正的发送到远端机器上去。
用netpoll呢,就直接调用了底层驱动的就诶口,真正的保证这个发下去的包是被马上发送到远端机器的。

netpoll用在这里明显可以保证console的响应能及时的处理。 像 frogsu 说的那样,
中断禁止环境下也可以用你的终端能及时的显示输出。

论坛徽章:
4
酉鸡
日期:2014-03-21 23:19:50狮子座
日期:2014-08-01 22:11:40酉鸡
日期:2015-01-10 21:31:442015年辞旧岁徽章
日期:2015-03-03 16:54:15
10 [报告]
发表于 2013-01-25 21:05 |只看该作者
非常感谢frogsu/hmsghnh两位,明白了。复杂的原因就是要独立出来,同理, netpoll的接收也有独立的函数处理。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP