linux网络子系统架构,openEuler网络子系统
功能网络子系统负责系统的网络IO,通过与网络设备(路由器、交换机等)的数据交互,实现端到端的数据交互过程。下图示意网络数据流:图 8-1 网络数据流视图网络子系统位于端系统中,从上图可以看出网络子系统在数据面划分成应用层、传输层、网络层、链路层、物理层。每一层可以对应到OSI^定义的网络七层模型^1。架构网络子系统架构可以分软件视角,硬件视角两个维度描述。软件视角淡化物理位置、设备差异,强调..
功能
网络子系统负责系统的网络IO,通过与网络设备(路由器、交换机等)的数据交互,实现端到端的数据交互过程。下图示意网络数据流:
图 8-1 网络数据流视图
网络子系统位于端系统中,从上图可以看出网络子系统在数据面划分成应用层、传输层、网络层、链路层、物理层。每一层可以对应到OSI^定义的网络七层模型^1。
架构
网络子系统架构可以分软件视角,硬件视角两个维度描述。软件视角淡化物理位置、设备差异,强调逻辑分层;硬件视角强调系统维度描述架构组成元素,本文以鲲鹏920芯片作为系统参考对象。
软件视角的网络子系统是linux网络子系统;硬件视角的网络子系统是鲲鹏网络子系统。
linux网络子系统
linux kernel 4.19版本中,网络子系统代码目录定义如下:
/net
/net/core
/driver/net
linux网络子系统按照逻辑分层方式描述架构分层。通过逻辑抽象分层,linux网络子系统给用户态提供统一的BSD Socket接口通道,并同时支持各种不同的硬件,各种不同的网络协议。
图8-2 linux网络子系统
linux 网络子系统内模块众多,功能复杂,本文不详细讲解每个模块的功能及实现。我们从数据面、管理面两个维度描述该子系统的工作原理。
数据面
在发送方向上,应用程序通过send()系统调用接口进行报文发送,报文内容会先进入内核空间完成必要的协议层处理,此时硬件Device未必是就绪状态,所以Driver程序必须等其就绪才能通知其进行报文发送处理。在此之前,报文必须缓存在主存内。
在接收方向上,硬件Device收到数据报文后,驱动收到中断通知完成数据报文读取进内核空间,完成必要的协议层处理,此时应用程序未必是就绪状态,所以内核需等其就绪后才能唤醒其进行报文接收处理。在此之前,报文必须缓存在主存内。
报文在内核中缓存是通过一个称之为sk_buff的数据结构进行管理的,该结构复杂,内部细节较多,这里不展开描述。其基本原理是:
报文头的解析/封装采取空间预留技术,在协议层内各种协议报文头处理过程中,协议头解析/封装结果只需在预留空间内偏移,省去了很多内存拷贝,迁移操作。
报文体的构造采取数据分段技术,当报文体内容过长时,可以通过分段形式不断补充数据,sk_buff以链方式管理数据包,同样也省去了很多内存拷贝、迁移操作。
以上两个逻辑可以图例方式表达:
图8-3 报文收发逻辑
在图例中更容易清晰看到:
内存拷贝:收发两个方向(硬件设备用户应用程序),都存在两次拷贝操作,一次是软件拷贝,一次是硬件拷贝。
执行调度:收报流程中,硬件设备中断触发驱动软件分配sk_buff,驱动软件触发软中断驱动协议层完成报文处理,待用户线程就绪时唤醒其执行接收报文处理。发送流程中,用户线程分配sk_buff,协议层完成报文处理后入发送缓存队列,随后通过软中断调度触发驱动软件通知硬件设备进行发送报文。
所以linux网络子系统数据面在空间性能方面存在内存拷贝的性能开销,时间性能方面存在多次调度切换的性能开销。
管理面
linux网络子系统管理面通过一个重要对象进行管理:网络设备。
图8-4 网络设备驱动架构
网络设备驱动架构中,对协议层抽象出统一的报文收发接口,使协议层与各种网络设备充分解耦。通过注册回调函数方式,实现具体硬件设备的收发报文接口调用。其中关键的数据结构是struct net_device,其对各种网络设备进行抽象、封装,屏蔽硬件差异。
网络设备驱动程序通过register_netdev()注册设备上线,注册时携带协议层定义的数据结构、回调函数,从而配合协议层对其进行控制。
例如网卡硬件能力实现了很多offloading功能,尽量将一些机械重复的工作下沉至网卡硬件,其目的是解放CPU,提升系统吞吐量。net_device就通过xx_features进行表达硬件的能力,如下所示:
struct net_device {
...
netdev_features_tfeatures;
netdev_features_thw_features;
netdev_features_twanted_features;
netdev_features_tvlan_features;
netdev_features_thw_enc_features;
netdev_features_tmpls_features;
netdev_features_tgso_partial_features;
...
}
设备上线注册时,驱动程序根据硬件实际情况设置这些字段通知协议层硬件能力,协议层在处理报文时根据硬件能力就跳过某些计算过程。
结语
linux网络子系统是站在单CPU视角看数据面、管理面,现代服务器普遍是SMP/NUMA系统结构,仅仅从单CPU视角看网络子系统不能完整展现服务器内网络子系统的工作过程。
下面我们介绍下鲲鹏920系列的网络子系统,用来展示更多工作过程。
鲲鹏网络子系统
以鲲鹏920作为参考对象,介绍其网络子系统。
图 8-5 鲲鹏网络子系统
组成部分:
网络ICL:
网络ICL(I/O Clusters)就是鲲鹏920网络子系统。网络ICL与PCIe系统架构兼容,可以支持多个PCI Function,每个PCI Function具备独立的任务空间、配置空间,以处理各自独立的服务数据、硬件参数配置。简单的说就是网络ICL可以向总线上报多个PCI Function。
PCI Function:
PCI Function可以呈现为物理网卡(PF)或虚拟网卡(VF),每个PF/VF可以被分配到1个或多个队列对(QP),其包括Tx队列和Rx队列,这些队列会映射到主存空间(Tx Queue、Rx Queue)。通过QP,PF或VF就可以进行主存的访存操作。
当PF或VF被分配多队列对时,这个网卡就具备同时与多个CPU进行报文收发处理(RSS技术)。
主存:
主存会提供存储空间映射到QP,并以ring buffer形式管理Tx Queue、Rx Queue。
中断:
接收到报文时,通过触发中断通知CPU的设备驱动程序处理收到的报文;发送报文完成后,通过触发中断通知CPU释放主存内的报文资源。
CPUs:
多核CPU,运行用户态程序、网络协议栈、网络驱动程序,软件形式通过总线触发Tx Schedule调度报文发送。
总线:
鲲鹏920片内总线。
Tx Schedule:
当主存 Tx Queue的ring buffer非空时,Tx Schedule就会被触发运行,执行发送调度操作。调度输出结果是触发TxDMA进行报文加载操作。
TxDMA / RxDMA:
TxDMA 用于将数据包从主存读取后加载进Packet Buffer,RxDMA用于从Packet Buffer读取后加载进主存队列。TxDMA / RxDMA的数据读存操作目的只有一个:给CPU”减负“,提升CPU利用率。
NIC Engine
PPP:提供NIC Engine可编程能力,为报文处理提供灵活性。包括提供基于VLAN和MAC信息的Rx方向的过滤能力,提供Flow Director机制实现RSS负载平衡能力。
Packet Buffer:提供Tx/Rx两个方向的报文缓存能力。
MAC复用器:
支持以太帧的发送/接收,实现CRC计算和校验,提供流控、自协商等能力。
为了更好的了解其工作原理,我们从报文收发两方面描述其工作原理。
接收数据流
接收数据流是指网络ICL从物理链路媒介中接收到数据,经过解析、过滤、复制等处理后,将数据报文存储到Packet Buffer,然后由RxDMA将数据报文存储至主存,最后向软件报告。
图 8-5 接收数据流过程
发送数据流
发送数据流是指网络设备驱动程序对ring buffer添加包任务,随后触发Tx Schedule发起调度,由NIC Engine完成主存内报文读取,TSO,报文编辑,MAC发送等操作。发送完成后,产生中断通知CPU释放包任务资源。
图 8-6 发送数据流过程
更多推荐
所有评论(0)