RX/TX环和sk_buff有什么关系?

What is the relationship between RX/TX ring and sk_buff?

我知道每个 NIC 在 RAM 中都有其 RX/TX 环用于 OS receiving/transmitting 数据包。环中的一项(数据包描述符)包括数据包的物理地址,数据包长度等。我想知道这个描述符是否指向sk_buff?如果数据包是 GSO 数据包会发生什么?环中的一个描述符 = 一个数据包 = 一个 sk_buff 是真的吗?

sk_buff 与物理网络接口无关(至少不直接)。 sk_buff 列表存储数据,如套接字访问软件和内核协议处理程序所见(它们操纵这些列表以 add/remove headers and/or 改变数据,例如,当采用加密时)。

低级别 driver 有责任将 sk_buff 列表内容翻译成物理网络适配器可以理解的内容。特别是,网络硬件可能非常笨拙(比如通过串行线路进行联网),在这种情况下 driver 基本上会逐字节读取 sk_buff 列表并通过线路发送。

更高级的适配器通常能够执行 scatter/gather DMA - 给定 RAM 中的地址列表,它们将能够访问每个地址并从那里获取数据包数据或将接收到的数据放回.然而,此机制的确切细节在很大程度上是特定于适配器的,在许多情况下甚至在单个供应商的产品之间也不一致。

The Linux kernel uses an sk_buff data structure to describe each packet. When a packet arrives at the NIC, it invokes the DMA engine to place the packet into the kernel memory via empty sk_buff's stored in a ring buffer called rx_ring . An incoming packet is dropped if the ring buffer is full. When a packet is processed at higher layers, packet data remains in the same kernel memory, avoiding any extra memory copies.

http://www.ece.virginia.edu/cheetah/documents/papers/TCPlinux.pdf

最后一句话似乎表明传入的数据包数据以 sk_buff 结构保存在内核内存中,没有冗余。所以我会说你的问题的答案是肯定的,该描述符将指向 sk_buff。是的,每个数据包都放在它自己的 sk_buff 中 rx_ring。

I wonder that does this descriptor point to a sk_buff?

不完全是。 sk_buff is a software construct, roughly, a data structure containing meta information to describe some chunk of network data AND point to the data 本身。因此,NIC 描述符不需要指向 sk_buff - 它可能只指向 数据缓冲区 (使用 DMA/physical 地址)。

And what happens if the packet is a GSO packet?

这个问题很难回答,因为这样的卸载可以在软件中实现(例如,通过网络堆栈),也可以在硬件中完成。

在前一种情况下,就 NIC SW 描述符而言没有什么可讨论的 - 上层应用程序提供连续的数据块,网络堆栈从中产生较小的数据包,因此 sk_buff-交给网络驱动程序的已经描述了小数据包。

在后一种情况(HW 卸载)中,网络驱动程序被提供了大量的数据(通过将单个 sk_buff-s 或 sk_buff 链移交给它),并且网络驱动程序反过来 post 对 NIC 的适当描述符 - 它可能是一个指向一大块数据的描述符,或者是指向同一连续数据缓冲区的较小部分的少数描述符 - 这无关紧要很多,因为卸载魔术将发生在硬件中——整个数据块将被切片,数据包头将相应地添加到前面,从而产生许多较小的网络数据包,以将其放在线上。

Is this true that one descriptor in the ring = one packet = one sk_buff?

严格来说,没有。这取决于。您的网络驱动程序可能会被要求传输一个 sk_buff 来描述一个数据缓冲区。但是,在某些情况下,您的驱动程序可能会决定 post 多个描述符指向相同的数据块但具有不同的偏移量 - 即提交将分部分完成,并且 NIC 环中将有多个描述符与单个数据相关sk_buff。此外,一个数据包并不总是与一个 sk_buff 相同 - 一个数据包可能表现为少数 ,每个段用单独的 sk_buff 描述,形成 sk_buff (请在sk_buff中找到nextprevfields)。