This patch has the same problem, however the core->CPU change seems to have affected this one non-trivially. Not sure what the correct resync is since the patch window is narrow here.
On Thu, Jan 8, 2015 at 10:07 AM, Stuart Haslam <[email protected]> wrote: > 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 55e4ef4..241b95d 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_core; > int core_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, core, > thr_run_func, > &gbl_args->thread[i]); > } > -- > 2.1.1 > > > > _______________________________________________ > lng-odp mailing list > [email protected] > http://lists.linaro.org/mailman/listinfo/lng-odp >
_______________________________________________ lng-odp mailing list [email protected] http://lists.linaro.org/mailman/listinfo/lng-odp
