2

我已经阅读了很多关于接收端缩放 (RSS)、接收数据包控制 (RPS) 和类似技术的内容,但我对如何在我的程序中实际使用这些技术感到茫然,即将传入的数据包在不同的线程/进程。

我确实知道 PF_RING,但我想 Linux 内核本身必须有一些基本支持。毕竟,例如,Interl 在其网站上吹嘘其 RSS 技术并声称支持 Linux。此外,RPS 不在 PF_RING 的范围内。我不愿意使用 PF_RING 的另一个原因是他们已经修补了网络驱动程序,而其中一些修补过的驱动程序似乎已经过时了。

我已经广泛地搜索了这个主题,但我发现最好的是关于启用 RSS 或 RPS 支持,而不是我如何以编程方式使用它们。

4

1 回答 1

2

内核 3.19 引入了 SO_INCOMING_CPU 套接字选项。这样,该进程就可以确定数据包最初被传递到哪个 CPU。

RPS/RFS 的替代方案是对多队列使用硬件支持。

然后将一组百万个套接字拆分为工作线程,每个工作线程使用 epoll() 来管理自己的套接字池上的事件。

理想情况下,我们希望每个 RX/TX 队列/cpu 有一个线程,但是在接受()或 connect()之后,我们无法知道套接字在哪个队列/cpu 上管理。

我们通常每个 RX 队列使用一个 cpu(IRQ smp_affinity 已正确设置),因此记住 cpu 传递最后一个数据包的套接字结构足以解决问题。

在 accept()、connect() 甚至文件描述符传递进程之后,应用程序可以使用:

诠释中央处理器;socklen_t len = sizeof(cpu);

getsockopt(fd, SOL_SOCKET, SO_INCOMING_CPU, &cpu, &len);

并使用此信息将套接字放入正确的筒仓以获得最佳性能,因为所有网络堆栈都应在适当的 cpu 上运行,而无需发送 IPI (RPS/RFS)。

[ https://patchwork.ozlabs.org/patch/408257/][1]

于 2015-07-22T12:15:41.083 回答