linux RX/TX环和sk_buff之间的关系是什么?

c6ubokkw  于 2023-03-01  发布在  Linux
关注(0)|答案(4)|浏览(158)

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

pnwntuvh

pnwntuvh1#

我想知道这个描述符是否指向sk_buff?
不完全是。sk_buff是一个软件构造,粗略地说,它是一个包含 * 元信息 * 的数据结构,用于 * 描述 * 某个网络数据块,并 * 指向 * 数据本身。因此,NIC描述符不需要指向sk_buff-它可能只指向一个 * 数据缓冲区 *(使用DMA/物理地址)。
如果数据包是GSO数据包,会发生什么情况?
这个问题很难回答,因为这样的卸载可以在软件中实现(比如说,通过网络堆栈),也可以在硬件中完成。
在前一种情况下,NIC SW描述符方面没有什么可讨论的-上层应用程序提供连续的数据块,网络堆栈从中产生较小的数据包,因此移交给网络驱动程序的sk_buff-s已经描述了小数据包。
在后一种情况下(硬件卸载)为网络驱动程序提供了大量数据块(通过将单个sk_buff-s或sk_buff链移交给它),并且网络驱动程序又将适当的描述符发布到NIC-它可能是指向一大块数据的一个描述符,或者少量描述符指向同一连续数据缓冲区的较小部分--这并不重要,因为卸载魔术将在硬件中发生--整个数据块将被分割,并且分组报头将被相应地预先挂起,从而产生要被放到线路上的许多较小的网络分组。
环中的一个描述符=一个数据包=一个sk_buff是真的吗?
严格地说,。这取决于。您的网络驱动程序可能会被要求传输一个描述一个数据缓冲区的sk_buff。但是,在某些情况下,您的驱动程序可能会决定发布指向同一数据块但偏移量不同的多个描述符-即提交将分部分完成,并且NIC环中将有多个描述符与单个sk_buff相关。此外,一个数据包并不总是与一个sk_buff相同-一个数据包可以表示为若干个 * 段 *,每个段用单独的sk_buff描述,形成sk_buff * 链 *(请在sk_buff中查找nextprev字段)。

sg3maiej

sg3maiej2#

Linux内核使用sk_buff数据结构来描述每个数据包。当数据包到达NIC时,它会调用DMA引擎,通过存储在称为rx_ring的环形缓冲区中的空sk_buff将数据包放入内核内存中。如果环形缓冲区已满,则会丢弃传入的数据包。当在更高层处理数据包时,数据包数据仍保留在同一内核内存中。避免任何额外的存储器复制。
http://www.ece.virginia.edu/cheetah/documents/papers/TCPlinux.pdf
最后一句话似乎表明传入的数据包数据被保存在内核内存的sk_buff结构体中,没有冗余,所以我可以说你的问题的答案是肯定的,这个描述符将指向一个sk_buff,而且是的,每个数据包都被放在rx_ring中它自己的sk_buff中。

gojuced7

gojuced73#

X1 M0 N1 X与物理网络接口无关(至少不直接)。X1 M1 N1 X列表存储套接字访问软件和内核协议处理程序(例如,当采用加密时,其操纵那些列表以添加/移除报头和/或更改数据)所看到的数据。
底层驱动程序负责将sk_buff列表内容转换为物理网络适配器可以理解的内容,特别是网络硬件可能非常笨拙(比如通过串行线进行联网),在这种情况下,驱动程序基本上会逐字节读取sk_buff列表并通过线路发送这些列表。
更高级的适配器通常能够执行分散/收集DMA -给定RAM中的地址列表,它们将能够访问每个地址,并从那里获得数据包数据或将接收到的数据放回。然而,此机制的确切细节在很大程度上取决于适配器,在许多情况下,甚至在单个供应商的产品之间也不一致。

hsvhsicv

hsvhsicv4#

我想知道这个描述符是否指向sk_buff?
答案是这取决于NIC驱动程序的实现,在b44(drivers/net/ethernet/broadcom/b44.c)这样的驱动程序中,它使用sk_buff作为DMA缓冲区,但在igb(drivers/net/ethernet/intel/igb/igb_main.c)这样的驱动程序中,它使用连续范围的页帧作为DMA缓冲区。
在b44中,当包到达时,如果包小,则分配新的sk_buffer,并将数据复制到该新的sk_buffer中,如果页面大,则将rx_ring中的sk_buffer传递到网络栈,并为rx_ring分配新的sk_buffer。
在igb中,当包到达时,分配一个新的sk_buff,sk_buff将引用dma缓冲区以避免内存复制。

相关问题