RSS,RPS和RFS之间的主要区别是什么?

时间:2017-07-06 20:43:00

标签: linux performance networking tcp linux-kernel

众所周知,有:https://www.kernel.org/doc/Documentation/networking/scaling.txt

  • RSS:接收侧缩放
  • RPS:接收数据包指导
  • RFS:接收流量转向

这是否意味着:

  • RSS - 允许我们使用许多CPU内核来处理来自以太网的Soft-irq(每个以太网队列一个CPU-Core)
  • RPS - 允许我们处理来自同一CPU-Core上同一连接的所有数据包的Soft-irq
  • RFS - 允许我们处理来自同一个连接上的所有数据包的Soft-irq,在同一个CPU-Core上,我们的应用程序的线程接受此连接

这是对的吗?

2 个答案:

答案 0 :(得分:5)

报价来自https://www.kernel.org/doc/Documentation/networking/scaling.txt

  • RSS:接收侧缩放 - 是硬件实现并散列一些字节的数据包(“通过网络和/或传输层标头的散列函数 - 例如,通过IP地址和数据包的TCP端口的4元组散列“)。实现是不同的,有些可能不会过滤最有用的字节,或者可能以其他方式受到限制。这种过滤和队列分配很快(在分组中只需要几个额外的周期来分类),但在某些网卡之间不能移植,或者不能与隧道数据包或一些罕见的协议一起使用。有时,您的硬件不支持足够的队列数,以便为每个逻辑CPU核心获得一个队列。
  

当延迟是一个问题或接收时,应启用RSS   中断处理形成了瓶颈。在CPU之间传播负载   减少队列长度。

  • 接收数据包控制(RPS)“在逻辑上是一个软件实现 RSS。在软件中,它必须在数据路径中稍后调用。“。因此,当您使用没有RSS的硬件或想要基于更多的分类时,这是硬件RSS的替代软件(仍解析一些字节以将它们哈希到队列ID中)复杂规则比hw可以或者具有无法在HW RSS分类器中解析的协议。但是使用RPS会占用更多的CPU资源并且还有额外的CPU间流量。
  

RPS比RSS有一些优势:1)它可以与任何NIC一起使用,   2)软件过滤器可以很容易地添加到新协议的哈希,   3)它不会增加硬件设备中断率(尽管它确实如此)   引入处理器间中断(IPI))。

  • RFS:接收流指导就像RSS(具有更多CPU开销的软件机制),但它不仅仅是散列到伪随机队列ID中,而是“考虑应用程序本地性”。 (因此,由于良好的局部性,数据包处理可能会更快)。跟踪队列将更加本地处理将处理接收数据的线程,并将数据包传送到正确的CPU核心。
  

RFS的目标是通过转向增加数据压缩率   内核处理数据包到应用程序线程所在的CPU   消耗数据包正在运行。 RFS依赖于相同的RPS机制   将数据包排入另一个CPU的积压并唤醒它   中央处理器。 ...在RFS中,数据包不会直接通过其散列值转发,   但是散列用作流查找表的索引。此表映射   流向正在处理这些流的CPU。

  • 加速RFS - 支持hw的RFS。 (检查您的网络驱动程序ndo_rx_flow_steer)“加速RFS是RFS到RPS的RSS:硬件加速的负载平衡机制,它使用软状态来控制流程,根据应用程序线程消耗每个流的数据包的位置正在运行。“。

用于数据包传输的类似方法(但数据包已经生成并准备好发送,只需选择最佳队列发送它 - 以及更容易的后处理,如释放skb)

  • XPS:传输数据包控制:“从CPU到硬件队列的映射是 记录。此映射的目标通常是分配队列 专门用于CPU的子集,其中发送完成 这些队列在此集合“
  • 中的CPU上处理

答案 1 :(得分:3)

osgx的回答涵盖了主要的不同之处,但重要的是要指出也可以同时使用RSS和RPS。

RSS控制所选的HW队列以接收数据包流。一旦满足某些条件,就会向SW发出中断。由NIC的驱动程序定义的中断处理程序将是处理接收的数据包的SW起始点。那里的代码将轮询来自相关接收队列的数据包,可能会执行初始处理,然后移动数据包以进行更高级别的协议处理。

此时可能会使用RPS机制(如果已配置)。驱动程序调用netif_receive_skb(),它最终将检查RPS配置。如果存在,它会将SKB排队以继续处理所选的CPU:

int netif_receive_skb(struct sk_buff *skb)
{
        ...
        return netif_receive_skb_internal(skb);
}

static int netif_receive_skb_internal(struct sk_buff *skb)
{
        ...
                int cpu = get_rps_cpu(skb->dev, skb, &rflow);

                if (cpu >= 0) {
                        ret = enqueue_to_backlog(skb, cpu, &rflow->last_qtail);
                        rcu_read_unlock();
                        return ret;
                }
        ...
}

在某些情况下,将RSS和RPS结合使用可以很聪明,以避免接收端的CPU利用率瓶颈。一个很好的例子是IPoIB(IP over Infiniband)。在没有深入细节的情况下,IPoIB有一种只能打开单个频道的模式。这意味着所有传入流量都将由单个核心处理。通过正确配置RPS,可以由多个内核共享一些处理负载,从而显着提高此方案的性能。

由于提到了传输,值得注意的是,接收过程(ACK,转发)产生的数据包传输将由netif_receive_skb()选择的同一核处理。

希望这有帮助。