假设我想避免linux内核处理传入数据包的开销,而是希望直接从用户空间获取数据包。我已经google了一下,似乎所有需要发生的事情就是使用带有一些套接字选项的原始套接字。是这样的吗?或者它比这更复杂?如果是这样,我可以谷歌或参考什么来实现这样的东西?
答案 0 :(得分:10)
有许多与内核旁路联网的技术。
首先,如果您要将消息发送到同一台计算机上的另一个进程,则可以通过共享内存区域执行此操作,而不会跳转到内核中。
通过网络传递数据包而不涉及内核变得更加有趣,并涉及可直接访问用户内存的专用硬件。这个想法叫做RDMA。
这是它可以工作的一种方式(这就是InfiniBand硬件所做的)。应用程序使用RDMA硬件注册内存缓冲区。此缓冲区固定在物理内存中,因为将其交换出来显然会很糟糕(因为硬件将继续写入物理内存区域)。控制区域也映射到用户空间存储器。当应用程序准备好使用缓冲区发送或接收消息时,它会将命令写入控制区域。硬件从一端的注册缓冲区获取数据,并将其放入另一端的另一个注册缓冲区。
显然,这个级别太低了,因此有一些抽象可以让编程RDMA硬件变得更容易。 OFED动词就是这样一种抽象。
InfiniBand软件堆栈有一个额外的有趣位:套接字直接协议(SDP),用于与现有应用程序兼容。它的工作原理是插入一个LD_PRELOAD垫片,将标准套接字API调用转换为IB动词。
InfiniBand正是我最熟悉的。从程序员的角度来看,RoCE / iWARP硬件非常相似,但使用的运输方式与InfiniBand不同(TCP使用iWarp中的卸载引擎,RoCE中的以太网)。 RDMA还有其他方法(例如,Quadrics)。