Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 捕获数据包后会发生什么?_Linux_Rss_Windows Installer_Packet_Dma - Fatal编程技术网

Linux 捕获数据包后会发生什么?

Linux 捕获数据包后会发生什么?,linux,rss,windows-installer,packet,dma,Linux,Rss,Windows Installer,Packet,Dma,我一直在读NIC捕获数据包后会发生什么,读得越多,我就越困惑 首先,我了解到,传统上,NIC捕获数据包后,它会被复制到内核空间中的内存块中,然后复制到用户空间,用于处理数据包数据的任何应用程序。然后我读了DMA,NIC绕过CPU直接将数据包复制到内存中。那么NIC->内核内存->用户空间内存流是否仍然有效?此外,大多数NIC(如Myricom)是否使用DMA来提高数据包捕获率 其次,RSS(接收端缩放)在Windows和Linux系统中的工作方式是否相似?我只能在MSDN文章中找到关于RSS如何

我一直在读NIC捕获数据包后会发生什么,读得越多,我就越困惑

首先,我了解到,传统上,NIC捕获数据包后,它会被复制到内核空间中的内存块中,然后复制到用户空间,用于处理数据包数据的任何应用程序。然后我读了DMA,NIC绕过CPU直接将数据包复制到内存中。那么NIC->内核内存->用户空间内存流是否仍然有效?此外,大多数NIC(如Myricom)是否使用DMA来提高数据包捕获率

其次,RSS(接收端缩放)在Windows和Linux系统中的工作方式是否相似?我只能在MSDN文章中找到关于RSS如何工作的详细解释,其中讨论了RSS(和MSI-X)如何在WindowsServer2008上工作。但是RSS和MSI-X的相同概念应该仍然适用于linux系统,对吗

多谢各位

问候,,
Rayne

看看这篇文章,它可能有助于解决一些内存管理问题

这个过程如何进行主要取决于驱动程序作者和硬件,但对于我看过或写过的驱动程序以及我使用过的硬件,通常是这样的:

  • 在驱动程序初始化时,它将分配一些缓冲区,并将这些缓冲区分配给NIC
  • 当NIC接收到一个数据包时,它会将下一个地址从缓冲区列表中拉出来,直接将数据存储到数据包中,并通过中断通知驱动程序
  • 驱动程序得到中断,可以将缓冲区转换到内核,也可以分配一个新的内核缓冲区并复制数据。“零拷贝网络”是前者,显然需要操作系统的支持。(下文将对此进行详细介绍)
  • 驱动程序需要分配一个新的缓冲区(在零拷贝的情况下),或者重新使用该缓冲区。在任何一种情况下,缓冲区都会返回给NIC以备将来使用
  • 内核中的零拷贝网络并没有那么糟糕。零拷贝一直到userland要困难得多。Userland获取数据,但网络数据包由报头和数据组成。至少,真正的零拷贝一直到userland需要NIC的支持,以便它可以将DMA数据包放入单独的报头/数据缓冲区。一旦内核将数据包路由到其目的地并验证校验和,就可以循环使用报头(对于TCP,无论是在硬件中(如果NIC支持它),还是在软件中(如果不支持它);请注意,如果内核必须自己计算校验和,它也可以复制数据:查看数据会导致缓存未命中,在其他地方复制数据可以免费使用调优代码)

    即使假设所有的恒星都对齐,当系统接收到数据时,数据实际上并不是在你的用户缓冲区中。直到应用程序请求数据时,内核才知道它将在何处结束。考虑多进程守护进程类Apache的情况。有很多子进程,都在同一个套接字上监听。也可以建立。一个连接,

    fork()
    ,两个进程都能够
    recv()
    传入数据

    Internet上的TCP数据包通常是1460字节的有效负载(1500的MTU=20字节IP头+20字节TCP头+1460字节数据).1460不是2的幂,在任何系统上都与页面大小不匹配。这会给数据流的重新组装带来问题。请记住,TCP是面向流的。发送方写入之间没有区别,在接收端等待的两个1000字节写入将在2000字节的读取中完全消耗

    进一步考虑,用户缓冲区,这些都是由应用程序分配的。为了被零拷贝一路使用,缓冲区需要是页面对齐的,不与任何其他页面共享内存。在<代码> ReVE()/代码>时间,内核可以理论上重新映射旧页面和包含数据的页面。将其“翻转”到位,但由于上面的重新组装问题,这是复杂的,因为连续的数据包将位于单独的页面上。内核可能会将其交回的数据限制在每个数据包的有效负载上,但这将意味着大量额外的系统调用、页面重新映射以及整体吞吐量可能会降低


    在这个话题上,我只是触及了表面。在21世纪初,我曾在几家公司工作,试图将零拷贝的概念扩展到userland。我们甚至在userland中实现了TCP堆栈,并完全绕过了内核,用于使用该堆栈的应用程序,但这带来了它自己的一系列问题,而且从来没有产生过效果n质量。这是一个很难解决的问题。

    谷歌的零拷贝网络…现在很少有高速设备能够容忍内核和用户的双重拷贝。IANANG(我不是网络大师)但我相信DMA被积极使用。所以,现在,一旦NIC捕获数据包,它就会被直接复制到(用户)内存?@Rayne是的;NIC将使用DMA将数据直接传输到映射到进程(userland)地址空间的物理内存中。你为什么要问?你想实现什么?+1表示零拷贝。它现在已经广泛使用了好几天。