Chinaunix首页 | 论坛 | 博客
  • 博客访问: 848671
  • 博文数量: 290
  • 博客积分: 511
  • 博客等级: 下士
  • 技术积分: 1590
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-29 13:14
文章分类

全部博文(290)

文章存档

2018年(28)

2017年(19)

2016年(8)

2015年(1)

2014年(14)

2013年(12)

2012年(22)

2011年(186)

分类: LINUX

2013-08-17 14:55:05

原文地址:Large Receive Offload 作者:xiaosuo

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

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

要想理解LRO的工作原理,理解sk_buff结构体是必须的,这方面可以参考写的,它详细介绍了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负担的减轻也是很显然的。
阅读(1265) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~