紫柳 发表于 2014-12-15 10:13

数据发送时为什么要先在IP层分片再在MAC层线性化SKB

如题

linux在进行数据包发送时,在ip曾用ip_fragment对大于MTU的数据包进行分片,在MAC层用dev_queue_xmit发送。dev_queue_xmit中先根据硬件网卡特性判断是否支持GSO,如果不支持则进行线性化处理,即把fraglist中的数据合到第一个SKB 数据区域中,如果支持GSO,则直接交给网卡处理。

我的问题是,为什么要先进行分片,再进行组片?

因为水平有限,理解只能理解到这部分,请大虾解惑,或者给个提示。

Tinnal 发表于 2014-12-15 22:38

网络这块不精通,简单回复一下。有错请大家指出。
这两处的目的是不一样的,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.
*/


从两个角度去看事情,得出不一样的结论,一个词来形容:事与愿违。

紫柳 发表于 2014-12-16 10:19

回复 2# Tinnal


    ip_fragment 和skb_linearize单独的作用很容易理解,疑惑在于为什么内核会先分片又紧接着组片? 处于什么样的考虑这样做的?

humjb_1983 发表于 2014-12-16 15:59

ip层分片和线性化应该是两个不同的概念,如Tinnal所说,分片是考虑mtu和gso(TSO),将不能一次发送的数据分成多个ip报文。
而线性化,是因为硬件不支持frag_list和SG,所以需要线性化,如果硬件支持,是不需要线性化的,通常的硬件都支持。

super皮波 发表于 2014-12-17 14:19

回复 3# 紫柳
疑惑在于为什么内核会先分片又紧接着组片?

个人理解
红色的分片主要是MTU,处于Ip层(不考虑内存是否连续,只考虑包的大小)
蓝色的组片主要考虑的是将不连续的内存,组织成连续的内存,处于mac层




   

紫柳 发表于 2014-12-17 17:59


以上几位说的都有些道理,我的疑惑就是 为什么内核会先分片又紧接着组片,这样分分组组的不是浪费资源吗?

现在我认为是为了提高性能,当然是在支持聚合分散I/O的前提下。如果不支持聚合分散I/O,才需要在二层线性化处理,才会出现分了又组的情况。

Tinnal 发表于 2014-12-17 21:08

回复 6# 紫柳


一方面,不能因为个别极端情况,去**良好的架构,IP层不应去直接看硬件的差异,软件设计本身应该不断的屏蔽细节,给上层提供更抽象的接口。否则,还不如你在用户态自己去看看硬件情况,该分包就分,不分包就不分呢。
另一方面,因为支持这个特性的硬件是主流,对于非主流的硬件,只能自己去适配。这也符合社区观。因为内核,特别Linux内核,是一个通用系统。

如果你用了这么极品的老网卡,代表你平来对速度要求就是不很苛刻(因为老硬件本身能力就不强)。如果你还是这么难伺候,非要把你家的老爷车开到最快,请自己去改内核代码。
页: [1]
查看完整版本: 数据发送时为什么要先在IP层分片再在MAC层线性化SKB