数据发送时为什么要先在IP层分片再在MAC层线性化SKB
如题linux在进行数据包发送时,在ip曾用ip_fragment对大于MTU的数据包进行分片,在MAC层用dev_queue_xmit发送。dev_queue_xmit中先根据硬件网卡特性判断是否支持GSO,如果不支持则进行线性化处理,即把fraglist中的数据合到第一个SKB 数据区域中,如果支持GSO,则直接交给网卡处理。
我的问题是,为什么要先进行分片,再进行组片?
因为水平有限,理解只能理解到这部分,请大虾解惑,或者给个提示。 网络这块不精通,简单回复一下。有错请大家指出。
这两处的目的是不一样的,ip_fragment是分包,是在不支持GSO,TSO等特性时,按IP协议的要求分包。
而对说dev_queue_xmit对包进行全并,考虑的却是硬件层面的事情,skb_needs_linearize函数的说明说得还是很清楚的:
/*
* Returns true if either:
* 1. skb has frag_list and the device doesn't support FRAGLIST, or
* 2. skb is fragmented and the device does not support SG, or if
* at least one of fragments is in highmem and device does not
* support DMA from it.
*/
从两个角度去看事情,得出不一样的结论,一个词来形容:事与愿违。
回复 2# Tinnal
ip_fragment 和skb_linearize单独的作用很容易理解,疑惑在于为什么内核会先分片又紧接着组片? 处于什么样的考虑这样做的? ip层分片和线性化应该是两个不同的概念,如Tinnal所说,分片是考虑mtu和gso(TSO),将不能一次发送的数据分成多个ip报文。
而线性化,是因为硬件不支持frag_list和SG,所以需要线性化,如果硬件支持,是不需要线性化的,通常的硬件都支持。 回复 3# 紫柳
疑惑在于为什么内核会先分片又紧接着组片?
个人理解
红色的分片主要是MTU,处于Ip层(不考虑内存是否连续,只考虑包的大小)
蓝色的组片主要考虑的是将不连续的内存,组织成连续的内存,处于mac层
以上几位说的都有些道理,我的疑惑就是 为什么内核会先分片又紧接着组片,这样分分组组的不是浪费资源吗?
现在我认为是为了提高性能,当然是在支持聚合分散I/O的前提下。如果不支持聚合分散I/O,才需要在二层线性化处理,才会出现分了又组的情况。 回复 6# 紫柳
一方面,不能因为个别极端情况,去**良好的架构,IP层不应去直接看硬件的差异,软件设计本身应该不断的屏蔽细节,给上层提供更抽象的接口。否则,还不如你在用户态自己去看看硬件情况,该分包就分,不分包就不分呢。
另一方面,因为支持这个特性的硬件是主流,对于非主流的硬件,只能自己去适配。这也符合社区观。因为内核,特别Linux内核,是一个通用系统。
如果你用了这么极品的老网卡,代表你平来对速度要求就是不很苛刻(因为老硬件本身能力就不强)。如果你还是这么难伺候,非要把你家的老爷车开到最快,请自己去改内核代码。
页:
[1]