Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1559140
  • 博文数量: 374
  • 博客积分: 10093
  • 博客等级: 上将
  • 技术积分: 4315
  • 用 户 组: 普通用户
  • 注册时间: 2005-03-21 00:59
文章分类

全部博文(374)

文章存档

2013年(1)

2011年(2)

2010年(10)

2009年(16)

2008年(33)

2007年(146)

2006年(165)

2005年(1)

分类: LINUX

2008-01-31 23:23:02

前不久Linus发布了Linux-2.6.24,这个版本中加入了支持TCP协议的通用Large Receive Offload功能,它通过将多个TCP数据整合在一个skb结构中,并在稍后的某个时刻作为一个大的数据包交付给上层的网络协议栈,以减少上层协议栈处理skb的开销,提高Linux系统接收TCP数据包的能力。

当然,这一切都是需要网卡驱动程序支持的。不过,对于Linux社区来说,并不是什么问题,相信很快就会有大量的网卡驱动程序支持LRO。

要想理解LRO的工作原理,理解sk_buff结构体是必须的,这方面可以参考David S. Miller写的How SKBs work,它详细介绍了sk_buff结构体中每个成员的作用。有一点需要注意,sk_buff最多可以有三种方式保存数据:
  1. 数据被保存在skb->data指向的由kmalloc申请的内存缓冲区中,这个数据区通常被称为线性数据区,数据区的长度可由函数skb_headlen给出。
  2. 数据被保存在紧随于skb线性数据区尾部的共享结构体skb_shared_info中的成员frags所表示的内存页面中,skb_frag_t的数目由nr_frags给出,skb_frags_t中有数据在内存页面中的偏移量和数据区的大小。注意,因为这里直接引用的是内存页面,所以可以在它的基础上实现零拷贝的高效网络。
  3. 数据被保存于skb_shared_info中的成员frag_list所表示的skb分片队列中。
以上数据区在读取的时候是从上往下依此进行的(可以参考函数skb_copy_datagram_iovec的实现),这也就要求保存数据的时候也要按序。

如果理解了以上部分,那么如何将多个skb数据包合并于一个数据包中就比较容易了。lro_receive_skb就是将一个skb表示的数据放在第3种缓冲区中,lro_receive_frags是为那些本身就把数据直接放在内存页面的网卡驱动设计的,它将数据放在第2种缓冲区中。

合并了N个skb的skb,能够一次性通过网络协议栈,而不是N次,对CPU负担的减轻也是很显然的。
阅读(5127) | 评论(8) | 转发(2) |
0

上一篇:

下一篇:回家过年

给主人留下些什么吧!~~

xiaosuo2008-08-14 21:00:19

skb_copy_expand是肯定要有数据拷贝的,而skb_make_writable则只有必要的时候才有拷贝。

chinaunix网友2008-08-14 17:39:02

对不起我实在是没有明白,能不能详细讲解一下 我参考了 yfydz 写的关于 skb_make_writable 的文章,http://blog.chinaunix.net/u/12313/showart_164455.html 他分析的是 2.6.17,与我的内核 2.6.25 有些不同,2.6.25 中没有了 copy_skb 部分,更主要的工作在 __pskb_pull_tail 函数中,该函数可以实现对空间的扩充,是这样的吗? 另外,你的观点恰恰与我相反,是不是指性能会提升?这个又是为什么呢? 刚接触内核不久,很多东西都没入门呢,还请指点一下吧,谢谢了!

xiaosuo2008-08-14 16:50:42

我观点与你恰恰相反。

chinaunix网友2008-08-14 16:39:37

这样的话实现起来好像比原来复杂了很多,性能也会下降很多,是这样的吗?我不是很确定

xiaosuo2008-08-14 15:56:05

参考这个函数: int skb_make_writable(struct sk_buff *skb, unsigned int writable_len)

评论热议
请登录后评论。

登录 注册