注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

gmd20的个人空间

// 编程和生活

 
 
 

日志

 
 

Linux内核里面网卡的GSO和TSO功能相关的一点记录  

2014-08-06 09:54:20|  分类: linux相关 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
现在一些网卡可以辅助tcp包的分片和tcp头部校验,这样把tcp的分片推迟到网卡驱动部分去做,结合网卡的scatter-gather list功能,有硬件的支持,一般来说可以提高性能吧。这就就是 large segment offload (LSO)。 如果专门指TCP的又可以叫做TCP segmentation offload (TSO)。 linux内核里面统一叫做Generic Segmentation Offload。

如果网卡驱动支持GSO功能(可以通过ethtool -k  查看), tcp层就可以直接往下面发一个原大于MTU的数据包了。比如virtualbox的virio_net网卡驱动就支持这个功能。使用下面这个systemtap脚本来验证一下。


function is_this:long(name:string)
{
return isinstr(name, @1)
}

probe kernel.function("ip_finish_output")
{
/* if (is_this(execname())) { */
devname = kernel_string($skb->dev->name)
/* if (devname == "eth1") { */
/* printf("%s, %d, %d\n", devname, $skb->len, @cast($skb->end, "skb_shared_info")->gso_size) */
printf("%s, %d, %s\n", devname, $skb->len, @cast($skb->end, "skb_shared_info")$$)
/* printf("%s, %d, %s\n", devname, $skb->len, $skb$$) */
/* } */
/* } */
}

probe begin
{
printf ("ip_finish_output2 probe.\n")
}

probe end
{
printf ("ip_finish_output2 probe end.\n")
}

用iperf测试,可以看到下发的skb的长度达到了65212。
eth1, 65212, {.nr_frags='\003', .tx_flags='\000', .gso_size=1448, .gso_segs=45, .gso_type=1, .frag_list=0x0, .hwtstamps={.hwtstamp={.tv64=0}, .syststamp={.tv64=0}}, .ip6_frag_id=0, .dataref={.counter=65538}, .destructor_arg=0x0, .frags=[{.page={.p=0xf60d2a00}, .page_o

ip_finish_output 函数里面通过 skb_is_gso (就是skb_shared_info的gso_size成员)判断底层网卡是不是支持gso功能,以决定是否还调用ip_fragment 来做ip包分片(如果底层网卡不支持GSO,tcp自己更加PMTU已经做了分片了?)
214 static int ip_finish_output(struct sk_buff *skb)
215 {
216 #if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM)
217 /* Policy lookup after SNAT yielded a new policy */
218 if (skb_dst(skb)->xfrm != NULL) {
219 IPCB(skb)->flags |= IPSKB_REROUTED;
220 return dst_output(skb);
221 }
222 #endif
223 if (skb->len > ip_skb_dst_mtu(skb) && !skb_is_gso(skb))
224 return ip_fragment(skb, ip_finish_output2);
225 else
226 return ip_finish_output2(skb);
227 }

网卡驱动xmit函数里面,也会检查这个gso功能是否启用,然后做skb的计算。
http://lxr.free-electrons.com/source/drivers/net/virtio_net.c 文件里面xmit_skb 函数。e1000网卡驱动也类似。

相关的内核文档:
GSO: Generic Segmentation Offload
http://lwn.net/Articles/188489/
接收方向有类似的技术
net: Generic Receive Offload
http://lwn.net/Articles/311357/

这篇文章也对这个有点介绍
http://www.coverfire.com/articles/queueing-in-the-linux-network-stack/





  评论这张
 
阅读(717)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017