Also fix an incorrect assumption that the value of a pktio handle is
an integer starting at 0 and incrementing by 1 for each _open call,
which was previously true for linux-generic but has no guarantee on
other platforms.

Signed-off-by: Stuart Haslam <[email protected]>
---
 example/l2fwd/odp_l2fwd.c | 302 ++++++++++++++++++++--------------------------
 1 file changed, 128 insertions(+), 174 deletions(-)

diff --git a/example/l2fwd/odp_l2fwd.c b/example/l2fwd/odp_l2fwd.c
index c8cc87e..209b0bd 100644
--- a/example/l2fwd/odp_l2fwd.c
+++ b/example/l2fwd/odp_l2fwd.c
@@ -14,6 +14,7 @@
 #include <string.h>
 #include <getopt.h>
 #include <unistd.h>
+#include <errno.h>
 
 #include <example_debug.h>
 
@@ -69,173 +70,70 @@ typedef struct {
        int if_count;           /**< Number of interfaces to be used */
        char **if_names;        /**< Array of pointers to interface names */
        int mode;               /**< Packet IO mode */
-       int type;               /**< Packet IO type */
-       int fanout;             /**< Packet IO fanout */
-       odp_buffer_pool_t pool; /**< Buffer pool for packet IO */
 } appl_args_t;
 
 /**
  * Thread specific arguments
  */
 typedef struct {
-       char *srcif;            /**< Source Interface */
-       char *dstif;            /**< Dest Interface */
-       odp_buffer_pool_t pool; /**< Buffer pool for packet IO */
-       odp_pktio_t srcpktio;   /**< Source pktio handle */
-       odp_pktio_t dstpktio;   /**< Destination pktio handle */
-       int mode;               /**< Thread mode */
-       int type;               /**< Thread i/o type */
-       int fanout;             /**< Thread i/o fanout */
+       int src_idx;
 } thread_args_t;
 
 /**
- * Grouping of both parsed CL args and thread specific args - alloc together
+ * Grouping of all global data
  */
 typedef struct {
        /** Application (parsed) arguments */
        appl_args_t appl;
        /** Thread specific arguments */
        thread_args_t thread[MAX_WORKERS];
+       /** Table of pktio handles */
+       odp_pktio_t pktios[ODP_CONFIG_PKTIO_ENTRIES];
 } args_t;
 
 /** Global pointer to args */
 static args_t *gbl_args;
-/** Number of worker threads */
-static int num_workers;
 
 /* helper funcs */
+static inline odp_queue_t lookup_dest_q(odp_packet_t pkt);
 static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned len);
 static void parse_args(int argc, char *argv[], appl_args_t *appl_args);
 static void print_info(char *progname, appl_args_t *appl_args);
 static void usage(char *progname);
 
 /**
- * @fn static burst_mode_init_params(void *arg, odp_buffer_pool_t pool)
- *
- * Burst mode: pktio for each thread will be created with either same or
- * different params
- *
- * @param arg  thread arguments of type 'thread_args_t *'
- * @param pool is the packet pool from where buffers should be taken
- *
- * @return odp_pktio_t ODP packet IO handle
- */
-static odp_pktio_t burst_mode_init_params(void *arg, odp_buffer_pool_t pool)
-{
-       thread_args_t *args;
-       odp_pktio_t pktio;
-
-       args = arg;
-       /* Open a packet IO instance for this thread */
-       pktio = odp_pktio_open(args->srcif, pool);
-       if (pktio == ODP_PKTIO_INVALID)
-               EXAMPLE_ERR("  Error: pktio create failed");
-
-       return pktio;
-}
-
-/**
- * @fn queue_mode_init_params(void *arg, odp_buffer_pool_t pool)
- *
- * Queue mode: pktio for each thread will be created with either same or
- * different params. Queues are created and attached to the pktio.
- *
- * @param arg  thread arguments of type 'thread_args_t *'
- * @param pool is the packet pool from where buffers should be taken
- *
- * @return odp_pktio_t ODP packet IO handle
- */
-static odp_pktio_t queue_mode_init_params(void *arg, odp_buffer_pool_t pool)
-{
-       char inq_name[ODP_QUEUE_NAME_LEN];
-       odp_queue_param_t qparam;
-       odp_queue_t inq_def;
-       int ret;
-       odp_pktio_t pktio = ODP_PKTIO_INVALID;
-
-       pktio = burst_mode_init_params(arg, pool);
-       if (pktio == ODP_PKTIO_INVALID)
-               return pktio;
-       /*
-        * Create and set the default INPUT queue associated with the 'pktio'
-        * resource
-        */
-       qparam.sched.prio  = ODP_SCHED_PRIO_DEFAULT;
-       qparam.sched.sync  = ODP_SCHED_SYNC_ATOMIC;
-       qparam.sched.group = ODP_SCHED_GROUP_DEFAULT;
-       snprintf(inq_name, sizeof(inq_name), "%i-pktio_inq_def", (int)pktio);
-       inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0';
-
-       inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_PKTIN, &qparam);
-       if (inq_def == ODP_QUEUE_INVALID) {
-               EXAMPLE_ERR("  Error: pktio queue creation failed");
-               return ODP_PKTIO_INVALID;
-       }
-
-       ret = odp_pktio_inq_setdef(pktio, inq_def);
-       if (ret != 0) {
-               EXAMPLE_ERR("  Error: default input-Q setup");
-               return ODP_PKTIO_INVALID;
-       }
-
-       return pktio;
-}
-
-/**
  * Packet IO worker thread using ODP queues
  *
  * @param arg  thread arguments of type 'thread_args_t *'
  */
 static void *pktio_queue_thread(void *arg)
 {
-       int thr, i;
-       thread_args_t *thr_args;
-       char dstpktio[MAX_WORKERS+1];
+       int thr;
        odp_queue_t outq_def;
        odp_packet_t pkt;
        odp_buffer_t buf;
        unsigned long pkt_cnt = 0;
        unsigned long err_cnt = 0;
 
-       thr = odp_thread_id();
-       thr_args = arg;
+       (void)arg;
 
-       if (thr_args->srcpktio == 0 || thr_args->dstpktio == 0) {
-               EXAMPLE_ERR("Invalid srcpktio:%d dstpktio:%d\n",
-                           thr_args->srcpktio, thr_args->dstpktio);
-               return NULL;
-       }
-       printf("[%02i] srcif:%s dstif:%s spktio:%02i dpktio:%02i QUEUE mode\n",
-              thr, thr_args->srcif, thr_args->dstif, thr_args->srcpktio,
-              thr_args->dstpktio);
+       thr = odp_thread_id();
 
-       /* Populate an array of destination pktio's in all threads as the
-        * scheduler can take packets from any input queue
-        */
-       for (i = 0; i < num_workers; i++)
-               dstpktio[i+1] = gbl_args->thread[i].dstpktio;
+       printf("[%02i] QUEUE mode\n", thr);
 
        /* Loop packets */
        for (;;) {
-               odp_pktio_t pktio_tmp;
-
                /* Use schedule to get buf from any input queue */
                buf = odp_schedule(NULL, ODP_SCHED_WAIT);
-
                pkt = odp_packet_from_buffer(buf);
+
                /* Drop packets with errors */
                if (odp_unlikely(drop_err_pkts(&pkt, 1) == 0)) {
                        EXAMPLE_ERR("Drop frame - err_cnt:%lu\n", ++err_cnt);
                        continue;
                }
 
-               pktio_tmp = odp_packet_input(pkt);
-               outq_def = odp_pktio_outq_getdef(dstpktio[pktio_tmp]);
-               if (outq_def == ODP_QUEUE_INVALID) {
-                       EXAMPLE_ERR("  [%02i] Error: def output-Q query\n",
-                                   thr);
-                       return NULL;
-               }
+               outq_def = lookup_dest_q(pkt);
 
                /* Enqueue the packet for output */
                odp_queue_enq(outq_def, buf);
@@ -251,6 +149,29 @@ static void *pktio_queue_thread(void *arg)
 }
 
 /**
+ * Lookup the destination pktio for a given packet
+ */
+static inline odp_queue_t lookup_dest_q(odp_packet_t pkt)
+{
+       int i, src_idx, dst_idx;
+       odp_pktio_t pktio_src, pktio_dst;
+
+       pktio_src = odp_packet_input(pkt);
+
+       for (src_idx = -1, i = 0; gbl_args->pktios[i] != ODP_PKTIO_INVALID; ++i)
+               if (gbl_args->pktios[i] == pktio_src)
+                       src_idx = i;
+
+       if (src_idx == -1)
+               EXAMPLE_ABORT("Failed to determine pktio input\n");
+
+       dst_idx = (src_idx % 2 == 0) ? src_idx+1 : src_idx-1;
+       pktio_dst = gbl_args->pktios[dst_idx];
+
+       return odp_pktio_outq_getdef(pktio_dst);
+}
+
+/**
  * Packet IO worker thread using bursts from/to IO resources
  *
  * @param arg  thread arguments of type 'thread_args_t *'
@@ -264,42 +185,50 @@ static void *pktio_ifburst_thread(void *arg)
        unsigned long pkt_cnt = 0;
        unsigned long err_cnt = 0;
        unsigned long tmp = 0;
+       int src_idx, dst_idx;
+       odp_pktio_t pktio_src, pktio_dst;
 
        thr = odp_thread_id();
        thr_args = arg;
 
-       if (thr_args->srcpktio == 0 || thr_args->dstpktio == 0) {
-               EXAMPLE_ERR("Invalid srcpktio:%d dstpktio:%d\n",
-                           thr_args->srcpktio, thr_args->dstpktio);
-               return NULL;
-       }
+       src_idx = thr_args->src_idx;
+       dst_idx = (src_idx % 2 == 0) ? src_idx+1 : src_idx-1;
+       pktio_src = gbl_args->pktios[src_idx];
+       pktio_dst = gbl_args->pktios[dst_idx];
+
        printf("[%02i] srcif:%s dstif:%s spktio:%02i dpktio:%02i BURST mode\n",
-              thr, thr_args->srcif, thr_args->dstif, thr_args->srcpktio,
-              thr_args->dstpktio);
+              thr,
+              gbl_args->appl.if_names[src_idx],
+              gbl_args->appl.if_names[dst_idx],
+              pktio_src, pktio_dst);
 
        /* Loop packets */
        for (;;) {
-               pkts = odp_pktio_recv(thr_args->srcpktio, pkt_tbl,
-                                       MAX_PKT_BURST);
-               if (pkts > 0) {
-                       /* Drop packets with errors */
-                       pkts_ok = drop_err_pkts(pkt_tbl, pkts);
-                       if (pkts_ok > 0)
-                               odp_pktio_send(thr_args->dstpktio, pkt_tbl,
-                                              pkts_ok);
-                       if (odp_unlikely(pkts_ok != pkts))
-                               EXAMPLE_ERR("Dropped frames:%u - err_cnt:%lu\n",
-                                           pkts-pkts_ok, ++err_cnt);
-
-                       /* Print packet counts every once in a while */
-                       tmp += pkts_ok;
-                       if (odp_unlikely((tmp >= 100000) || /* OR first print:*/
-                           ((pkt_cnt == 0) && ((tmp-1) < MAX_PKT_BURST)))) {
-                               pkt_cnt += tmp;
-                               printf("  [%02i] pkt_cnt:%lu\n", thr, pkt_cnt);
-                               fflush(NULL);
-                               tmp = 0;
-                       }
+               pkts = odp_pktio_recv(pktio_src, pkt_tbl, MAX_PKT_BURST);
+               if (pkts <= 0)
+                       continue;
+
+               /* Drop packets with errors */
+               pkts_ok = drop_err_pkts(pkt_tbl, pkts);
+               if (pkts_ok > 0)
+                       odp_pktio_send(pktio_dst, pkt_tbl, pkts_ok);
+
+               if (odp_unlikely(pkts_ok != pkts)) {
+                       err_cnt += pkts-pkts_ok;
+                       EXAMPLE_ERR("Dropped frames:%u - err_cnt:%lu\n",
+                                   pkts-pkts_ok, err_cnt);
+               }
+
+               if (pkts_ok == 0)
+                       continue;
+
+               /* Print packet counts every once in a while */
+               tmp += pkts_ok;
+               if (odp_unlikely(tmp >= 100000 || pkt_cnt == 0)) {
+                       pkt_cnt += tmp;
+                       tmp = 0;
+                       printf("  [%02i] pkt_cnt:%lu\n", thr, pkt_cnt);
+                       fflush(NULL);
                }
        }
 
@@ -307,6 +236,51 @@ static void *pktio_ifburst_thread(void *arg)
 }
 
 /**
+ * Create a pktio handle, optionally associating a default input queue.
+ */
+static odp_pktio_t create_pktio(const char *dev, odp_buffer_pool_t pool,
+                               int mode)
+{
+       char inq_name[ODP_QUEUE_NAME_LEN];
+       odp_queue_param_t qparam;
+       odp_queue_t inq_def;
+       odp_pktio_t pktio;
+       int ret;
+
+       pktio = odp_pktio_open(dev, pool);
+       if (pktio == ODP_PKTIO_INVALID) {
+               EXAMPLE_ERR("Error: failed to open %s\n", dev);
+               return ODP_PKTIO_INVALID;
+       }
+
+       printf("created pktio %d (%s)\n", pktio, dev);
+
+       /* no further setup needed for burst mode */
+       if (mode == APPL_MODE_PKT_BURST)
+               return pktio;
+
+       qparam.sched.prio  = ODP_SCHED_PRIO_DEFAULT;
+       qparam.sched.sync  = ODP_SCHED_SYNC_ATOMIC;
+       qparam.sched.group = ODP_SCHED_GROUP_DEFAULT;
+       snprintf(inq_name, sizeof(inq_name), "%i-pktio_inq_def", (int)pktio);
+       inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0';
+
+       inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_PKTIN, &qparam);
+       if (inq_def == ODP_QUEUE_INVALID) {
+               EXAMPLE_ERR("Error: pktio queue creation failed\n");
+               return ODP_PKTIO_INVALID;
+       }
+
+       ret = odp_pktio_inq_setdef(pktio, inq_def);
+       if (ret != 0) {
+               EXAMPLE_ERR("Error: default input-Q setup\n");
+               return ODP_PKTIO_INVALID;
+       }
+
+       return pktio;
+}
+
+/**
  * ODP L2 forwarding main function
  */
 int main(int argc, char *argv[])
@@ -316,7 +290,7 @@ int main(int argc, char *argv[])
        int i;
        int first_cpu;
        int cpu_count;
-       odp_pktio_t pktio;
+       int num_workers;
        odp_shm_t shm;
        odp_buffer_pool_param_t params;
 
@@ -395,39 +369,16 @@ int main(int argc, char *argv[])
        }
        odp_buffer_pool_print(pool);
 
-       memset(thread_tbl, 0, sizeof(thread_tbl));
-       /* initialize threads params */
-       for (i = 0; i < num_workers; ++i) {
-               int src_idx, dst_idx;
-               thread_args_t *thr_args = &gbl_args->thread[i];
-
-               src_idx = i % gbl_args->appl.if_count;
-               dst_idx = (src_idx % 2 == 0) ? src_idx+1 : src_idx-1;
+       for (i = 0; i < gbl_args->appl.if_count; ++i) {
+               gbl_args->pktios[i] = create_pktio(gbl_args->appl.if_names[i],
+                                                  pool, gbl_args->appl.mode);
+               if (gbl_args->pktios[i] == ODP_PKTIO_INVALID)
+                       exit(EXIT_FAILURE);
+       }
+       gbl_args->pktios[i] = ODP_PKTIO_INVALID;
 
-               thr_args->srcif = gbl_args->appl.if_names[src_idx];
-               thr_args->dstif = gbl_args->appl.if_names[dst_idx];
-               thr_args->pool  = pool;
-               thr_args->mode  = gbl_args->appl.mode;
+       memset(thread_tbl, 0, sizeof(thread_tbl));
 
-               if (gbl_args->appl.mode == APPL_MODE_PKT_BURST) {
-                       pktio = burst_mode_init_params(thr_args, pool);
-                       if (pktio == ODP_PKTIO_INVALID) {
-                               EXAMPLE_ERR("  for thread:%02i\n", i);
-                               exit(EXIT_FAILURE);
-                       }
-               } else { /* APPL_MODE_PKT_QUEUE */
-                       pktio = queue_mode_init_params(thr_args, pool);
-                       if (pktio == ODP_PKTIO_INVALID) {
-                               EXAMPLE_ERR("  for thread:%02i\n", i);
-                               exit(EXIT_FAILURE);
-                       }
-               }
-               gbl_args->thread[i].srcpktio = pktio;
-       }
-       for (i = 0; i < num_workers; ++i) {
-               int idx = (i % 2 == 0) ? i+1 : i-1;
-               gbl_args->thread[i].dstpktio = gbl_args->thread[idx].srcpktio;
-       }
        /* Create worker threads */
        for (i = 0; i < num_workers; ++i) {
                void *(*thr_run_func) (void *);
@@ -439,6 +390,9 @@ int main(int argc, char *argv[])
                        thr_run_func = pktio_ifburst_thread;
                else /* APPL_MODE_PKT_QUEUE */
                        thr_run_func = pktio_queue_thread;
+
+               gbl_args->thread[i].src_idx = i % gbl_args->appl.if_count;
+
                odph_linux_pthread_create(&thread_tbl[i], 1, cpu, thr_run_func,
                                          &gbl_args->thread[i]);
        }
-- 
2.1.1



_______________________________________________
lng-odp mailing list
[email protected]
http://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to