c - Using DPDK ring with primary and secondary processes - Stack Overflow

admin2025-04-21  2

I want to have 2 DPDK processes, primary and secondary.
The primary opens a ring using rte_ring_create() with the name myring.
Now, the secondary should be able to open the other side of that ring using rte_ring_lookup() as written here
26.1.2.2. How the Application Works

if (rte_eal_process_type() == RTE_PROC_PRIMARY){
    send_ring = rte_ring_create(_PRI_2_SEC, ring_size, rte_socket_id(), flags);
    recv_ring = rte_ring_create(_SEC_2_PRI, ring_size, rte_socket_id(), flags);
    message_pool = rte_mempool_create(_MSG_POOL, pool_size,
            STR_TOKEN_SIZE, pool_cache, priv_data_sz,
            NULL, NULL, NULL, NULL,
            rte_socket_id(), flags);
} else {
    recv_ring = rte_ring_lookup(_PRI_2_SEC);
    send_ring = rte_ring_lookup(_SEC_2_PRI);
    message_pool = rte_mempool_lookup(_MSG_POOL);
}

But, I want to be able to make the secondary process use the ring as if it was a regular interface device.
What I mean is, with DPDK params you're able to define physical ports and vdev ports using -a and --vdev=....

I want to give the ring myring as DPDK parameter as written here:

./dpdk-testpmd -l 1-3 -n 4 --vdev=net_ring0 --vdev=net_ring1 -- -i

Just, using --vdev=net_ringmyring.
I also tried calling the ring when creating it, in the primary process: net_ring_myring.

Nothing seem to work.
On the secondary process I get errors such as:

Device net_ring_myring is not driven by the primary process
rte_pmd_ring_probe(): Failed to probe net_ring_myring
vdev_probe(): failed to initialize net_ring_myring device
EAL: Bus (vdev) probe failed.

I want to have 2 DPDK processes, primary and secondary.
The primary opens a ring using rte_ring_create() with the name myring.
Now, the secondary should be able to open the other side of that ring using rte_ring_lookup() as written here
26.1.2.2. How the Application Works

if (rte_eal_process_type() == RTE_PROC_PRIMARY){
    send_ring = rte_ring_create(_PRI_2_SEC, ring_size, rte_socket_id(), flags);
    recv_ring = rte_ring_create(_SEC_2_PRI, ring_size, rte_socket_id(), flags);
    message_pool = rte_mempool_create(_MSG_POOL, pool_size,
            STR_TOKEN_SIZE, pool_cache, priv_data_sz,
            NULL, NULL, NULL, NULL,
            rte_socket_id(), flags);
} else {
    recv_ring = rte_ring_lookup(_PRI_2_SEC);
    send_ring = rte_ring_lookup(_SEC_2_PRI);
    message_pool = rte_mempool_lookup(_MSG_POOL);
}

But, I want to be able to make the secondary process use the ring as if it was a regular interface device.
What I mean is, with DPDK params you're able to define physical ports and vdev ports using -a and --vdev=....

I want to give the ring myring as DPDK parameter as written here:

./dpdk-testpmd -l 1-3 -n 4 --vdev=net_ring0 --vdev=net_ring1 -- -i

Just, using --vdev=net_ringmyring.
I also tried calling the ring when creating it, in the primary process: net_ring_myring.

Nothing seem to work.
On the secondary process I get errors such as:

Device net_ring_myring is not driven by the primary process
rte_pmd_ring_probe(): Failed to probe net_ring_myring
vdev_probe(): failed to initialize net_ring_myring device
EAL: Bus (vdev) probe failed.
Share Improve this question asked Jan 22 at 21:30 hudachudac 2,7988 gold badges40 silver badges64 bronze badges
Add a comment  | 

5 Answers 5

Reset to default 1

By the looks of it, the error being observed at the secondary process may come from rte_eth_dev_attach_secondary, which suggests that it might not be correct to create a ring device at the secondary process: that can only attach to an ethdev created at the primary one.

Also, it is most likely wrong to assume that --vdev=net_ringmyring can be used to pass some actual ring name in place of that myring part: that is an indivisible name that has been assigned to the device which the secondary process is trying to attach to.

As a quick suggestion, perhaps it pays to create the ring device at the primary process as follows

struct rte_ring *r_0, *r_1;
unsigned int flags = 0;
unsigned int sz = 1024;
int port_id;

r_0 = rte_ring_create("r_0", sz, rte_socket_id(), flags);
r_1 = rte_ring_create("r_1", sz, rte_socket_id(), flags);

port_id = rte_eth_from_rings("net_ring0", &r_0, 1, &r_1, 1, rte_socket_id());

/* (configure and start the port) */

and, also at the primary process, implement all of the logic that directly interacts with the rings, at the OP's discretion, whilst, at the secondary process, attach to the device and leverage regular ethdev APIs (such as rte_eth_rx_burst or rte_eth_tx_burst) to interact with traffic:

uint16_t port_id;

(void)rte_eal_hotplug_add("vdev", "net_ring0", "");
(void)rte_eth_dev_get_port_by_name("net_ring0", &port_id);

/* (interact with packet receive and transmit APIs, etc) */

For the secondary process, it might also be possible to use some existing tool (like test-pmd) and attach by means of passing the EAL argument (--vdev, as already described in the OP). That is worthwhile checking also.

Regarding the "buffer overflow detected" error (as indicated in the comment), that may come from the OP's application rather than from the DPDK. It's hard to tell why the error happens without seeing the actual code producing it.

The purpose of rte_eal_hotplug_add is to create a new ethdev or to attach to an existing one. In the secondary DPDK process context, only the latter is valid: attach. This method allows an application to create devices or to attach to devices on "when needed" basis, in contrast to probing devices at start of day, during EAL initialisation.

The example in the ring device documentation says nothing about secondary processes and (seemingly) assumes the primary process context. Should that be the case, rte_eal_hotplug_add is not needed because this very device is created not by EAL probe, but, due to its nature (involving the prior creation of a ring by the application), via rte_eth_from_rings.

The use of --vdev net_ring0 with EAL does not necessarily involve rte_eal_hotplug_add. That rather relies on EAL-internal stack of bus probe functions, in this particular case, for vdev bus. On the other hand, rte_eal_hotplug_add is a public API and it's meant for dynamic attach during runtime, perhaps after EAL has long initialised, hence the name: hotplug. But these are just two different methods to do the same thing: create a device or attach to a device.

Yes, the use of test-pmd for the secondary process might prove difficult, as it might indeed assume the primary process also being test-pmd, with a well-known mbuf pool name. Perhaps try proc-info instead.

Yes, the segfault (as shown in the comment) may be caused by some unrelated code. In order to prevent PCI devices from ever being probed, consider to pass --no-pci argument in the EAL section.

As for the EAL: failed to parse device, that could mean the bus was not found. It may happen when the library supporting the bus in question has not been linked. Consider to add deps += ['bus_vdev'] to meson.build of the program used for the secondary process and then rebuild.

With regard to the latest comment, the issue with applications like test-pmd is that, albeit designed with support for the secondary process in mind, they somehow expect the same application to be used both in the primary and secondary roles (hence test-pmd's failure to look up the mempool by name, — it did not match the one in the primary process), whereas for other applications (like l2fwd), the issue is that they, seemingly, aren't designed to support the secondary process at all.

The key moment to this is that the secondary process is not supposed to conduct any control path actions, like mempool creation (basically, creation of any objects in the hugepage memory is not allowed in that context) and device configuration. It can only attach to an already configured datapath and use Rx/Tx methods (for traffic) and statistic retrieval APIs.

Consider to study the secondary process generic workflow and come up with a custom application to use in the secondary role that would just attach to the port (by doing look-ups on the shared objects such as queues and mempools), with all steps that do not make sense in that role omitted.

转载请注明原文地址:http://anycun.com/QandA/1745227610a90486.html