SylixOS网络开发(四)

gewenbin
gewenbin
gewenbin
188
文章
15
评论
2020年12月26日19:55:09 评论 1,056

1. 概述

本章节讲述网络零拷贝技术的基本原理,需要知道的一个前提条件是,零拷贝可能不会提升网络驱动收发数据的速度,对不同的平台需要具体的分析,不能一概而论。

2. 发送零拷贝

我们来看看上一章节中的网络数据流图:

SylixOS网络开发(四)

发送数据的时候原来是将pbuf中的数据复制到驱动中的DMA缓冲区中然后设置硬件进行发送,这个复制其实是可以去掉的,发送零拷贝其实就是去掉了这个复制过程。在解释为什么可以去掉这个复制过程之前,我们先来看看为啥驱动层里需要一个DMA缓冲区:

  • 不管是网卡还是啥其他外设的DMA传输,对缓冲区的物理地址有要求,即要求缓冲区的物理地址必须是连续的,因为DMA硬件是直接和内存进行数据传输的。
  • DMA传输需要特别注意的是,缓冲区数据一致性,这里说的一致性是指和cache的一致性,也就是说必须保证DMA缓冲区中的数据是最新的。这可以通过两种方法来保证,一是使用不带cache的缓冲区,二是程序员手动调用操作cache的接口来保证数据的一致性,也就是cache flush和cache invalidate。

明白了为啥需要DMA缓冲区之后,我们来看看pbuf中的缓冲区。在SylixOS中,内核pbuf的缓冲区同样是物理地址连续的,并且是带cache的,那么我们可以直接将pbuf中的缓冲区拿过来给网卡硬件使用,同时由于缓冲区是带cache的,所以网卡硬件使用之前需要对缓冲区区域进行cache flush以保证内存中的数据是最新的。

如果使用发送零拷贝还需要考虑pbuf何时回收的问题,在非零拷贝的驱动中,由于已经将数据从pbuf中的缓冲区复制到了驱动中的DMA缓冲区,所以pbuf被协议栈回收不会影响硬件上发送数据,但是在零拷贝中不是这样的。如果在零拷贝中协议栈在硬件还没将数据发送完成的情况下回收了pbuf,那么这个pbuf可能会被再次使用。这样就破坏了pbuf中的上一次还未发完的数据,从而导致网络异常。解决方法就是在发送的时候调用协议栈提供的接口将pbuf引用计数加一,这样协议栈就不会主动去回收pbuf了,而在数据发送完成之后,用协议栈提供的接口将pbuf引用计数减一,这时协议栈才去回收pbuf。

3. 接收零拷贝

3.1 概述

网卡发送数据的时候会去设置缓冲区描述符中buffer的地址,因为发送是由协议栈主动发起的,对于系统而言是可控制的。但是接收就不一样了,因为网卡不知道何时回接收到数据,数据的到来对于系统来说是一个异步事件,所以必须在驱动初始化的阶段就设置好各个缓冲区描述符中buffer的地址,这样当接收到数据的时候,网卡就将数据放到缓冲区描述符对应的buffer中。

在非零拷贝的驱动中,内核中的pbuf是网络发送和接收共用的。在零拷贝驱动中,内核中的pbuf是发送专用,接收用的pbuf是通过另外的方式进行管理的。

3.2 接收用零拷贝池

使用接收零拷贝时,驱动需要调用协议栈提供的接口创建零拷贝池,零拷贝池示意图如下:

SylixOS网络开发(四)

零拷贝池中的一个结点主要由两部分组成:

  • pbuf head:这个就是用于管理pbuf的数据结构。
  • pbuf payload:这个是用于存放帧数据的缓冲区。

从图中还可以看出pbuf head的大小是cacheline大小对齐的,在32位平台上,pbuf head为36字节大小,cacheline对齐后为64字节。一个结点的典型设置值为2KB大小,也就是说payload区域的大小是1984字节。

3.3 零拷贝池中pbuf的申请和释放

在网络驱动初始化的时候需要从零拷贝池中申请pbuf,然后将pbuf中的payload地址赋值给相应的缓冲区描述符。当驱动中使用input方法将零拷贝池中的pbuf传递给协议栈处理完之后,协议栈会回收这个pbuf,所以在调用完input方法之后还需要再次从零拷贝池中申请pbuf并将payload赋值给缓冲区描述符。

3.4 接收零拷贝池的cache属性

一般而言,零拷贝池需要设置为带cache属性的,当然如果遇到问题,可以先设置为不带cache的以排查问题。当使用带cache的零拷贝池时,就需要注意payload区域的dma一致性问题了,在驱动中调用input方法将pbuf上送协议栈之前需要将payload区域对应的cache失效,以保证协议栈读取数据时payload中的数据是最新的。

gewenbin
  • 本文由 发表于 2020年12月26日19:55:09
  • 转载请务必保留本文链接:http://www.databusworld.cn/9847.html
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: