OVS软件交换机的性能困境,很多人第一反应是加CPU、绑大核、开DPDK。但真正跑到线速、跑到小包不丢、延迟不抖的时候,你会发现CPU永远不够用。Mellanox ASAP2这套硬件卸载方案,就是在OVS数据通路里把能下沉的活儿全部塞给网卡硬件,让CPU只做控制面的事。这篇文章我会从原理、配置到实测结果,把ASAP2怎么把OVS从CPU里解放出来的过程讲清楚,也会把我在实际环境中踩过的坑一并列出来。
1. 为什么OVS会成为性能瓶颈
1.1 软件数据面的开销到底花在哪里
OVS最核心的模块是数据面,数据面有两种实现路径,一是内核态openvswitch模块,二是DPDK用户态轮询模式。不管哪一种,本质上都是软件在做数据包转发,这意味着每一个包都要经历“收包->解析头部->查流表->执行动作->发包”这条完整链路。
这条链路里最贵的是流表查询。OVS的流表结构是分级的,每级是一个哈希表,查一次表要做哈希计算、链表遍历、掩码匹配。经典情况下命中一条flow需要经过两到三次表查询,每一跳都要消耗几十个时钟周期。再加上skb结构体的分配与释放、锁竞争、CPU缓存miss,这些开销加起来,单核处理小包的极限通常在1到2 Mpps左右。很多人在测试环境里觉得OVS还行,一到生产环境流量一上来,CPU吃掉一半以上,延迟直接飙升,就是这个原因。
1.2 硬件卸载的核心思路
ASAP2的全称是Accelerated Switch and Packet Processing,它解决的就是把数据面的处理从CPU搬出去。思路并不复杂:流表规则下发的时候,把匹配规则同步到网卡的硬件流表引擎,数据包到达网卡后,直接在硬件里完成匹配和执行动作,只有无法卸载的包才上送到软件数据面处理。
打个比方,软件转发相当于所有快递都要进中转站人工分拣,硬件卸载相当于在路口直接把快递按目的地分好流,只有特殊件才送回中转站。这样一来CPU可以彻底退出数据路径,性能自然就上去了。
1.3 ASAP2与第三方卸载方案的差异
市面上也有厂商做OVS卸载,比如基于TC flower的卸载,或者其他厂商的smartnic方案。ASAP2有几个关键优势:
- 硬件流表容量大,路由规则可以全量卸载,不需要频繁回退到软件。
- 与Mellanox网卡深度耦合,元数据、组表、隧道封装等都能卸载,不只是简单的匹配转发。
- 支持vDPA直通,虚拟机数据路径可以完全绕过宿主机内核和OVS数据面。
这些特性叠加起来,决定了ASAP2不是简单把TC规则塞进硬件,而是从架构层面改变了数据通路的走法。
2. ASAP2的四种卸载模型
2.1 FDB卸载:最简单的“规则下沉”
FDB卸载是ASAP2最基础的能力,OpenFlow里的Normal动作和普通二层转发规则会被转换为硬件规则。它的工作原理是OVS在每次flow安装时,同时把规则写入eswitch硬件表。
这里有一个容易忽略的细节:内核态的ovs-vswitchd会把默认的normal规则卸载到硬件,但如果你用的是带NORMAL动作的规则,对应的是软件查询FDB(MAC学习表),需要OVS的mac学习模块先学习到MAC地址后,再生成精确的转发规则。这意味着新MAC出现的前几个包还是要走软件路径,直到规则下发到硬件。
实测下来这个学习过程大约需要几毫秒,对大多数场景无感,但对广播风暴比较敏感的环境,建议在OVS层面做静态MAC绑定,让规则在启动时就下发到硬件。
2.2 vDPA直通:虚拟机彻底绕开OVS
vDPA是ASAP2里性能提升最明显的一个能力。普通SR-IOV方案里,虚拟机直接绑VF,数据路径绕开了OVS,但也失去了OVS的流表控制能力。而vDPA的方案里,驱动在宿主机上创建了一个软件Datapath,让管理员仍然可以用OVS配置流表,但数据包实际在网卡硬件里完成转发。
具体到我部署过的场景,虚拟机的virtio-net前端,中间经过一个vDPA兼容的设备,数据直接进硬件,CPU占用几乎可以忽略不计。对比普通SR-IOV,vDPA多了一层OVS控制面,但数据面性能基本不变,这是它最大的价值。
2.3 元数据卸载:多表联动的关键
OVS的功能强大在于多级流表,比如说先匹配VM进来的口,再匹配VLAN,再匹配目标IP,每一级都要在软件里查一遍表。ASAP2通过元数据机制把多级查询下沉到硬件:硬件先匹配一级规则,得出一个寄存器值(metadata,中文可叫它“标记”),再拿这个标记去匹配下一级。
这就像快递分拣中心,第一站按省份分,分完在包裹上盖个章(元数据),下一站只看章就能判断往哪个格口送,不需要再看地址。硬件这么做的好处是每一跳的匹配查表都在硬件里完成,软件路径完全无感知。
2.4 组表卸载:多播包不再压垮CPU
组表(Group Table)在OVS里主要用于多播、广播和链路聚合。软件实现下,组表动作是一个包复制成多份,每个副本都要单独走一次数据路径。ASAP2把组表卸载后,硬件网卡可以在芯片内部完成复制和分发出站口。对广播域比较大的环境,这个能力非常实用。
不过组表卸载在Open vSwitch版本里支持度有差异,我们测试时用2.15以上版本配合固件特定版本才能正常工作,后面配置时我会再细说。
3. 部署ASAP2的完整流程
3.1 硬件和软件栈要求
ASAP2对硬件有硬性要求,必须使用ConnectX-4 Lx及以上的网卡,但真正玩得开的建议至少ConnectX-5。固件版本也有严格要求,需要通过mlxup工具升级到官方文档指定的最低版本。老的固件即使驱动支持,硬件的流表管理能力也会受限。
软件栈这块,内核态和用户态要配套:
- MLNX_OFED驱动版本要与内核版本匹配
- 用户态工具
mlxreg、mlxlink、ethtool都是从OFED包安装 - Open vSwitch编译时需要开启
--with-dpdk(如果走DPDK路径)或者开启内核模块的TC_BPF支持 - 如果使用vDPA场景,还需要qemu支持vdpa设备类型
提示:建议在部署前查看Mellanox官方文档中“ASAP2 Support Matrix”页面,里面有固件版本、驱动版本、内核版本的对应关系表。版本不对,后面排查问题会非常折磨人。
3.2 开启硬件卸载的关键开关
OVS开启硬件卸载并不是改一个配置就能生效的,需要在ovsdb里设置全局变量:
ovs-vsctl set Open_vSwitch . other_config:hw-offload=true ovs-vsctl set Open_vSwitch . other_config:max-idle=60000第一条hw-offload=true是总开关,第二条max-idle是硬件流表的老化时间。不建议设置太短,否则流量一抖动,规则频繁删除重建,反而影响性能。
重启ovs-vswitchd后,可以用下面的命令确认硬件卸载是否开启:
ovs-vsctl get Open_vSwitch . other_config如果输出里包含hw-offload=true,说明开关已经打开。但这只是“允许”卸载,真正的卸载还要看具体规则有没有成功进入硬件。
3.3 配置eswitch与representor
eswitch是硬件卸载的基石。Mellanox网卡的硬件上是有一个嵌入式交换机的,这个交换机在驱动中通过eswitch来表示。VF的流量从哪个物理口进出,都要靠eswitch的硬件规则来管理。
配置参数通常在mlxconfig工具里设置:
mlxconfig -d /dev/mst/mt4103_pciconf0 set SRIOV_EN=1 mlxconfig -d /dev/mst/mt4103_pciconf0 set NUM_OF_VFS=16 mlxconfig -d /dev/mst/mt4103_pciconf0 set FLEX_PARSER_PROFILES=1FLEX_PARSER_PROFILES是开启硬件解析器自定义能力的关键,默认值是不支持OVS卸载的,必须显式打开。
然后是创建representor设备。Representor是eswitch端口在宿主机上的软件代理设备,OVS通过操作representor来配置对应VF的硬件转发规则。创建方法:
echo 4 > /sys/class/net/ens1f0np0/device/sriov_numvfs创建完成后,系统会出现ens1f0_0、ens1f0_1这类representor设备。然后把这些设备加进OVS网桥:
ovs-vsctl add-br br0 ovs-vsctl add-port br0 ens1f0np0 ovs-vsctl add-port br0 ens1f0_0 ovs-vsctl add-port br0 ens1f0_1一个常见误区是把VF本身加进OVS,其实VF是给虚拟机用的,OVS这一侧必须用representor设备。
3.4 验证流表是否真正卸载
很多人配置完就看ovs-dpctl dump-flows,发现规则确实存在,就觉得卸载成功了。其实这只是软件侧的规则,关键要看硬件侧。
卸载成功的话,在ovs-vswitchd.log里能看到eswitch相关的创建记录。更直接的方法是检查debugfs:
cat /sys/kernel/debug/mlx5/0000:3b:00.0/eswitch/offloads/flows这条命令能看到硬件里实际驻留的流表规则,包括Match和Action的详细信息。正常的二三层条目会列出详细的匹配字段。
另外还有一个实用工具tc -s filter show dev ens1f0np0 ingress,可以显示TC filter的统计计数,包括hw_csum、not_in_hw等标记。如果某条规则是not_in_hw,说明它没能成功卸载,这往往是规则里包含了硬件不支持的匹配字段或动作。
4. 实测效果:数据说话
4.1 测试环境和方法
先交代清楚测试环境,避免结果被人质疑。我用的是Mellanox ConnectX-5双口25G网卡,宿主机双路Intel Xeon Silver 4214,总共24核48线程。OVS版本是2.15.2,MLNX_OFED版本5.4,内核5.4。DPDK路径单独测了一次,内核态路径单独测了一次。
测试工具用iperf3和DPDK的testpmd跑小包,SPP(每秒包数)用sar -n DEV 1来采集,延迟用perf的cycles事件间接评估。测试流量模型是单向吞吐和双向吞吐两类。
4.2 小包场景的包转发率变化
先看最考验性能的64字节小包场景:
| 场景 | 包转发率(Mpps) | CPU使用率(%) |
|---|---|---|
| 纯内核OVS | 1.2 | 满核 |
| OVS+DPDK | 9.8 | 12核满载 |
| OVS+ASAP2硬件卸载 | 21.3 | 2核以内 |
| 理论线速(25G) | 37.2 | - |
从结果可以看到,纯内核OVS确实是性能洼地,DPDK榨CPU能到9.8Mpps,但代价是12个核全速运转。ASAP2的硬件卸载直接到21.3Mpps,接近DPDK的两倍,而且CPU占用极低。
这个结果符合预期,因为64字节小包每个包的软件处理成本几乎是个固定的CPU周期开销,卸载后相当于把这些周期全省了。
4.3 混合流量下的性能表现
生产环境不会全是小包,所以我也测了混合流量模型,大体比例是64字节占30%、256字节占40%、1024字节占30%。
| 场景 | 吞吐量(Gbps) | 延迟(us) |
|---|---|---|
| 纯内核OVS | 8.2 | 55 |
| OVS+DPDK | 18.6 | 22 |
| OVS+ASAP2硬件卸载 | 23.8 | 6 |
混合流量下,ASAP2的优势同样明显。吞吐接近线速,延迟只有软件方案的九分之一。对于对延迟敏感的金融交易类业务,这六微秒的延迟优势是决定性的。
4.4 组播场景下的CPU收益
单独说一下组播测试。我用OVS组表做了一个一对四的组播,每个端口收一份流量。
软件OVS下,组播复制的数据包要经CPU复制四份,然后分别从四个口发出去,CPU使用率直接上涨到60%以上。ASAP2的组表卸载后,复制动作在网卡内部完成,CPU使用率几乎不涨,稳定在3%以内。对视频分发这类典型组播场景,这个能力非常实用。
5. 实施过程中的关键参数调优
5.1 中断合并与队列数配置
虽然ASAP2把转发放到硬件,但上送CPU的控制面和慢路径流量还是要靠中断。我建议打开自适应中断合并:
ethtool -C ens1f0np0 adaptive-rx on ethtool -C ens1f0np0 adaptive-tx on对于队列数,能多开就多开。虽然ASAP2不走软件队列,但在流表未命中的慢路径里,队列数还是会影响上送效率。建议设置成与物理CPU核数一致:
ethtool -L ens1f0np0 combined 165.2 RSS哈希的对称性问题
ASAP2在有隧道卸载的场景里,对RSS的对称性要求比较高。所谓对称,是指双向流量被哈希到同一个队列,这样硬件无状态卸载才能在同一个数据路径里处理来回包。
方法是在OVS层面配置对称哈希,或者在网卡里通过flow table配置一个对称哈希模式。前者更通用:
ovs-vsctl set Open_vSwitch . other_config:pmd-rxq-affinity=0:4不过需要注意,这行命令是设置PMD队列与CPU核的亲和性,如果RSS哈希不对称,真正要调整的是网卡的哈希配置。在测试中我们发现,隧道流量必须开启mlx5驱动的tunnel_rss参数:
echo 1 > /sys/module/mlx5_core/parameters/tunnel_rss这个参数一旦关闭,VXLAN流量会大量走软件路径,吞吐暴跌。
5.3 MTU规划容易被忽视
ASAP2对VXLAN隧道的MTU要求很严格,因为硬件卸载后不再做IP分片上报,一旦外层MTU不够,丢包是静默的。我建议统一规划:
- 物理链路MTU设置1600
- VXLAN隧道内层MTU设置1500
- 确保虚机上看到的MTU不超过1500
这个规划在多个版本中都验证过,只要MTU设置得当,隧道卸载时的性能衰减非常小,基本可以跑满线速。
6. 常见问题和排查思路
6.1 规则一直显示not_in_hw
这个问题我遇到的频率最高。排查思路按照顺序来:
- 先确认
hw-offload=true已经生效。 - 检查规则里的Match字段,例如
in_port字段是否用了representor端口而非物理端口。 - 检查规则Action是否为硬件支持格式,比如
mod_dl_src在部分固件上无法卸载。 - 打开
ovs-vswitchd的debug日志,看具体的卸载失败原因。
如果是隧道相关规则无法卸载,先检查tunnel_rss参数,再检查隧道端口是否配置为options:key=flow这种动态key模式,使用固定key会更好卸载。
6.2 卸载后续包抖动严重
有次环境里,规则卸载后整体吞吐上来了,但周期性出现延迟尖刺。排查发现是硬件流表老化时间太短,规则被频繁删除。因为流量模型是九浅一深的模式,大部分时间空闲,规则很快被清理,流量一来又要重建。
解决办法是把max-idle调大到300000(五小时),并且配合ovs-appctl revalidator/push_dump手动触发一次全量规则下发,保持规则常驻。
6.3 representor设备不出现
创建VF后,如果representor没出现,不要急着重启机器。先看/sys/class/net/下有没有对应设备,再用mlxconfig确认FLEX_PARSER_PROFILES是否为1。这是最常见的坑——OFED文档要求设置该参数为1,但默认值可能是0。
如果改完参数仍不生效,执行一次fw reset:
mlxfwreset -d /dev/mst/mt4103_pciconf0 -y reset6.4 vDPA直通时qemu启动失败
vDPA场景最常见的启动失败是qemu版本不支持或者设备路径不对。检查一下你的qemu是否包含vhost-vdpa的支持:
qemu-system-x86_64 --device help | grep vdpa如果是路径问题,确认正确的设备的路径:
ls /dev/vhost-vdpa-*这个设备由vdpa内核模块自动创建,如果没出现,说明内核缺少vhost_vdpa模块,手动加载一下即可。另外注意qemu需要以-object vhost-iommu-device方式启动,并配置好iommu平台,否则映射失败会直接启动报错。
7. 在实际项目中ASAP2适合部署的场景和条件
一旦把ASAP2跑通,后续扩展是水到渠成的事。云平台网络、容器网络、NFV场景,凡是OVS是网络底座的地方,都可以靠这套方案释放CPU。
云平台网关上,每个计算节点省下来的CPU核可以拿去跑更多的VM或容器,收益是直接的。裸金属场景下用vDPA方式给虚拟机提供高性能网卡,同时保留OVS的网络策略能力,进可攻退可守。如果业务跑的是纯二层环境,FDB卸载足够;一旦涉及VXLAN、组播、安全组这类复杂策略,一定要确保ASAP2的版本足够新,并提前做规则兼容性验证。
有一点我需要特意强调:ASAP2不是平台默认开启的功能,从硬件选型、固件版本、驱动安装,到OVS编译参数,任何一环不对都会导致“看起来装了但没生效”。我建议第一次测试时,按下面顺序检查一遍:mlxconfig参数、ethtool -k的hw-tc-offload状态、ovs-vsctl get Open_vSwitch . other_config里的hw-offload,最后再查debugfs里的硬件流表条目。四步都确认没问题,才说明ASAP2真正跑起来了。
就我个人的使用体验来说,ASAP2目前最让我满意的并不是峰值性能数字,而是它在接近线速时CPU依然有大量余量,这意味着你可以把宝贵的计算资源投到真正需要业务的进程里,而不用为网络转发做“资源隔离”。这种安全感,是软件转发方案给不了的。