Chinaunix首页 | 论坛 | 博客
  • 博客访问: 346395
  • 博文数量: 67
  • 博客积分: 2550
  • 博客等级: 少校
  • 技术积分: 990
  • 用 户 组: 普通用户
  • 注册时间: 2008-09-17 18:24
文章分类

全部博文(67)

文章存档

2011年(6)

2010年(2)

2009年(40)

2008年(19)

我的朋友

分类: 系统运维

2011-03-17 17:27:48

scatter/gather i/o机制: 什么是所谓的sg(简写了), 其实理解起来也比较简单,sg是与block dma相对应的一种dma方式. 
        在传统dma传输中,要求进行dma操作的起始地址与结束地址之间必须是物理连续的,但有些体系中如ia,连续的存储器地址在物理上不一定是连续的,则对 于这种不连续的dma通常要分多次完成.如果传输完一块物理连续的data后发起一次中断,之后主机再进行下一次传输,这种方式称为block dma.
        sg方式有所不同,它只是用一个链表描述物理地址不连续的存储器,然后把链表首地址告诉dma master,dma master传输完一块物理连续的数据后,就不用再发中断了,而根据链表传输下一块物理连续的数据,最后再发起一次中断.当然要想使用sg机制网卡设备必 须支持sg特性才行.之后我们来了解下这个链表是什么?回想第2章讲sk_buff结构时提到的skb_shinfo(skb)中有一个 skb_frag_t frags[],这个frags数组就起到了这个链表的作用,数组frags中保存了3个变量;page指针指向了该不连续数据块所在的物理页面地址, page_offset指明了该数据块的起始地址在该页面中的偏移量,而size 表示该数据块的大小. 这样该不连续数据块中的第一块用frags[0]表示,第二块用frags[1]表示....以此类推  最后用nr_frags变量表示该数据块的分块个数.当然这个个数也不是无限大的 最大不能超过MAX_SKB_FRAGS个. 
了解了 frags[]之后 我们再来说说skb_shinfo中另一个结构frag_list, 虽然名字相似,但作用却不一样, frags[]的出现完全是因为scatter/gather i/o机制,另一方面说如果网卡硬件不支持sg,那frags[]基本就不会用到了. frag_list是一个buffer list 用于连接各个分包的 说到分包就会想到mtu,这么说吧 数据流从l4层下来,在l3层做的其中一步工作就是将超过mtu大小的数据进行预先拆分,举个例子 mtu为500  从l4层下来的数据为1500, l3层把这1500数据切成3份,建立3个sk_buff  只有第一sk_buff带l4层头部,另外两个sk_buff依次连接到frag_list上.再举个例子.mtu还是500,从l4层下来的数据流分3 次达到l3层,大小分别是100,200,500,因为前两个数据包小于mtu,所以l3层会将数据包重新组织为连续的(因为我们要进行dma操作 block dma方式 ),将前两个数据包经过一次复制合为一个大小为300的sk_buff,而为第3个数据包重新分配一个sk_buff并连入前面那个(1 2合成的)sk_buff的frag_list中(当然还是第一sk_buff带l4头部,第二个不带).但此时如果网卡支持sg特性,那么l3层根本不 需要重组数据块,首先为第一个数据包建立一个大小为100的sk_buff,然后把第二个数据包的页面信息记录到第一个sk_buff的frag[0] 中,当然仍然为第三个数据包分配一个sk_buff链接到第一个sk_buff的frag_list中(因为100+200+500>500了), 此时我们就看出了scatter/gather i/o特性的好处:减少了copy操作.
对于使用scatter/gather i/o是否可以提高性能 我们可以看看下面这几句对话:
  Q:    1 一次dma可以收到多个报文吗?
         2 如果收到多个报文,这些报文需要连续存放吗?
        说的是接收 发送反过来
  A:  yy 那么用不用sg都能理解
        yn 不用sg就太傻了
        n.. 用sg就太傻了
ok 如果此时你已理解scatter/gather i/o,frag[],frag_list那么我们接下来看看msg_more标志
msg_more 标志是应用程序传给l4层的,告知它接下来我会立即发送更多的数据, 这个msg_more对于l3层有很大的用处 ;举个例子 mtu还是500, 发送的数据包还是分三次100 200 500但是打上了msg_more, 此时l3层首先分配一个大小为500的sk_buff,将100 200 复制到这个sk_buff中,当500的数据包到来时 l3将其拆分为2部分 200 ,300, 把200的数据拷贝到上面那个sk_buff中,并新建一个大小为500的sk_buff 把剩余的300数据复制到这个sk_buff里(这里 我们与上面的例子对照可能看不出msg_more的好处 但如果三个数据包下来的循序是100 500 200那...)
sake更好的理解 我们看下面几幅图:
1)fragmentation without scatter/gather i/o ,no msg_more
 
2)fragmentation without scatter/gather i/o ,with msg_more
 
3)fragmentation with sg
 
4)fragmentaion without sg
 
下面转入本章正题  l4 l3层都有哪些协议能下发数据(当然通常发送数据的是上层的应用程序,但总之也要经过l4 l3的)   udp  icmp  rawip  tcp sctp igmp 这些协议均可进行下发,而按所经过的l3层函数的不同 可分为如下几类
在了解这些函数之前 先来简要说下socket数据结构
上层要想发起一次网络传输 会首先建立起一个socket结构 该结构包含源 目的ip地址,ip option, packet id,ttl等私有信息 结构如下;
struct inet_sock{
       struct  sock sk;
       ....
       struct {
       } cork;
}
在 l3层分配sk_buff时 将其socket信息与该buffer建立链接  skb->sk(要建立起这样一个概念 一个socket可以对应多个buffer,诸多buffer公用一个socket, 因此在l3层分配buffer时会用到该socket中的私有信息)
阅读(2651) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~