免费注册 查看新帖 |

Chinaunix

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

[网络子系统] 有关netpoll的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
发表于 2013-02-25 21:21 |显示全部楼层
30可用积分
本帖最后由 chishanmingshen 于 2013-02-25 21:41 编辑

from 3.7.0

1.
  1. static void netpoll_poll_dev(struct net_device *dev)
  2. {
  3.         const struct net_device_ops *ops;
  4.         struct netpoll_info *ni = rcu_dereference_bh(dev->npinfo);

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

  7.         ops = dev->netdev_ops;
  8.         if (!ops->ndo_poll_controller)<-------------提前跳出了?!
  9.                 return;

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

  12.         poll_napi(dev);<-----------------------此处为何在netpoll实例不需要收包时跳过?

  13.         (以下省略部分代码)
  14. }

复制代码
既然调用poll_napi()可以释放部分内存,为何在netpoll实例不需要收包时跳过??



2.

  1. /* call with IRQ disabled */
  2. void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb,
  3.                              struct net_device *dev)
  4. {
  5.         int status = NETDEV_TX_BUSY;
  6.         unsigned long tries;
  7.         const struct net_device_ops *ops = dev->netdev_ops;
  8.         /* It is up to the caller to keep npinfo alive. */
  9.         struct netpoll_info *npinfo;

  10.         WARN_ON_ONCE(!irqs_disabled());

  11.         npinfo = rcu_dereference_bh(np->dev->npinfo);
  12.         if (!npinfo || !netif_running(dev) || !netif_device_present(dev)) {
  13.                 __kfree_skb(skb);
  14.                 return;
  15.         }

  16.         /* don't get messages out of order, and no recursion */
  17.         if (skb_queue_len(&npinfo->txq) == 0 && !netpoll_owner_active(dev)) {<--------此处为何要判断队列为空这个条件?
  18.                 struct netdev_queue *txq;

  19.                 txq = netdev_pick_tx(dev, skb);

  20.                 /* try until next clock tick */
  21.                 for (tries = jiffies_to_usecs(1)/USEC_PER_POLL;
  22.                      tries > 0; --tries) {
  23.                         if (__netif_tx_trylock(txq)) {
  24.                                 if (!netif_xmit_stopped(txq)) {
  25.                                         if (vlan_tx_tag_present(skb) &&
  26.                                             !(netif_skb_features(skb) & NETIF_F_HW_VLAN_TX)) {
  27.                                                 skb = __vlan_put_tag(skb, vlan_tx_tag_get(skb));
  28.                                                 if (unlikely(!skb))
  29.                                                         break;
  30.                                                 skb->vlan_tci = 0;
  31.                                         }

  32.                                         status = ops->ndo_start_xmit(skb, dev);
  33.                                         if (status == NETDEV_TX_OK)
  34.                                                 txq_trans_update(txq);
  35.                                 }
  36.                                 __netif_tx_unlock(txq);

  37.                                 if (status == NETDEV_TX_OK)
  38.                                         break;

  39.                         }

  40.                         /* tickle device maybe there is some cleanup */
  41.                         netpoll_poll_dev(np->dev);

  42.                         udelay(USEC_PER_POLL);
  43.                 }

  44.                 WARN_ONCE(!irqs_disabled(),
  45.                         "netpoll_send_skb_on_dev(): %s enabled interrupts in poll (%pF)\n",
  46.                         dev->name, ops->ndo_start_xmit);

  47.         }

  48.         if (status != NETDEV_TX_OK) {
  49.                 skb_queue_tail(&npinfo->txq, skb);
  50.                 schedule_delayed_work(&npinfo->tx_work,0);
  51.         }
  52. }
复制代码
为何要加上队列为空这个条件?



疑惑的2个问题,请高手指点,谢谢先!!!

最佳答案

查看完整内容

我的理解:正常工作模式:网卡硬件触发中断,软件介入之后,到驱动这一层的时候,会首先应答一下网卡,比如读,清中断控制,状态寄存器,然后处理正事,NAPI正式介入干活。poll模式呢,不依赖中断的模式:管你有没有中断,先应答一下网卡,然后处理正事,就像中断模式一样。这里面“应答”这个动作就被单拎出来,包装出一个ndo_poll_controller的接口,其他的都一样。所以,这个接口是否实现就比较重要了,实现了,说明驱动支持pol ...

论坛徽章:
0
发表于 2013-02-25 21:21 |显示全部楼层
我的理解:
正常工作模式:网卡硬件触发中断,软件介入之后,到驱动这一层的时候,会首先应答一下网卡,比如读,清中断控制,状态寄存器,然后处理正事,NAPI正式介入干活。

poll模式呢,不依赖中断的模式:管你有没有中断,先应答一下网卡,然后处理正事,就像中断模式一样。

这里面“应答”这个动作就被单拎出来,包装出一个ndo_poll_controller的接口,其他的都一样。所以,这个接口是否实现就比较重要了,实现了,说明驱动支持poll模式,没实现就不支持。就不要再继续干活了,于是就直接退出,而不是强行调用napi接口。

个人理解,欢迎斧正。

论坛徽章:
0
发表于 2013-02-26 13:42 |显示全部楼层
前面注释写了啊,
skb_queue_len(&npinfo->txq) == 0  避免 消息乱序
&& !netpoll_owner_active(dev)   避免递归嵌套


如果队列不为空,说明前面还有数据包还没发送出去,要先发完前面的包,才能发送现在的包,不然顺序就乱了。
那个for循环里面就是马上把包发出去。

前面还有一个 queue_process  函数,那个会处理这恶搞队列里面的包的。

论坛徽章:
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
发表于 2013-02-26 15:04 |显示全部楼层
哦。明白了。谢谢!

就是说这个分支:(skb_queue_len(&npinfo->txq) == 0 && !netpoll_owner_active(dev))
其实没有也行,有它仅仅是提高了一点发包效率。

我理解没错吧,那么1楼的第1个问题如何理解呢?

回复 2# hmsghnh


   

论坛徽章:
0
发表于 2013-02-27 14:43 |显示全部楼层
关于第一个问题:

ops->ndo_poll_controller 是用来“主动”处理“中断”事件的。poll模式么,不依赖你中断了,无论如何,先poll一下controller。

poll_napi(dev) 这个呢,就是用来实际干活的,poll模式下主动干活的程序段。这个呢,逻辑上是要依赖于上面这个controller的操作的。当然,实际上很多驱动实现中,这个函数功能上不依赖controller,但是逻辑上还是依赖的。你都没有实现对controller的poll,剩下的咱们也就算了吧,说明人家驱动就没打算让咱们这个干,万一强行poll_napi出了事算谁的?poll还是driver?

论坛徽章:
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
发表于 2013-02-27 15:44 |显示全部楼层
回复 4# 灌水菜鸟

你都没有实现对controller的poll,剩下的咱们也就算了吧,说明人家驱动就没打算让咱们这个干,万一强行poll_napi出了事算谁的?poll还是driver?
----->没明白啊,没有实现controller的poll就不能执行poll_napi()?恕我愚钝,请再指点下吧!





   

论坛徽章:
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
发表于 2013-02-27 21:14 |显示全部楼层
本帖最后由 chishanmingshen 于 2013-02-28 08:24 编辑

尝试理解你说的!谢谢!

看了代码,你说的“应答”:包括读,清中断控制,状态寄存器,还包括将此设备的napi结构体放到sd中吧?!
就是这个:
list_add_tail(&napi->poll_list, &sd->poll_list);


回复 6# 灌水菜鸟


   

论坛徽章:
0
发表于 2013-02-28 11:37 |显示全部楼层
是,这个也是必要的。呵呵,这个还真是没有注意到。只想到控制器的操作了,数据结构的准备确实没想到,多谢了。

论坛徽章:
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
发表于 2013-03-01 11:00 |显示全部楼层
回复 8# 灌水菜鸟


初步了解了,谢谢!

只有支持“应答”才能支持poll(这里是netpoll),尽管很多设备都支持poll。

其实我感觉搞个flag就好理解了。

   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP