Ray*_*yne 10 linux rss windows-installer packet dma
我一直在读关于NIC捕获数据包后会发生什么,我读的越多,我就越困惑.
首先,我已经读过,传统上,在NIC捕获数据包之后,它会被复制到内核空间中的内存块,然后被复制到用户空间,以用于处理数据包数据的任何应用程序.然后我读到了DMA,其中NIC直接将数据包复制到内存中,绕过CPU.那么NIC - >内核内存 - >用户空间内存流仍然有效吗?此外,大多数NIC(例如Myricom)是否使用DMA来提高数据包捕获率?
其次,RSS(Receive Side Scaling)在Windows和Linux系统中的工作方式是否相似?我只能找到关于RSS如何在MSDN文章中工作的详细解释,他们在这里讨论RSS(和MSI-X)如何在Windows Server 2008上运行.但RSS和MSI-X的相同概念应该仍然适用于Linux系统,对吧?
谢谢.
此致,Rayne
Ste*_*sen 14
这个过程如何发挥主要取决于驱动程序作者和硬件,但对于我看过或写过的驱动程序以及我使用的硬件,这通常是它的工作方式:
内核中的零拷贝网络并不是那么糟糕.零拷贝一直到用户区要困难得多.Userland获取数据,但网络数据包由标头和数据组成.至少,真正的零拷贝一直到用户区需要来自NIC的支持,以便它可以将数据包DMA分成单独的头/数据缓冲区.一旦内核将数据包路由到目的地并且验证校验和(对于TCP,如果NIC支持它,则在硬件中,或者如果不支持,则在软件中),标题将被回收;请注意,如果内核必须自己计算校验和,则需要也可以复制数据:查看数据导致缓存未命中并将其复制到其他地方可以免费使用调优代码).
即使假设所有星星都对齐,当系统接收到数据时,数据实际上并不在您的用户缓冲区中.在应用程序请求数据之前,内核不知道它将在何处结束.考虑像Apache这样的多进程守护进程的情况.有许多子进程,都在同一个套接字上侦听.您还可以建立连接,fork()
并且两个进程都能够recv()
传入数据.
因特网上的TCP分组通常是1460字节的有效载荷(1500的MTU = 20字节的IP报头+ 20字节的TCP报头+ 1460字节的数据).1460不是2的幂,与您找到的任何系统上的页面大小都不匹配.这给重组数据流带来了问题.请记住,TCP是面向流的.发送器写入之间没有区别,并且在接收到的两个1000字节写入将在2000字节读取中完全消耗.
进一步考虑用户缓冲区.这些是由应用程序分配的.为了完全用于零拷贝,缓冲区需要页面对齐,不要与其他任何内容共享该内存页面.当时recv()
,内核理论上可以用包含数据的旧页面重新映射旧页面并将其"翻转"到位,但由于上面的重组问题,这很复杂,因为连续的数据包将在不同的页面上.内核可能会将数据限制回每个数据包的有效负载,但这意味着需要进行大量额外的系统调用,页面重新映射以及总体上较低的吞吐量.
我真的只是在谈论这个话题.我在21世纪初曾在几家公司工作,试图将零拷贝概念扩展到用户区.我们甚至在userland中实现了一个TCP堆栈,并完全为使用堆栈的应用程序规避了内核,但这带来了一系列问题并且从未产生过生产质量.这是一个非常难以解决的问题.
Stb*_*Stb -1
看看这篇论文,http://www.ece.virginia.edu/cheetah/documents/papers/TCPlinux.pdf它可能有助于解决一些内存管理问题