10GbE be2net 低包性能

10GbE be2net 低包性能

我正在测试两个工作站的网络性能,每个工作站都有 2.4GHz Xeon 四核处理器和 NC550SFP PCIe 双端口 10GbE 服务器适配器,背靠背连接。

我检查了 RAM 的带宽,约为 12Gbps,因此这里没有瓶颈。PCIe 总线速度也还可以。

我正在使用 UDP 的最小数据包大小测试最大 pps,结果与这些相比很糟糕:2012-lpc-networking-qdisc-fastabend.pdf(抱歉,我只能发布一个链接)。如果我增加数据包大小和 MTU,我可以获得接近线速(~9.9Gbps)。

我正在使用带有 NST 脚本的 pktgen、用于多个线程的 macvlan 接口,但只获得 ~1Mpps,所有四个核心都达到了 100%。

为了提高pktgen的TX性能,我偶然发现了这个文档: Linux 网络堆栈的扩展

我已经检查过并且是的,我有 mq qdiscs,它应该能产生最高的性能:

# ip link list | grep eth3
5: eth3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000

我认为问题在于只使用了一个TX队列:

# dmesg | grep be2net
[    4.528058] be2net 0000:01:00.1: irq 47 for MSI/MSI-X
[    4.528066] be2net 0000:01:00.1: irq 48 for MSI/MSI-X
[    4.528073] be2net 0000:01:00.1: irq 49 for MSI/MSI-X
[    4.528079] be2net 0000:01:00.1: irq 50 for MSI/MSI-X
[    4.528104] be2net 0000:01:00.1: enabled 4 MSI-x vector(s)
[    4.696026] be2net 0000:01:00.1: created 4 RSS queue(s) and 1 default RX queue
[    4.761108] be2net 0000:01:00.1: created 1 TX queue(s)

我得到了关于如何启用多个 TX 队列的提示Linux 网络堆栈的扩展

支持多队列的 NIC 的驱动程序通常提供内核模块参数或指定要配置的硬件队列数。例如,在 bnx2x 驱动程序中,此参数称为 num_queues。如果设备支持足够的队列,则典型的 RSS 配置是为每个 CPU 配备一个接收队列,否则为每个内存域配备至少一个接收队列,其中内存域是一组共享特定内存级别(L1、L2、NUMA 节点等)的 CPU。

我查看了 Emulex 的 be2net 驱动程序文档,甚至给他们发了一封电子邮件,但毫无进展。我还浏览了内核源代码。

我在 Ubuntu 12.04 上获得了最新的内核版本(3.10),并且在 NIC 上安装了最新的固件。

有人有想法吗?

谢谢!

答案1

我在 Red Hat Enterprise Linux 机器上遇到了类似的挑战。我读了同一篇论文,并得出结论,我真正的问题是默认使用所有可能的 IRQ 让每个 CPU 参与网络数据包工作。我将 IRQ 活动集中到可用核心的子集,然后相应地引导工作。这是 rc.local 文件:

# Reserve CPU0 as the default default IRQ handler
for IRQ in `grep eth0 /proc/interrupts | cut -d ':' -f 1`; do echo 2 > /proc/irq/$IRQ/smp_affinity; done
for IRQ in `grep eth1 /proc/interrupts | cut -d ':' -f 1`; do echo 2 > /proc/irq/$IRQ/smp_affinity; done
for IRQ in `grep eth2 /proc/interrupts | cut -d ':' -f 1`; do echo 2 > /proc/irq/$IRQ/smp_affinity; done
for IRQ in `grep eth4 /proc/interrupts | cut -d ':' -f 1`; do echo $(( (($IRQ & 1) + 1) << 2 )) > /proc/irq/$IRQ/smp_affinity; done

这是 cgrules.conf 文件,它定义/区分我的 apache web 服务器和 10gbe,以便可以按预期实现严重的网络吞吐量:

apache      cpuset,cpu  apache/

下面是 cgconfig.conf 文件,它实际上将服务器与其余 CPU 活动分开:

mount {
    cpuset  = /cgroup/cpuset;
    cpu = /cgroup/cpu;
    cpuacct = /cgroup/cpuacct;
    memory  = /cgroup/memory;
    devices = /cgroup/devices;
    freezer = /cgroup/freezer;
    net_cls = /cgroup/net_cls;
    blkio   = /cgroup/blkio;
}

group apache {
    cpuset {
        cpuset.memory_spread_slab="0";
        cpuset.memory_spread_page="0";
        cpuset.memory_migrate="0";
        cpuset.sched_relax_domain_level="-1";
        cpuset.sched_load_balance="1";
        cpuset.mem_hardwall="0";
        cpuset.mem_exclusive="0";
        cpuset.cpu_exclusive="0";
        cpuset.mems="1";
        cpuset.cpus="4-7,12-15";
    }
}

group apache {
    cpu {
        cpu.rt_period_us="1000000";
        cpu.rt_runtime_us="0";
        cpu.cfs_period_us="100000";
        cpu.cfs_quota_us="-1";
        cpu.shares="1024";
    }
}

在默认配置下(没有 IRQ 和 cgroups hack),我测量到的网络吞吐量约为 5Gb/s。在 IRQ 集中且随机网络 IO 移开后,我使用 netperf 测量到接近线速(9.5Gb/s)的性能。

nb 巨型数据包没有任何区别,无论是之前还是之后的数字。

相关内容