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中的私有信息)
阅读(2724) | 评论(0) | 转发(1) |