实际上,网卡驱动的确非常棘手。rtl8139驱动,我也是调试了好多天才工作正常,另外lan100驱动我以前写了一个效率非常高的版本,只是经常出现丢包现象,然后又重新写了一个非常简化的版本(命名为lan100too.c)。
另外,我这里有一个Admtek983B的网卡,我曾经运行过一次,小包能否ping通,大包就不行。因为有rtl8139,所以这个问题就没有深究。
这么看来,重新实现dev_alloc_skb非常有必要。你现在有过实现吗?我今天晚上抽时间想想该如何实现。然后通过交流一下。
谢谢!
On Wed, 10 Jun 2009 18:35:28 +0800, duwenyong <duwe...@foxmail.com>
wrote:
struct iphdr *iph = skb->nh.iph;/** Initialise the virtual path cache for the packet. It describes* how the packet travels inside Linux networking.*/if (likely(skb->dst == NULL)) {int err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos,skb->dev);if (unlikely(err)) {if (err == -EHOSTUNREACH)IP_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS);goto drop;}
#if defined(__LITTLE_ENDIAN_BITFIELD)__u8 ihl:4,version:4;#elif defined (__BIG_ENDIAN_BITFIELD)__u8 version:4,ihl:4;#else#error "Please fix <asm/byteorder.h>"#endif__u8 tos;__u16 tot_len;__u16 id;__u16 frag_off;__u8 ttl;__u8 protocol;__u16 check;__u32 saddr;__u32 daddr;/*The options start here. */
另外,我觉得USB的unaligned问题应该和这个问题还不一样。 只是直觉而已。
谢谢!
On Thu, 11 Jun 2009 12:16:28 +0800, duwenyong <duwe...@foxmail.com>
wrote:
> 如果在定义变量前加 __unaligned 编译器就会自动去处理非对齐的问题,如:
> __unaligned struct iphdr *iph;
> 但由于现在经过CIL转换的,CIL认不出__unaligned
> ,直接报语法错误,编译不了。
> 郭老大,有没有什么好的办法啊。到处都有非对齐的问题的,USB 也有。晕了。
>
>
>
>
> duwenyong
> 2009-06-11
> duwenyong
> 2009-06-11
> duwenyong
> 2009-06-11
抱歉,我将"pragma"说成了"progma"。我错了。
是的__unaligned的确是TCS的一个keyword,在变量或者结构定义的地方添加__unaligned也许可行,但是代价太大,并且无法保证所有的地方都进行了必要的修改。
据我所知,并不是每个体系结构都能够支持unaligned memory
access。到底哪些体系结构支持那些体系结构不支持,看看include/asm-$(arch)/unaligned.h就知道了。正因为有些体系结构不知道unaligned
memory
access。所以,在有些网卡驱动中,通过如下定义来屏蔽网卡驱动的中的某些高级功能(比如zero-copy),参见下面的代码:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
drivers/net/3c59x.c from line 210 to line 219
/* "Knobs" that adjust features and parameters. */
/* Set the copy breakpoint for the copy-only-tiny-frames scheme.
Setting to > 1512 effectively disables this feature. */
#ifndef __arm__
static int rx_copybreak = 200;
#else
/* ARM systems perform better by disregarding the bus-master
transfer capability of these cards. -- rmk */
static int rx_copybreak = 1513;
#endif
如果此网卡驱动运行在ARM系统结构下,则关闭zero-copy功能
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
drivers/net/tulip/de2104x.c from line 66 to line 72
/* Set the copy breakpoint for the copy-only-tiny-buffer Rx structure. */
#if defined(__alpha__) || defined(__arm__) || defined(__hppa__) \
|| defined(__sparc_) || defined(__ia64__) \
|| defined(__sh__) || defined(__mips__)
static int rx_copybreak = 1518;
#else
static int rx_copybreak = 100;
#endif
如果此网卡驱动运行在alpha,arm,hppa等体系结构下,则关闭zero-copy功能,也就是说所有数据包都进行copy。
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
等等,通过查找rx_copybreak定义,还可以发现许多例子。(之所以VIA的网卡驱动没有这样定义,我认为非常有可能是因为这些网卡驱动没有测试充分,可能没有在非x86体系结构下进行测试。当然,这仅仅是猜测而已)
谢谢。
在 Thu, 11 Jun 2009 17:05:51 +0800,duwenyong <duwe...@foxmail.com> 写道:
> 用了这么久,我还真的不知道“progam”确切意思,也查不到这个单词,呵呵。
> 反应 __unaligned就是加在变量前量就行了,我在pSOS下试了,确实可行了。
>
> 但是这样也麻烦啊,要到处加
> __unaligned,而且很多时候我们根本不知道该不该加,如果没有出问题,然后再很痛苦去调试,是根本不知道需不需要给某个变量加
> __unaligned的
>
>
>
>
谢谢!
在 Thu, 11 Jun 2009 17:05:51 +0800,duwenyong <duwe...@foxmail.com> 写道:
> 用了这么久,我还真的不知道“progam”确切意思,也查不到这个单词,呵呵。
> 反应 __unaligned就是加在变量前量就行了,我在pSOS下试了,确实可行了。
>
> 但是这样也麻烦啊,要到处加
> __unaligned,而且很多时候我们根本不知道该不该加,如果没有出问题,然后再很痛苦去调试,是根本不知道需不需要给某个变量加
> __unaligned的
>
>
>
>
1.
如果在编译linux内核的时候,的确添加dlink和C99能否自动解决对齐的问题,那么,修改编译内核是的编译选项,添加dlink和C99,是一个解决方案;
2. 或者,在这些驱动代码中,添加类似的判断
#ifdefine __trimedia__
int rx_copybreak = 5158;
#else
int rx_copybreak = 200;
#endif
这样在trimeida体系结构下禁止zero-copy高级功能。
这两种方法可能都会造成一些效率上的损失,此事古难全。
谢谢!
//如果skb->data的为0x0746290E ,非4对齐,但为2对齐
//那么访问iph->saddr和iph->daddr一定是错的值,但其他变量是正确,因为saddr和daddr是__u32类型,其他都是__16或__u8。
我刚看了TCS的relase
note,可以在安装TCS的目录下看到不仅有include和lib目录,还有另外两个include_dink和lib_dink目录,这两个是新的,如果编译参数增加-dink就会使用include_dink和lib_dink的文件,而不使用include和lib,-dink可以再和-c99参数一起编译,这样对齐的问题应该会解决的。由编译器会去处理非对齐的问题,比如要取得iph->saddr,编译器会就分别取4个byte,然后再拼成一个__u32返回,这样,避免了直接从一个非4对齐的地址取一个__u32的值。但效率应该是变低了。
我还没尝试去这样做,不知道对不对。
在 Thu, 11 Jun 2009 17:05:51 +0800,duwenyong <duwe...@foxmail.com> 写道:
> 用了这么久,我还真的不知道“progam”确切意思,也查不到这个单词,呵呵。
> 反应 __unaligned就是加在变量前量就行了,我在pSOS下试了,确实可行了。
>
> 但是这样也麻烦啊,要到处加
> __unaligned,而且很多时候我们根本不知道该不该加,如果没有出问题,然后再很痛苦去调试,是根本不知道需不需要给某个变量加
> __unaligned的
>
>
>
>
On Fri, 12 Jun 2009 10:14:53 +0800, duwenyong <duwe...@foxmail.com>
wrote:
> 我在pSOS下试了dlink和C99竟然没办法自动解决对齐,晕。不知道我有没有弄错。
> 如果不行,还真的只能定义rx_copybreak 为1518。
>
>
>
>
> duwenyong
> 2009-06-12
我这边关闭了zero-copy,然后ADMTek AN983B网卡工作就非常正常。
当然,我基于MDS MBE板子。
其实linux对网络协议栈及网卡驱动程序优化的考虑,我觉得还是挺到位的。如果你的系统有能力自己处理unaligned
memory access,你就可以自行处理;如果不行,就只有这样了。
个人觉得,是否支持unaligned memory
access,应该主要和编译器后端有关,所以优化编译器后端才是最根本的方法。
linux网络协议栈的确不够优化,所以才有interpeak,targettcp等专业,付费网络协议栈的市场。
On Fri, 12 Jun 2009 11:35:52 +0800, duwenyong <duwe...@foxmail.com>
wrote:
> duwenyong
> 2009-06-12
>
>
>
> 发件人: Guo Hongruan
> 发送时间: 2009-06-12 10:19:59
在 Fri, 12 Jun 2009 15:32:19 +0800,duwenyong <duwe...@foxmail.com> 写道:
> 你上次说到“实际上,网卡驱动的确非常棘手。rtl8139驱动,我也是调试了好多天才工作正常,另外lan100驱动我以前写了一个效率非常高的版本,只是经常出现丢包现象,然后又重新写了一个非常简化的版本(命名为lan100too.c)。”
> 你原来那个高效率的lan100驱动是不是就是使用了zero_copy?
> 我看现有的lan100too.c是没有使用zero_copy的,像rtl8139的。
>
>
>
>
> duwenyong
> 2009-06-12
>
>
>
> 发件人: duwenyong
> 发送时间: 2009-06-12 13:06:02
> 收件人: tmlinux
> 抄送:
> 主题: [tmlinux] Re: Issue 146
> intmlinux:AquestionaboutVIAVT6105&NationalDP83815Ethernet Controller
>
> ADMTek AN983B网卡可以正常工作。
> 可能是卡太久没用,金手指被氧化了,导致PCI IO错误,像皮擦一擦就OK了。
>
>
>
>
> duwenyong
> 2009-06-12
>
>
>
> 发件人: Guo Hongruan
> 发送时间: 2009-06-12 12:05:57
以前的lan100,早就不知道放在那里了。估计找不到了。模仿VIA应该好做,但是也一样是需要copy
skb。
在 Fri, 12 Jun 2009 16:11:06 +0800,duwenyong <duwe...@foxmail.com> 写道:
> 我在HTC
> EDVR板试了LAN100,使用你的lan100too.c驱动,网络是通了,在但是从PC ping
> tmlinux,tmliux就会出现以下错误:
> Badness in __kfree_skb at net/core/skbuff.c:330
> 我调试节,是因为在中断中调用__kfree_skb函数,从而导致WARN_ON
> (in_irq())显示出该错误,虽是仍然能ping通,但过会儿网络效率就变得非常低,ping
> 32字节都要1000ms左右。
>
> 如果从tmlinux ping PC,数据包小一点倒正常,数据包大一些(如4096
> bytes)就会出现需要1000ms左右。再大一些(如102400),同样也出现了
> Badness in __kfree_skb at net/core/skbuff.c:330
>
> 你把你原来那个效率高的lan100驱动共享一下吧,我调试看看。
>
>
>
>
> duwenyong
> 2009-06-12
>
>
>
> 发件人: duwenyong
> 发送时间: 2009-06-12 15:32:43
> 收件人: tmlinux
> 抄送:
> 主题: [tmlinux] Re: Issue
> 146intmlinux:AquestionaboutVIAVT6105&NationalDP83815Ethernet Controller
>
> 你上次说到“实际上,网卡驱动的确非常棘手。rtl8139驱动,我也是调试了好多天才工作正常,另外lan100驱动我以前写了一个效率非常高的版本,只是经常出现丢包现象,然后又重新写了一个非常简化的版本(命名为lan100too.c)。”
> 你原来那个高效率的lan100驱动是不是就是使用了zero_copy?
> 我看现有的lan100too.c是没有使用zero_copy的,像rtl8139的。
>
>
>
>
> duwenyong
> 2009-06-12
>
>
>
> 发件人: duwenyong
> 发送时间: 2009-06-12 13:06:02
> 收件人: tmlinux
> 抄送:
> 主题: [tmlinux] Re: Issue 146
> intmlinux:AquestionaboutVIAVT6105&NationalDP83815Ethernet Controller
>
> ADMTek AN983B网卡可以正常工作。
> 可能是卡太久没用,金手指被氧化了,导致PCI IO错误,像皮擦一擦就OK了。
>
>
>
>
> duwenyong
> 2009-06-12
>
>
>
> 发件人: Guo Hongruan
> 发送时间: 2009-06-12 12:05:57
在 Fri, 12 Jun 2009 17:05:28 +0800,duwenyong <duwe...@foxmail.com> 写道:
> 其实的LAN100是完全可以做到zero_copy的,VIA的不行,因为VIA的要求接收数据的地址必须为4的对齐,由于Ethernet
> Header为14字节,致使IP header没办法4对齐。
> 而LAN100的RX和TX的地址却支持非4对齐,它只要求descriptor的addres必须为4对齐,但descriptor指的数据地址却没有要求(对些,在数据手册上我也找不到有明说,但我在pSOS上使用我们的协议栈来证实了这一点),看来很有必要改一下lan100too.c,让接收地址为2对齐(但一定不能4对齐),这样再加14字节ethernet
> header后,ip header就一定4字节对齐了,效率一定会提高的。
>
>
>
>
> duwenyong
> 2009-06-12
>
>
>
> 发件人: Guo Hongruan
> 发送时间: 2009-06-12 16:18:54
在 Fri, 12 Jun 2009 17:05:28 +0800,duwenyong <duwe...@foxmail.com> 写道:
> 其实的LAN100是完全可以做到zero_copy的,VIA的不行,因为VIA的要求接收数据的地址必须为4的对齐,由于Ethernet
> Header为14字节,致使IP header没办法4对齐。
> 而LAN100的RX和TX的地址却支持非4对齐,它只要求descriptor的addres必须为4对齐,但descriptor指的数据地址却没有要求(对些,在数据手册上我也找不到有明说,但我在pSOS上使用我们的协议栈来证实了这一点),看来很有必要改一下lan100too.c,让接收地址为2对齐(但一定不能4对齐),这样再加14字节ethernet
> header后,ip header就一定4字节对齐了,效率一定会提高的。
>
>
>
>
> duwenyong
> 2009-06-12
>
>
>
> 发件人: Guo Hongruan
> 发送时间: 2009-06-12 16:18:54
git commit -a
git format-patch origin
And then send the patch at the linux source tree to me.
On Sat, 13 Jun 2009 15:44:40 +0800, duwenyong <duwe...@foxmail.com>
wrote:
> 确实,不过,我也确实使用2对齐竟然都很正常。我今天把lan100too.c也改变收发都是2对齐的,ping也能正常。
> 现在的问题是当ping大包的时候,延时很长,不过这个问题在没修改成2对齐前就存在了。
>
> 那个“Badness in __kfree_skb at
> net/core/skbuff.c:330”的问题现在不会出现了。
> 在中断里要调用dev_kfree_skb_irq()函数,好像不里调用dev_kfree_skb()的
>
> 附件是我修改的,还我先使用了
> #define RX_ZERO_COPY 1
> #define TX_ZERO_COPY 1
> 来开启,如果定义为0,就是你原先的。
> 你可以先试下,看在你那里是不是正常的。
> 大数据量的问题我还在找。
>
>
>
>
>
> duwenyong
> 2009-06-13
在psos下你那里的想象也一样吗?
On Sat, 13 Jun 2009 15:44:40 +0800, duwenyong <duwe...@foxmail.com>
wrote:
> 确实,不过,我也确实使用2对齐竟然都很正常。我今天把lan100too.c也改变收发都是2对齐的,ping也能正常。
> 现在的问题是当ping大包的时候,延时很长,不过这个问题在没修改成2对齐前就存在了。
>
> 那个“Badness in __kfree_skb at
> net/core/skbuff.c:330”的问题现在不会出现了。
> 在中断里要调用dev_kfree_skb_irq()函数,好像不里调用dev_kfree_skb()的
>
> 附件是我修改的,还我先使用了
> #define RX_ZERO_COPY 1
> #define TX_ZERO_COPY 1
> 来开启,如果定义为0,就是你原先的。
> 你可以先试下,看在你那里是不是正常的。
> 大数据量的问题我还在找。
>
>
>
>
>
> duwenyong
> 2009-06-13