DPDK主从进程共享ring:将ring作为vdev设备调用失败求助
解决DPDK主从进程中ring转虚拟网口的问题
错误原因
你遇到的问题核心是:手动调用rte_ring_create()创建的ring只是一个内存队列对象,并没有被注册为DPDK的net_ring虚拟网口设备。从进程用--vdev=net_ring_xxx启动时,EAL会在主进程的虚拟设备列表中查找对应设备,找不到就会触发探针失败的错误。
正确实现方案
方案1:主进程启动时通过--vdev创建net_ring设备(推荐)
这种方式最符合DPDK的设计逻辑,无需手动编码创建ring:
主进程启动参数:
在主进程的启动命令中添加--vdev参数直接创建net_ring虚拟网口,示例:./primary_app -l 0-1 --vdev=net_ring0,rx_ring_sz=1024,tx_ring_sz=1024参数说明:
rx_ring_sz/tx_ring_sz指定收发队列的大小,可根据需求调整。主进程中获取ring(可选):
如果主进程需要直接操作底层ring,可通过ring名称查找:// net_ring的rx ring命名规则:net_ring<dev_id>_rx_<queue_id> struct rte_ring *rx_ring = rte_ring_lookup("net_ring0_rx_0"); struct rte_ring *tx_ring = rte_ring_lookup("net_ring0_tx_0");从进程操作虚拟网口:
从进程启动时无需添加--vdev参数,直接枚举网口并像普通物理网口一样初始化、收发:uint16_t port_id; // 通过设备名获取端口ID rte_eth_dev_get_port_by_name("net_ring0", &port_id); // 初始化网口(常规DPDK网口初始化流程) struct rte_eth_conf port_conf = RTE_ETH_CONF_DEFAULT; rte_eth_dev_configure(port_id, 1, 1, &port_conf); rte_eth_dev_start(port_id);
方案2:主进程动态创建ring并注册为net_ring设备
如果必须在主进程代码中动态创建ring,需要将其注册为net_ring虚拟设备:
主进程代码实现:
// 1. 创建rx和tx ring(建议分开创建,避免收发冲突) struct rte_ring *rx_ring = rte_ring_create("my_rx_ring", 1024, rte_socket_id(), RING_F_SP_ENQ | RING_F_SC_DEQ); struct rte_ring *tx_ring = rte_ring_create("my_tx_ring", 1024, rte_socket_id(), RING_F_SP_ENQ | RING_F_SC_DEQ); // 2. 将ring注册为net_ring虚拟设备 int ret = rte_vdev_init("net_ring_myring", "rx_ring=my_rx_ring,tx_ring=my_tx_ring"); if (ret != 0) { rte_exit(EXIT_FAILURE, "Failed to register net_ring device\n"); }从进程操作虚拟网口:
从进程启动时无需添加--vdev参数,直接通过设备名查找端口,执行常规网口初始化流程即可,代码同方案1的从进程部分。
注意事项
- 不要在从进程中使用
--vdev=net_ring_xxx参数,因为虚拟设备由主进程创建并管理,从进程只需枚举使用即可。 net_ringPMD的命名规则是固定的,手动创建ring时要确保注册vdev时指定的ring名称与实际创建的ring名称完全一致。- 主进程必须先启动并完成vdev注册,再启动从进程,否则从进程无法枚举到对应的虚拟网口。
内容的提问来源于stack exchange,提问作者hudac
相关产品推荐
相关产品推荐

