概述
Table of Contents
109.硬件卸载简介
110.网卡硬件卸载功能
111.DPDK软件接口
接收侧:
发送侧:
112.硬件与软件功能实现
113.VLAN硬件卸载
1. 收包时VLAN Tag的过滤
2. 收包时VLAN Tag的剥离
3. 发包时VLAN Tag的插入
4. 多层VLAN的支持
114.IEEE1588硬件卸载功能
115.IP TCP/UDP/SCTP checksum硬件卸载功能
116.Tunnel硬件卸载功能
分片功能卸载
117.TSO(TCP Segment Offload TCP分片功能的硬件卸载)
组包功能卸载
118.RSC(Receive Side Coalescing,接收方聚合)
119.小结
系列文章
相关阅读
108.第8章讨论了网卡流分类、多队列与并行处理,本章主要介绍以网卡为主的硬件卸载与智能化发展趋势。与软件实现相比,同样的功能如果硬件来做,可以减少CPU的开销。通常,硬件能力强,具有高并发处理特点,有助于大幅提高系统吞吐率与减少时延。按照最流行的说法,软件正在统治这个世界。DPDK这样的软件着力于性能优化,设计之初就会对芯片硬件功能充分挖掘加以利用。协同化的软硬件设计是一个系统优化设计的基石。
硬件加速实现在哪里,是一个有趣的系统问题,可以实现在通用CPU上,也可以实现在芯片组,还可以实现在各种接口卡。和网络数据最直接的接口是网卡,在网卡上进行网络数据卸载是主要思路,也本章的主要专注点。
硬件的缺点在于资源局限,功能固化,一旦设计发布完成,再对功能进行改动就变得非常困难。且硬件的设计与发布时间长,更新周期无法与软件相比。事物发展常有螺旋形态的上升规律,这在软件与硬件的发展过程也是如此。
109.硬件卸载简介
多年来,遵循摩尔定律的发展趋势,硬件的能力提升迅速,在一块小小的网卡上,处理器能够提供的性能已经远远超出了简单的数据包接收转发的需求,这在技术上提供了将许多原先软件实现的功能下移由网卡硬件直接完成的可能。同时,我们可以看到,随着技术的发展,硬件将会提供越来越丰富的功能,从以太网,IP数据报文头部的校验和计算、加解密等功能,发展到对高级协议的分析处理,可以预期,未来硬件直接提供的功能将会占据越来越大的比重。一些成熟的功能更有可能是由硬件而不是软件提供。
对于数据中心服务器,需要处理来自网络中的数据包,解析网络协议,早期受芯片技术限制,网卡功能简单,大量依赖服务器的CPU来处理网络协议,服务器的处理能力被消耗在这些处理任务上。互联网诞生至今,过去25年,以太网接口技术实现了1万倍的飞速跳跃,从10Mbit/s发展到100Gbit/s。随着半导体技术的飞速发展,处理器有越来越强的运算能力,能容纳承载更多的应用,接纳更多的网络数据包构建互联网应用。服务器需要处理来自网络中的大量数据包。同样的半导体技术进步也体现在网卡上,已经可以看到近年来万兆网络在服务器中大量使用。
对于专有网络设备,为了提高处理数据包的速度,数据面和控制面分离是一项常用的技术。简单说,就是复杂的数据包处理进入控制面,进行复杂的控制处理;而在数据面留下简单且类似的包处理,比如:
- ❑查表(路由表,访问控制,ARP,调度队列)。
- ❑报文校验与头部修改(以太网,IP,隧道报文)。
- ❑复杂运算(如加解密与压缩算法)。
基于专门设计的硬件,快速执行数据包的转发和一些简单的报文修改处理可以有效地提高数据的吞吐量和降低发送时延。具体来说,在网络功能节点的设计上,数据面的处理此前大多使用专门的硬件(网络处理器,FPGA, ASIC)来处理这些比较耗时的功能,以提高处理效率。
下面将会按照几个方面来介绍硬件卸载功能。首先我们可以了解Intel几代网卡提供的硬件卸载功能,这个发展脉络可以给我们有益的启示。然后,我们将硬件卸载功能分为计算及更新、分片、组包三大类,分门别类进行介绍。
110.网卡硬件卸载功能
DPDK支持的网卡种类已经非常多,本章不会对所有的网卡进行罗列。我们将会选取几种有代表性的Intel网卡进行介绍,希望能够为读者提供一个网卡的硬件卸载功能发展脉络。如果读者希望了解更多的细节,有一句话叫做,everything on the Internet,网上能够搜索到每块网卡的说明书及详细的功能介绍。
本章将选取四种有代表性的Intel网卡(i350、82599、x550、xl710)作为例子进行比较。本章主要对比网卡的功能差异,具体的功能将在下面的章节说明。
i350是1G的网卡,82599和x550是10G的网卡,而xl710是10G/40G的网卡。可以看到这四种网卡是符合时间轴线(从旧到新)逐步发展而来的,而功能也大致是逐步丰富的,基本代表了业界的脉搏。
表9-1简略罗列了各种网卡支持的硬件卸载的功能,下面几个节会具体介绍每种功能。当然,本章未必涵盖每种网卡支持的所有的硬件卸载功能,只是选取了一些有助于读者理解硬件卸载功能的特性。
表9-1 网卡硬件卸载功能比较
从表9-1中可看出,每种硬件支持的功能是类似的,这表明很多有效实用的硬件卸载功能是会在新的各种网卡上继承下来。而同时,新的硬件卸载功能也会逐步被丰富起来。
111.DPDK软件接口
网卡的硬件卸载功能可能是基于端口设置,也有可能是基于每个包设置使能,需要仔细区分。在包粒度而言,每个包都对应一个或者多个Mbuf, DPDK软件利用rte_mbuf数据结构里的64位的标识(ol_flags)来表征卸载与状态,ol_flags的解码信息具体如下,根据下面罗列的名称可以大致了解目前DPDK所提供的各项硬件卸载功能。
接收侧:
表9-2 DPDK软件接口提供的硬件卸载功能(接收侧)
发送侧:
表9-3 DPDK软件接口提供的硬件卸载功能(发送侧)
详细信息参见以下链接:
http://www.dpdk.org/browse/dpdk/tree/lib/librte_mbuf:https://git.dpdk.org/dpdk/tree/lib/librte_mbuf
Mode | Name | Size | |
---|---|---|---|
-rw-r--r-- | meson.build | 305 | logplain |
-rw-r--r-- | rte_mbuf.c | 26598 | logplain |
-rw-r--r-- | rte_mbuf.h | 56054 | logplain |
-rw-r--r-- | rte_mbuf_core.h | 25398 | logplain |
-rw-r--r-- | rte_mbuf_dyn.c | 13428 | logplain |
-rw-r--r-- | rte_mbuf_dyn.h | 10643 | logplain |
-rw-r--r-- | rte_mbuf_pool_ops.c | 2234 | logplain |
-rw-r--r-- | rte_mbuf_pool_ops.h | 2165 | logplain |
-rw-r--r-- | rte_mbuf_ptype.c | 6155 | logplain |
-rw-r--r-- | rte_mbuf_ptype.h | 21286 | logplain |
-rw-r--r-- | version.map | 1042 | logplain |
http://www.dpdk.org/browse/dpdk/tree/app/testpmd:https://git.dpdk.org/dpdk/tree/app/testpmd
path: root/app/testpmd
Path not found
112.硬件与软件功能实现
顾名思义,硬件卸载功能是将某些功能下移到硬件实现。这些功能原先一般是由软件承担的,而有了硬件卸载功能,这些工作将不再需要由软件完成。
如果需要使用硬件卸载功能,网卡驱动需要提供相应的API给上层应用,通过调用API驱动硬件完成相应的工作。而驱动硬件的工作实际上是由网卡驱动程序完成的,网卡驱动程序也是通过硬件提供的接口来驱动硬件。硬件提供的接口一般包括寄存器(Register)和描述符(Descriptor)。寄存器是全局的设置,一般用于开启某项功能或者为某项功能设置全局性的参数配置,一般情况下是基于以太网端口为基本单位。描述符可以看做是每个数据包的属性,和数据包一起发送给硬件,一般用于携带单个数据包的参数或设置。这两种接口提供的一粗一细两种粒度可以有效合作,完成硬件卸载功能的设置。
第8章已经提到,网卡的硬件有很多种类,对于硬件卸载功能的支持也各不相同。本书中提到的网卡主要是Intel的产品,而其他厂商的网卡也可能提供类似的功能。对于每种具体的硬件设备,具体功能的支持可能有所差异,下面章节对于具体功能的介绍尽量着眼于理论性和通用性,以避免解释和讨论每种网卡的特定实现。读者应该明白不应以本书的描述去确定具体网卡的功能,本书的描述可能是一种综合性的展现。
对于各种各样的硬件卸载功能,按照功能的相似性大致可分成三类,分别是计算及更新功能、分片功能、组包功能。
需要注意的是,下面在分别介绍每种硬件卸载功能时,会指出相关的DPDK的代码作为参考。大部分情况下,所列出的代码是对每种网卡的具体实现进行封装后的通用接口,不排除某些网卡支持这种功能而其他网卡不支持或者支持的程度和方式有所差异。因此,读者在使用某种网卡时,可能会发现某种功能无法支持或行为有所不同。针对读者正在使用的网卡,如果要了解是否支持此功能或者功能实现的细节,需要对代码进行更加深入的分析,关注此种网卡的具体实现。
计算及更新功能卸载
113.VLAN硬件卸载
VLAN虽然只有4个字节,但是可以实现以太网中逻辑网络隔离功能,在数据中心、企业网络以及宽带接入中被广泛应用。典型网络处理中,需要对报文的VLAN Tag进行识别,判断有无(检测0x8100),读取剥离,识别转发,以及发送插入。这些是常见操作。大多网卡支持此类卸载操作。
如9-1图所示,VLAN在以太网报文中增加了了一个4字节的802.1q Tag(也称为VLAN Tag), VLAN Tag的插入可以完全由软件完成。毫无疑问,如果由软件完成VLAN Tag的插入将会给CPU带来额外的负荷,涉及一次额外的内存拷贝(报文内容复制),最坏场景下,这可能是上百周期的开销。大多数网卡硬件提供了VLAN卸载的功能,VLAN Tag的插入和剥离由网卡硬件完成,可以减轻服务器CPU的负荷。
图9-1 VLAN在以太网报文数据头部结构
1. 收包时VLAN Tag的过滤
VLAN定义了虚拟网络,只有属于相同VLAN的报文,才需要被进一步处理,不属于VLAN的报文会被直接丢弃,因此网卡最典型的卸载功能之一就是在接收侧针对VLAN进行包过滤。典型实现是在网卡硬件端口设计了VLAN过滤表,无法在过滤表中匹配的VLAN包会被丢弃,没有VLAN信息的以太网则会通过网卡的过滤机制,在DPDK中app/testpmd提供了测试命令与实现代码。表9-4给出了Testpmd的命令及功能解释。
表9-4 Testpmd的命令及功能解释
现代网卡的过滤机制会直接涉及报文丢弃,软件开发人员常常会碰到无法正常收包的场景,因此需要进行问题分析定位,仔细查看网卡的接收过滤机制,VLAN过滤是其中的一种可能而已,过滤机制可能会因网卡而异。
2. 收包时VLAN Tag的剥离
网卡硬件能够对接收到的包的VLAN Tag进行剥离。首先硬件能够对VLAN包进行识别,原理上是判断以太帧的以太网类型来确定是否是VLAN包。启动这项硬件特性,需要在网卡端口,或者是属于这个网卡端口的队列上设置使能标志,将VLAN剥离特性打开,对应到软件,是驱动写配置入相应的寄存器。网卡硬件会从此寄存器中提取配置信息,用于判断是否对收到的以太网数据执行VLAN剥离。如果打开剥离功能,则执行此功能;如果没有打开剥离功能,则不执行剥离功能。DPDK的app/testpmd提供了如何基于端口使能与去使能的测试命令。
testpmd> vlan set strip (on—off) (port_id)
testpmd> vlan set stripq (on—off) (port_id, queue_id)
网卡硬件会将4字节的VLAN tag从数据包中剥离,VLAN Tag中包含的信息对上层应用是有意义的,不能丢弃,此时,网卡硬件会在硬件描述符中设置两个域,将需要的信息通知驱动软件,包含此包是否曾被剥离了VLAN Tag以及被剥离的Tag。软件省去了剥离VLAN Tag的工作负荷,还获取了需要的信息。对应在DPDK软件,驱动对每个接收的数据包进行检测,会依据硬件描述符信息,如果剥离动作发生,需要将rte_mbuf数据结构中的PKT_RX_VLAN_PKT置位,表示已经接收到VLAN的报文,并且将被剥离VLAN Tag写入到下列字段。供上层应用处理。
struct rte_mbuf{
uint16_t vlan_tci; /**< VLAN Tag Control Identifier(CPU order) */
}
3. 发包时VLAN Tag的插入
在发送端口插入VLAN在数据包中,是报文处理的常见操作。VLAN Tag由两部分组 成:TPID(Tag Protocol Identifier),也 就 是VLAN的Ether type,和TCI(Tag Control Information)。TPID是一个固定的值,作为一个全局范围内起作用的值,可通过寄存器进行设置。而TCI是每个包相关的,需要逐包设置,在DPDK中,在调用发送函数前,必须提前设置mbuf数据结构,设置PKT_TX_VLAN_PKT位,同时将具体的Tag信息写入vlan_tci字段。
struct rte_mbuf{
uint16_t vlan_tci; /**< VLAN Tag Control Identifier(CPU order) */
}
DPDK PMD会被发送报文函数调用,软件驱动程序会检查mbuf的这两部分设置信息,在报文离开网络端口时具体插入VLAN Tag信息。下文是testpmd中做发送端VLAN设置的命令,可以参考代码实现,了解如何利用这个特性。
testpmd> tx_vlan set (port_id) vlan_id[, vlan_id_outer]
如果在发送端口0,需要给出去的报文设置VLAN Tag= 5,可以使用如下命令:
tx_vlan set 0 5,
或者,如果在发送端口1,需要给出去的报文设置双层VLAN,比如内层、外层VLAN Tag是2,3,可以使用如下命令:
tx_vlan set 1 2 3
4. 多层VLAN的支持
VLAN技术非常流行,使用也很广泛。早期定义时,VLAN本身只定义了12位宽,最多容纳4096个虚拟网络,这个限制使得它不适合大规模网络部署,为了解决这个局限,业界发展出了采用双层乃至多层VLAN堆叠模式,随着这种模式(也被称为QinQ技术)在网络应用中变得普遍,现代网卡硬件大多提供对两层VLAN Tag进行卸载,如VLAN Tag的剥离、插入。DPDK的app/testapp应用中提供了测试命令。网卡数据手册有时也称VLAN Extend模式,这在DPDK的代码中被延用。
testpmd> vlan set qinq (on—off) (port_id)。
- ❑以82599, X550网卡为例,在接收侧,VLAN过滤与剥离操作是针对双层VLAN中的内层VLAN Tag。
- ❑以XL710网卡为例,VLAN剥离时能同时剥去内外层VLAN Tag,并存储在mbuf的数据结构中。
对于发包方向,硬件可能只会提供对内层VLAN的操作。也就是说,硬件会假设外层VLAN已经由软件生成,硬件能够解析此外层VLAN,并且跳过它对内层进行操作,假如硬件发现某个包只有一层VLAN,它会假设这个包只有外层VLAN,而停止对内层操作的功能。
114.IEEE1588硬件卸载功能
IEEE1588定义了PTP(Precision Timing Protocol,精准时间同步协议),用于同步以太网的各个节点,是一个非常适合使用硬件卸载功能的特性。如我们所知,IEEE1588为网络设备提供时间同步功能。作为时间同步功能,本身对实时性的要求很高。也就是说,当需要为数据包打上时间戳的时候,希望时间戳能够尽量的精确。如果采用软件的方式,报文修改处理本身消耗大,可能打时间戳和获取时间戳之间已经存在一定的延时,导致时间戳本身不是非常精确。而使用硬件来实现IEEE1588的功能,则能够快速完成获取并打时间戳的工作,能有效提高时间戳的精确性。图9-2描述了PTP的报文格式。
图9-2 用于IEEE188的PTP报文格式
PTP协议说明了IEEE1588的基本流程。分为初始化和时间同步两部分。图9-3描述了PTP相关的消息流程。
在初始化时,每个潜在的可以作为master的节点都会发出sync包,其中携带了时钟相关的信息。同时,每个节点也在接收别的节点发出的sync包,当收到sync包时,会将其中的参数和自身进行比较,如果对端的参数较优,则将自己置为slave的角色,而将对端节点认为是master。当然,slave节点还将继续监听sync包,如果它发现还有更优的另外的节点,它将会把master节点切换为更优的新节点。另外,slave还需要支持超时机制,如果它长时间不能从选中的master那里收到sync包,它将会把自己切换成master,并重复master选举的过程。
图9-3 IEEE1588的PTP基本流程
初始化完成后,确定了master和slave的角色,此时将会开始时间同步过程,因为在master和slave上时间同步的处理是不同的。
对于master,需要周期性地发送sync包,这些sync包需要携带时间戳。基于精确性的考虑,时间戳可由网卡硬件添加,并且在尽量接近物理层的地方实现。而且在sync包之后,follow_up包将接着发送,并且其中包含了sync包的时间点。
当master收到delay request包,master需要记录时间点,并且以delay response包响应。而slave节点需要记录每个从选中的master发送过来的sync包的时间点。
在上述的过程中,硬件承担的责任也就是硬件卸载能够承担的工作是:
- 1)分辨出哪些包是需要时间戳的。
- 2)为那些需要的包添加时间戳。既需要在接收方向,也需要在发送方向上进行。
- 3)需要存储添加的时间戳,从而能够将这个时间戳的值告知软件。
DPDK在app/testpmd内提供了如何使用IEEE1588的例子,testpmd有专门的1588转发处理模式,DPDK基于专用核来实现报文收发,又结合了网卡硬件卸载特性,适合构建基于IEEE1588功能的应用。如果我们采用纯粹的软件来实现给包打时间戳的功能,由于软件处理必然会存在的时延问题,时间戳会精度不够准确。在使用DPDK测试1588前,需要注意打开如下编译配置,再对DPDK代码进行编译。
CONFIG_RTE_LIBRTE_IEEE1588=y.
在DPDK代码中,我们可以关注这个函数,int rte_eth_timesync_enable(uint8_t port_id),通过此函数,调用者可以在收发两个方向上同时使能IEEE1588功能。使能IEEE1588功能后,硬件将会承担在收发数据包上打时间戳的工作,并且将所打的时间戳的值存储在寄存器中,驱动程序需要读取寄存器以获取时间戳的值。
DPDK已经提供了读取收发的时间戳的函数,
int rte_eth_timesync_read_rx_timestamp(uint8_t port_id, struct timespec *timestamp, uint32_t flags)
和
int rte_eth_timesync_read_tx_timestamp(uint8_t port_id, struct timespec *timestamp)
将收发时间戳的值暴露给调用者,调用者使用此函数获取时间戳后可以完成IEEE1588协议栈的操作,而不需要关心时间戳获取的问题。
简单说,DPDK提供的是打时间戳和获取时间戳的硬件卸载。需要注意,DPDK的使用者还是需要自己去管理IEEE1588的协议栈,DPDK并没有实现协议栈。
115.IP TCP/UDP/SCTP checksum硬件卸载功能
checksum计算是网络协议的容错性设计的一部分,基于网络传输不可靠的假设,因此在Ethernet、IPv4、UDP、TCP、SCTP各个协议层设计中都有checksum字段,用于校验包的正确性,checksum不涉及复杂的逻辑。虽然各个协议定义主体不同,checksum算法参差不齐,但总体归纳,checksum依然可以说是简单机械的计算,算法稳定,适合固化到硬件中。需要注意的是,checksum可以硬件卸载,但依然需要软件的协同配合实现。
在DPDK的app/testpmd提供了csum的转发模式,可以作为编程参考。checksum在收发两个方向上都需要支持,操作并不一致,在接收方向上,主要是检测,通过设置端口配置,强制对所有达到的数据报文进行检测,即判断哪些包的checksum是错误的,对于这些出错的包,可以选择将其丢弃,并在统计数据中体现出来。在DPDK中,和每个数据包都有直接关联的是rte_mbuf,网卡自动检测进来的数据包,如果发现checksum错误,就会设置错误标志。软件驱动会查询硬件标志状态,通过mbuf中的ol_flags字段来通知上层应用。
PKT_RX_L4_CKSUM_BAD表示4层协议checksum校验失败
PKT_RX_IP_CKSUM_BAD表示3层协议checksum校验失败
可见,在接收侧利用硬件做checksum校验,对程序员是非常简单的工作,但在发送侧就会复杂一些,硬件需要计算协议的checksum,将且写入合适的位置。在原理上,网卡在设计之初时就依赖软件做额外设置,软件需要逐包提供发送侧上下文状态描述符,这段描述符需要通过PCIe总线写入到网卡设备内,帮助网卡进行checksum计算。设置上下文状态描述符,在DPDK驱动里面已经实现,对于使用DPDK的程序员,真正需要做的工作是设置rte_mbuf和改写报文头部,保证网卡驱动得到足够的mbuf信息,完成整个运算。
从设置mbuf的角度,如下字段需要关注。
/* fields to support TX offloads */
uint64_t tx_offload; /**< combined for easy fetch */
struct {
uint64_t l2_len:7; /**< L2 (MAC) Header Length. */
uint64_t l3_len:9; /**< L3 (IP) Header Length. */
uint64_t l4_len:8; /**< L4 (TCP/UDP) Header Length. */
uint64_t tso_segsz:16; /**< TCP TSO segment size */
IPv6头部没有checksum字段,无需计算。对于IPv4的checksum,在发送侧如果需要硬件完成自动运算与插入,准备工作如下:
ipv4_hdr->hdr_checksum = 0; //将头部的checksum字段清零
ol_flags —= PKT_TX_IP_CKSUM; //IP层checksum请求标识置位
对于UDP或者TCP, checksum计算方法一样,准备工作如下:
udp_hdr->dgram_cksum = 0; //将头部的checksum字段清零
ol_flags —= PKT_TX_UDP_CKSUM; //UDP层checksum请求标识置位
/* 填入IP 层伪头部计算码,具体实现参阅DPDK代码*/
udp_hdr->dgram_cksum = get_psd_sum(l3_hdr, info->ethertype, ol_flags);
对于SCTP checksum计算方法一样,准备工作如下:
sctp_hdr->hdr_checksum = 0;
ol_flags —= PKT_TX_SCTP_CKSUM;
因为checksum通常是需要整个报文参与运算,所以逐包运算对CPU是个不小的开销。
116.Tunnel硬件卸载功能
以VxLAN和NVGRE为例说明Tunnel相关的硬件卸载功能。
VxLAN和NVGRE的情况相对复杂一些,对于这两个协议的支持程度可能在每种网卡上有所不同。某些网卡可能只提供一些相对简单的checksum功能。也就是说,这些网卡具有识别VxLAN和NVGRE的数据包的能力,并能对其涉及的协议IP和TCP/UDP提供校验和的功能(可能需要注意,VxLAN的外层UDP的校验和需要固定填写成0),从而减轻CPU的负担。这种校验和的功能可以涵盖外层和内存头。
关于VxLAN和NVGRE还可能提供更复杂的功能,比如将VxLAN或NVGRE的外层头添加或剥离的功能卸载到硬件。
从VxLAN和NVGRE的数据包结构看,它们属于overlay的数据包,图9-4描述了VxLAN数据包的基本结构。无论考虑外层还是内层,都可以将其看成是二层三层的数据包,因此一些二层三层相关的硬件卸载功能可以应用到VxLAN和NVGRE的数据包上,这些可以视为对VxLAN和NVGRE的硬件卸载功能的扩展。
图9-4 VxLAN的数据包结构
例如,流的重定向功能可以基于VxLAN和NVGRE的特定信息,TNI或VNI,以及内层的MAC或IP地址进行重定向。同样地,对IP流进行过滤时,也可以根据内层的IP信息进行过滤。
如前所述,VxLAN和NVGRE的硬件卸载是较新的功能,因此当前DPDK(Release2.2)对其还没有全面支持。目前DPDK仅支持对VxLAN和NVGRE的流进行重定向。
在dpdk/testpmd中,可以使用相关的命令行来使用VxLAN和NVGRE的数据流重定向功能,如下所示:
flow_director_filter X mode Tunnel add/del/update mac XX:XX:XX:XX:XX:XX vlan
XXXX tunnel NVGRE/VxLAN tunnel-id XXXX flexbytes (X, X) fwd/drop queue X fd_id X
在数据结构rte_eth_fdir_flow中增加了Tunnel(目前只包括VxLAN和NVGRE)数据流相关的定义,参见:
union rte_eth_fdir_flow {
......
struct rte_eth_tunnel_flow tunnel_flow;
};
读者可参考tunnel_flow相关的代码了解VxLAN和NVGRE的数据流重定向功能的具体实现。
分片功能卸载
117.TSO(TCP Segment Offload TCP分片功能的硬件卸载)
《Linux环境中的网络分段卸载技术 GSO/TSO/UFO/LRO/GRO》
TSO(TCP Segment Offload)是TCP分片功能的硬件卸载,显然这是发送方向的功能。如我们所知,TCP会协商决定发送的TCP分片的大小。对于从应用层获取的较大的数据,TCP需要根据下层网络的报文大小限制,将其切分成较小的分片发送。
硬件提供的TCP分片硬件卸载功能可以大幅减轻软件对TCP分片的负担。而且这项功能本身也是非常适合由硬件来完成的,因为它是比较简单机械的实现。在图9-5中,我们可以看到,TCP分片需要将现有的较大的TCP分片拆分成较小的TCP分片,在这个过程中,不需要提供特殊的信息,仅仅需要复制TCP的包头,更新头里面的长度相关的信息,重新计算校验和,显然这些功能对于硬件来说都不是陌生的事情。
图9-5 TSO分片功能示意图
在dpdk/testpmd中提供了两条TSO相关的命令行:
- 1)tso set 1400 0:用于设置tso分片大小。
- 2)tso show 0:用于查看tso分片的大小。
和csum硬件卸载功能类似,tso分片硬件卸载功能也需要对mbuf进行设置,同样从设置mbuf的角度,如下字段需要关注。
/* fields to support TX offloads */
uint64_t tx_offload; /**< combined for easy fetch */
struct {
uint64_t l2_len:7; /**< L2 (MAC) Header Length. */
uint64_t l3_len:9; /**< L3 (IP) Header Length. */
uint64_t l4_len:8; /**< L4 (TCP/UDP) Header Length. */
uint64_t tso_segsz:16; /**< TCP TSO segment size */
同时tso使用了ol_flag中的PKT_TX_TCP_SEG来指示收发包处理流程中当前的包需要开启tso的硬件卸载功能。对DPDK具体实现感兴趣的读者可以以上述代码作为切入点来进一步了解更多的细节。
组包功能卸载
118.RSC(Receive Side Coalescing,接收方聚合)
《Linux环境中的网络分段卸载技术 GSO/TSO/UFO/LRO/GRO》
《DPDK笔记 RSS(receive side scaling)网卡分流机制》
《网卡多队列:RPS、RFS、RSS、Flow Director(DPDK支持)》
RSC(Receive Side Coalescing,接收方聚合)是TCP组包功能的硬件卸载。硬件组包功能实际上是硬件拆包功能的逆向功能。
硬件组包功能针对TCP实现,是接收方向的功能,可以将拆分的TCP分片聚合成一个大的分片,从而减轻软件的处理。
当硬件接收到TCP分片后,如图9-6和图9-7所示,硬件可以将多个TCP分片缓存起来,并且将其排序,这样,硬件可以将一串TCP分片的内容聚合起来。这样多个TCP分片最终传递给软件时将会呈现为一个分片,这样带给软件的好处是明显的,软件将不再需要分析处理多个数据包的头,同时对TCP包的排序的负担也有所减轻。
图9-6 RSC组包功能示意图1
图9-7 RSC组包功能示意图2
图9-8描述了网卡在接收处理上的详细流程,对能够分片的数据包进行识别,描述了新分组数据流,现有分组数据流的处理逻辑。以上图片引自Intel x550网卡的数据手册,这是一份公开的文档,有兴趣的读者可以从互联网上搜索到并下载进行延伸阅读。
图9-8 RSC组包事件处理机制示意图
无疑,RSC是一种硬件能力,使用此功能时需要先明确硬件支持此能力。同时我们通过配置来开启RSC功能。需要关注下面的数据结构:
/**
* A structure used to configure the RX features of an Ethernet port.
*/
struct rte_eth_rxmode {
/** The multi-queue packet distribution mode to be used, e.g. RSS. */
enum rte_eth_rx_mq_mode mq_mode;
uint32_t max_rx_pkt_len; /**< Only used if jumbo_frame enabled. */
uint16_t split_hdr_size; /**< hdr buf size (header_split enabled).*/
uint16_t header_split : 1, /**< Header Split enable. */
hw_ip_checksum : 1, /**< IP/UDP/TCP checksum offload enable. */
hw_vlan_filter : 1, /**< VLAN filter enable. */
hw_vlan_strip : 1, /**< VLAN strip enable.*/
hw_vlan_extend : 1, /**< Extended VLAN enable. */
jumbo_frame : 1, /**< Jumbo Frame Receipt enable. */
hw_strip_crc : 1, /**< Enable CRC stripping by hardware. */
enable_scatter : 1, /**< Enable scatter packets rx handler */
enable_lro : 1; /**< Enable LRO */
};
RSC是接收方向的功能,因此和描述接收模式的数据结构(即enable_lro)相关。(LRO是指Large Receive Offload,是RSC的另一种表述。)
我们可以看到,当对接收处理进行初始化ixgbe_dev_rx_init时,会调用ixgbe_set_rsc,此函数中对enable_lro进行判断,如果其为真,则会对RSC进行相关设置,从而使用此功能。需要关注具体实现的读者可以研读此段代码。
119.小结
硬件卸载功能实际上是网卡功能的增强,通过由网卡硬件提供额外的功能来分担CPU的处理负荷。可以认为是有好处而没有额外短处的功能。但需要明确的是,由于硬件多种多样,硬件卸载功能的支持与否以及支持的程度都可能不同,同时应用程序需要了解并使用硬件卸载功能,否则是无法从硬件卸载功能中得到好处的。因此,这对开发者提出了额外的要求。
系列文章
《《深入浅出DPDK》读书笔记(一):基础部分知识点》
《《深入浅出DPDK》读书笔记(二):网卡的读写数据操作》
《《深入浅出DPDK》读书笔记(三):NUMA - Non Uniform Memory Architecture 非统一内存架构》
《《深入浅出DPDK》读书笔记(四):并行计算-SIMD是Single-Instruction Multiple-Data(单指令多数据)》
《《深入浅出DPDK》读书笔记(五):同步互斥机制》
《《深入浅出DPDK》读书笔记(六):报文转发(run to completion、pipeline、精确匹配算法、最长前缀匹配LPM)》
《《深入浅出DPDK》读书笔记(七):PCIe与包处理I/O》
《《深入浅出DPDK》读书笔记(八):网卡性能优化(异步中断模式、轮询模式、混和中断轮询模式)》
《《深入浅出DPDK》读书笔记(九):流分类与多队列》
《《深入浅出DPDK》读书笔记(十):硬件加速与功能卸载(VLAN、IEEE1588、IP TCP/UDP/SCTP checksum、Tunnel)》
相关阅读
《DPDK PMD( Poll Mode Driver)轮询模式驱动程序》
《DPDK笔记 RSS(receive side scaling)网卡分流机制》
《网卡多队列:RPS、RFS、RSS、Flow Director(DPDK支持)》
《Linux环境中的网络分段卸载技术 GSO/TSO/UFO/LRO/GRO》
最后
以上就是俭朴白开水为你收集整理的《深入浅出DPDK》读书笔记(十):硬件加速与功能卸载(VLAN、IEEE1588、IP TCP/UDP/SCTP checksum、Tunnel)109.硬件卸载简介110.网卡硬件卸载功能111.DPDK软件接口112.硬件与软件功能实现113.VLAN硬件卸载114.IEEE1588硬件卸载功能115.IP TCP/UDP/SCTP checksum硬件卸载功能116.Tunnel硬件卸载功能分片功能卸载117.TSO(TCP Segment Offload TCP分片功能的硬件卸载)组包的全部内容,希望文章能够帮你解决《深入浅出DPDK》读书笔记(十):硬件加速与功能卸载(VLAN、IEEE1588、IP TCP/UDP/SCTP checksum、Tunnel)109.硬件卸载简介110.网卡硬件卸载功能111.DPDK软件接口112.硬件与软件功能实现113.VLAN硬件卸载114.IEEE1588硬件卸载功能115.IP TCP/UDP/SCTP checksum硬件卸载功能116.Tunnel硬件卸载功能分片功能卸载117.TSO(TCP Segment Offload TCP分片功能的硬件卸载)组包所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复