[dpdk-users] Attaching to an ethernet port from a secondary process

Lazaros Koromilas l at nofutznetworks.com
Wed Feb 17 12:40:02 CET 2016


On Wed, Feb 17, 2016 at 1:17 PM, Lazaros Koromilas <l at nofutznetworks.com> wrote:
> Hi all,
>
> I'm trying to take advantage of the multi-process support together
> with the port hotplugging framework. The idea is that my primary
> process will configure all ports I'm going to need and then secondary
> processes will come up, selectively attach to ports and perform rx/tx.
> I succeed up to the point that I attach to the pre-configured ports
> but the rx/tx queue descriptors are uninitialized, so I get a segfault
> there. This can be reproduced with the attached, slightly modified
> examples/skeleton/basicfwd.c sdk app. I run this as follows:
>
> sudo ./build/basicfwd -l0 -n2 --proc-type=primary --vdev
> eth_pcap0,rx_pcap=pcap0-in.pcap,tx_pcap=pcap0-out.pcap --vdev
> eth_pcap1,rx_pcap=pcap1-in.pcap,tx_pcap=pcap1-out.pcap
> sudo ./build/basicfwd -l2 -n2 --proc-type=secondary
> eth_pcap0,rx_pcap=pcap0-in.pcap,tx_pcap=pcap0-out.pcap
> eth_pcap1,rx_pcap=pcap1-in.pcap,tx_pcap=pcap1-out.pcap
>
> Where pcap{0,1}-in.pcap files are pcap dumps. The primary will
> initialize the ports and pause(2). The secondary will attach to the
> same ports and do work. The latter then segfaults in
> rte_eth_rx_burst() with dev->data->{rx,tx}_queues being NULL pointers.
>
> All privileged operations are done from the primary. As far as I can
> tell, these are all functions in librte_ether that need to run in a
> primary process:
> grep -B12 PROC_PRIMARY_ rte_ethdev.c | grep '^rte_eth' | sed 's/(.*//'
> rte_eth_dev_rx_queue_start
> rte_eth_dev_rx_queue_stop
> rte_eth_dev_tx_queue_start
> rte_eth_dev_tx_queue_stop
> rte_eth_dev_configure
> rte_eth_dev_start
> rte_eth_dev_stop
> rte_eth_dev_set_link_up
> rte_eth_dev_set_link_down
> rte_eth_dev_close
> rte_eth_rx_queue_setup
> rte_eth_tx_queue_setup
>
> Any hints are much appreciated.
>
> Thanks!
> Lazaros.

I'm pasting the diff here, so that it exists in the archives too.

--- basicfwd.c.orig 2016-02-16 19:31:26.279293811 +0200
+++ basicfwd.c  2016-02-17 13:28:28.717350548 +0200
@@ -33,6 +33,7 @@

 #include <stdint.h>
 #include <inttypes.h>
+#include <unistd.h>
 #include <rte_eal.h>
 #include <rte_ethdev.h>
 #include <rte_cycles.h>
@@ -174,6 +175,7 @@ main(int argc, char *argv[])
    struct rte_mempool *mbuf_pool;
    unsigned nb_ports;
    uint8_t portid;
+   int i;

    /* Initialize the Environment Abstraction Layer (EAL). */
    int ret = rte_eal_init(argc, argv);
@@ -183,29 +185,47 @@ main(int argc, char *argv[])
    argc -= ret;
    argv += ret;

+   if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
+       /* Attach to ports in app command line. */
+       for (i = 1; i < argc; i++) {
+           printf("Port name %s\n", argv[i]);
+           ret = rte_eth_dev_attach(argv[i], &portid);
+           if (ret < 0)
+               rte_exit(EXIT_FAILURE, "Could not attach to %s\n", argv[i]);
+           printf("Attached to port %s with id %u\n", argv[i], portid);
+       }
+   }
+
    /* Check that there is an even number of ports to send/receive on. */
    nb_ports = rte_eth_dev_count();
    if (nb_ports < 2 || (nb_ports & 1))
        rte_exit(EXIT_FAILURE, "Error: number of ports must be even\n");

-   /* Creates a new mempool in memory to hold the mbufs. */
-   mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS * nb_ports,
-       MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
-
-   if (mbuf_pool == NULL)
-       rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
-
-   /* Initialize all ports. */
-   for (portid = 0; portid < nb_ports; portid++)
-       if (port_init(portid, mbuf_pool) != 0)
-           rte_exit(EXIT_FAILURE, "Cannot init port %"PRIu8 "\n",
-                   portid);
+   if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+       /* Creates a new mempool in memory to hold the mbufs. */
+       mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS * nb_ports,
+           MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
+
+       if (mbuf_pool == NULL)
+           rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
+
+       /* Initialize all ports. */
+       for (portid = 0; portid < nb_ports; portid++)
+           if (port_init(portid, mbuf_pool) != 0)
+               rte_exit(EXIT_FAILURE, "Cannot init port %"PRIu8 "\n",
+                       portid);
+   }

    if (rte_lcore_count() > 1)
        printf("\nWARNING: Too many lcores enabled. Only 1 used.\n");

-   /* Call lcore_main on the master core only. */
-   lcore_main();
+   if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+       /* Wait here forever. */
+       pause();
+   } else {
+       /* Call lcore_main on the master core only. */
+       lcore_main();
+   }

    return 0;
 }


More information about the users mailing list