免费注册 查看新帖 |

Chinaunix

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

8139网卡驱动问题:如何才能让数据包立即发送 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-06-05 20:59 |只看该作者 |倒序浏览
现象:我在应用层通过8139网卡每隔1ms发送一个数据包,然后在另外一台直连的机子上通过Wireshark接收包,发现这些数据包的时间间隔完全变了,大概十个个左右数据包的时间间隔是us级别的,接着就是隔几十或几百ms才能收到接下来的十个左右的包(间隔也是us级别),这样循环往复。

需求:对于这种时间间隔不定的收包序列在我的应用中是不允许的,包之间的时间误差只能在us级别内。

解决方法:我现在觉得这个只能在驱动层去解决,但看了8139的网卡驱动,不是很确定该如何修改,有下面几个问题需要高手指点一下:

1:将NUM_TX_DESC的值由4改为1,这样是否可以减少发送缓冲数量,使得每个包都能立即发送出去,而不被缓冲?

2:在函数rtl8139_start_xmit里面,我只看到其将要发送的数据内容和长度拷贝到了缓冲和寄存器,不知道这些数据最后是什么时候发送出去的?

3:对于第2个问题,不知道是不是通过rtl8139_interrupt来发送数据的?如果是,那这个iterrupt是什么时候被触发的呢?是不是跟IntrStatus这个寄存器有关?

谢谢!

论坛徽章:
0
2 [报告]
发表于 2010-06-05 23:21 |只看该作者
1. 不行,那个没关系的。改了更差

2。8139TOO.C里。下面这句写了DESCRIPTOR 长度后,网卡就会发包。
RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
1731                   tp->tx_flag | max(len, (unsigned int)ETH_ZLEN));
1732

关于驱动可以参考最后的2个文章。

其实你的根本问题是由于在应用程序层做的。进程有一个调度的问题。即使在你的程序里写个死循环,CPU占用率也不会是100%的。因为内核在定时的把你的进程挂起,然后去执行其他进程。当你的进程处于RUNNING状态时,就可以连续发US级别的包。当你的进程被切换出去后,就会有MS级别的延迟。

知道了这个原因后,你要做的不是改驱动代码,而是自己写个KERNEL MODULE,在里面发数据包。不过KERNEL MODULE也有很多延时函数。如果用UDELAY的话,是个忙等待,可以保证你的要求,但是开销很大。如果用MSLEEP之类的话,再醒过来的时间间隔可能会稍微大一点点。但是开销小。下面的连接是讲这几个DELAY, SLEEP的
http://blog.csdn.net/myleeming/archive/2008/10/21/3118654.aspx

====================================

5、RTL8139网卡驱动程序分析[转]  (转载者:Godbach)
http://linux.chinaunix.net/bbs/v ... p%3Bfilter%3Ddigest

6、改写drivers/net/8139too.c (作者:xiongce )
http://linux.chinaunix.net/bbs/v ... p%3Bfilter%3Ddigest

论坛徽章:
0
3 [报告]
发表于 2010-06-06 21:21 |只看该作者
本帖最后由 yu_single 于 2010-06-06 22:01 编辑

谢谢accessory帮忙分析:)
用户线程的切换开销应该是其中一个原因,但从收包的时序看,应该不是主要原因,因为其中大部分包的时间间隔都是us级别的,而我需要的时间间隔还是要1ms左右(这里“左右”就是指us级别的误差,而所有数据包接收时间的整体偏移几个ms都没关系),这个可能我一开始没写清楚,不好意思。
譬如,我发包时序为:
packet1:1ms   // 这里指packet1在第1ms的时候发出去
packet2:2ms
pcaket3:3ms
pcaket4:4ms
packet5:5ms
packet6:6ms
pcaket7:7ms
pcaket8:8ms

正常收包时序需要是:
packet1:2.01ms   // 这里指packet1在第2.01ms的时候收到,这里1.01ms的延迟可以接受,只要第2个包跟它的间隔差不多是1ms就行
packet2:2.99ms // 第二个包延迟0.99ms也可以接受,因为其同第一个包的时间间隔基本没变。以下同理。
pcaket3:4.01ms
pcaket4:5.1ms
packet5:6.011ms
packet6:7.09ms
pcaket7:8.011ms
pcaket8:9.0ms

但实际的收包时序是(不符合要求的情况):
packet1:2.1ms   // 这里指packet1大概在第2.1ms的时候收到,由于是第一个包,接收时间上没有要求
packet2:4.11ms // 第二个包跟第一个时间间隔差不多有2ms,无法接受
pcaket3:4.21ms // 第三个包跟第二个间隔只有0.1ms,无法接受
pcaket4:4.23ms
packet5:8.011ms
packet6:8.02ms
pcaket7:8.021ms
pcaket8:8.03ms

按照收包的实际情况看,如果仅仅是把用户线程移到内核,我觉得理论上只可能减少第4个和第5包的时间间隔,但无法拉开第2~4包和第5~8个包的接收间隔。还望高手再帮我分析一下原因。谢谢!

论坛徽章:
0
4 [报告]
发表于 2010-06-07 19:33 |只看该作者
问题基本上被定位出来了,原因有二:
(1)我接收包的时候打印的是驱动收到包的时间,跟发包时间是吻合的,但是我应用层实际拿到包的时间已经完全变了(是不规则的,原因应该跟2一样),这时候再发出去,无论发送的多么实时,都发不正确;
(2)即使收包没问题,发包也受到用户线程调度的影响,因为系统的HZ定义为100,也就是用户线程至少10ms调度一次,如果我应用层发包的时间间隔小于10ms,那实际从网卡发出去的包的间隔都将是10ms,当我把间隔改为15ms,实际从网卡发出去的包间隔有时是20ms,有时是30ms(这个我还不知如何解释)。

解决方法:
(1)修改HZ,让它变成1000或更大,但有网友说这会可能使其它内核模块出问题,而且100是内核开发者定的一个数字,应该是最优的了,改大后降低系统性能。
(2)编写内核模块来处理包的转发,不知netfilter能否满足我的要求,因为我的包并不是ip,arp和rarp包。
(3)修改驱动。

目前想先尝试(2),不行再尝试(3)
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP