This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "".
The branch, master has been updated via 634b380b63de53c65b92c214d91aaf03785d69db (commit) via b1749baf2590f402ba3cbd23385b9056c99f3839 (commit) via a37fda78cb7c7d4804c0d9ae1c67801977ce1de5 (commit) via 0fe531c4ec9d49f562f91056eab29f81b98f63f6 (commit) via 8bd76909bea5d4d3a7917d00269a493628c96d5e (commit) via 4c23114ed39db175beaa317f63b782fad02b2c6f (commit) from 88fd84e7e613ce93fc078320b312d2aa8c388a8c (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- commit 634b380b63de53c65b92c214d91aaf03785d69db Author: Matias Elo matias.elo@nokia.com Date: Wed Jan 3 13:52:09 2018 +0200
test: l2fwd: improve cache usage
Rearrange thread local fast path data to improve cache usage. Increases maximum throughput by ~10% in direct pktio mode (dpdk zero-copy).
Signed-off-by: Matias Elo matias.elo@nokia.com Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c index 27b29939..2353e241 100644 --- a/test/performance/odp_l2fwd.c +++ b/test/performance/odp_l2fwd.c @@ -137,12 +137,10 @@ typedef union { } stats_t ODP_ALIGNED_CACHE;
/** - * Thread specific arguments + * Thread specific data */ typedef struct thread_args_t { - int thr_idx; - int num_pktio; - int num_groups; + stats_t stats;
struct { odp_pktin_queue_t pktin; @@ -158,24 +156,22 @@ typedef struct thread_args_t { /* Groups to join */ odp_schedule_group_t group[MAX_PKTIOS];
- /* Pointer to per thread stats */ - stats_t *stats; - + int thr_idx; + int num_pktio; + int num_groups; } thread_args_t;
/** * Grouping of all global data */ typedef struct { + /** Thread specific arguments */ + thread_args_t thread[MAX_WORKERS]; /** Barriers to synchronize main and workers */ odp_barrier_t init_barrier; odp_barrier_t term_barrier; - /** Per thread packet stats */ - stats_t stats[MAX_WORKERS]; /** Application (parsed) arguments */ appl_args_t appl; - /** Thread specific arguments */ - thread_args_t thread[MAX_WORKERS]; /** Table of port ethernet addresses */ odph_ethaddr_t port_eth_addr[MAX_PKTIOS]; /** Table of dst ethernet addresses */ @@ -322,7 +318,7 @@ static int run_worker_sched_mode(void *arg) odp_pktout_queue_t pktout[MAX_PKTIOS]; odp_queue_t tx_queue[MAX_PKTIOS]; thread_args_t *thr_args = arg; - stats_t *stats = thr_args->stats; + stats_t *stats = &thr_args->stats; int use_event_queue = gbl_args->appl.out_mode; pktin_mode_t in_mode = gbl_args->appl.in_mode;
@@ -464,7 +460,7 @@ static int run_worker_plain_queue_mode(void *arg) odp_queue_t tx_queue; int pktio = 0; thread_args_t *thr_args = arg; - stats_t *stats = thr_args->stats; + stats_t *stats = &thr_args->stats; int use_event_queue = gbl_args->appl.out_mode; int i;
@@ -592,7 +588,7 @@ static int run_worker_direct_mode(void *arg) odp_queue_t tx_queue; int pktio = 0; thread_args_t *thr_args = arg; - stats_t *stats = thr_args->stats; + stats_t *stats = &thr_args->stats; int use_event_queue = gbl_args->appl.out_mode;
thr = odp_thread_id(); @@ -849,12 +845,12 @@ static int create_pktio(const char *dev, int idx, int num_rx, int num_tx, * Print statistics * * @param num_workers Number of worker threads - * @param thr_stats Pointer to stats storage + * @param thr_stats Pointers to stats storage * @param duration Number of seconds to loop in * @param timeout Number of seconds for stats calculation * */ -static int print_speed_stats(int num_workers, stats_t *thr_stats, +static int print_speed_stats(int num_workers, stats_t **thr_stats, int duration, int timeout) { uint64_t pkts = 0; @@ -882,9 +878,9 @@ static int print_speed_stats(int num_workers, stats_t *thr_stats, sleep(timeout);
for (i = 0; i < num_workers; i++) { - pkts += thr_stats[i].s.packets; - rx_drops += thr_stats[i].s.rx_drops; - tx_drops += thr_stats[i].s.tx_drops; + pkts += thr_stats[i]->s.packets; + rx_drops += thr_stats[i]->s.rx_drops; + tx_drops += thr_stats[i]->s.tx_drops; } if (stats_enabled) { pps = (pkts - pkts_prev) / timeout; @@ -1471,7 +1467,7 @@ int main(int argc, char *argv[]) odph_ethaddr_t new_addr; odp_pool_param_t params; int ret; - stats_t *stats; + stats_t *stats[MAX_WORKERS]; int if_count; int (*thr_run_func)(void *); odp_instance_t instance; @@ -1641,8 +1637,6 @@ int main(int argc, char *argv[])
memset(thread_tbl, 0, sizeof(thread_tbl));
- stats = gbl_args->stats; - odp_barrier_init(&gbl_args->init_barrier, num_workers + 1); odp_barrier_init(&gbl_args->term_barrier, num_workers + 1);
@@ -1669,7 +1663,7 @@ int main(int argc, char *argv[]) gbl_args->thread[i].num_groups = 1; gbl_args->thread[i].group[0] = group[i % num_groups];
- gbl_args->thread[i].stats = &stats[i]; + stats[i] = &gbl_args->thread[i].stats;
odp_cpumask_zero(&thd_mask); odp_cpumask_set(&thd_mask, cpu);
commit b1749baf2590f402ba3cbd23385b9056c99f3839 Author: Bogdan Pricope bogdan.pricope@linaro.org Date: Tue Jan 9 11:50:19 2018 +0200
example: generator: replace L3/L4 packet parsing with a simple one
Platform packet parsing is providing information not needed by this application while consuming cycles. Replacing platform packet parsing with a limited parsing may increase performance on RX side.
Signed-off-by: Bogdan Pricope bogdan.pricope@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c index 586c3ede..f8c787e4 100644 --- a/example/generator/odp_generator.c +++ b/example/generator/odp_generator.c @@ -572,6 +572,12 @@ static int create_pktio(const char *dev, odp_pool_t pool, itf->config.pktout.bit.udp_chksum = 0; }
+ itf->config.parser.layer = ODP_PROTO_LAYER_L2; + if (itf->config.pktin.bit.udp_chksum) + itf->config.parser.layer = ODP_PROTO_LAYER_L4; + else if (itf->config.pktin.bit.ipv4_chksum) + itf->config.parser.layer = ODP_PROTO_LAYER_L3; + if (odp_pktio_config(itf->pktio, &itf->config)) { EXAMPLE_ERR("Error: Failed to set interface configuration %s\n", dev); @@ -781,11 +787,12 @@ static int gen_send_thread(void *arg) */
static void process_icmp_pkt(int thr, thread_args_t *thr_args, - odph_icmphdr_t *icmp) + uint8_t *_icmp) { uint64_t trecv; uint64_t tsend; uint64_t rtt_ms, rtt_us; + odph_icmphdr_t *icmp = (odph_icmphdr_t *)_icmp;
if (icmp->type == ICMP_ECHOREPLY) { thr_args->counters.ctr_icmp_reply_rcv++; @@ -818,18 +825,12 @@ static void process_pkts(int thr, thread_args_t *thr_args, { odp_packet_t pkt; odp_packet_chksum_status_t csum_status; - char *buf; + uint32_t left, offset, i; odph_ipv4hdr_t *ip; - odph_icmphdr_t *icmp; - unsigned i;
for (i = 0; i < len; ++i) { pkt = pkt_tbl[i];
- /* only ip pkts */ - if (!odp_packet_has_ipv4(pkt)) - continue; - csum_status = odp_packet_l3_chksum_status(pkt); if (csum_status == ODP_PACKET_CHKSUM_BAD) printf("L3 checksum error detected.\n"); @@ -842,20 +843,36 @@ static void process_pkts(int thr, thread_args_t *thr_args, if (odp_unlikely(odp_packet_has_error(pkt))) continue;
+ offset = odp_packet_l3_offset(pkt); + left = odp_packet_len(pkt) - offset; + + if (left < sizeof(odph_ipv4hdr_t)) + continue; + + ip = (odph_ipv4hdr_t *)((uint8_t *)odp_packet_data(pkt) + + offset); + + /* only ip pkts */ + if (ODPH_IPV4HDR_VER(ip->ver_ihl) != ODPH_IPV4) + continue; + thr_args->counters.ctr_pkt_rcv++; - buf = odp_packet_data(pkt); - ip = (odph_ipv4hdr_t *)(buf + odp_packet_l3_offset(pkt));
/* udp */ - if (ip->proto == ODPH_IPPROTO_UDP) + if (ip->proto == ODPH_IPPROTO_UDP) { thr_args->counters.ctr_udp_rcv++; + } else if (ip->proto == ODPH_IPPROTO_ICMPV4) { + uint32_t l3_size = ODPH_IPV4HDR_IHL(ip->ver_ihl) * 4; + + offset += l3_size; + left -= l3_size;
- /* icmp */ - if (ip->proto == ODPH_IPPROTO_ICMPV4) { - icmp = (odph_icmphdr_t *)(buf + - odp_packet_l4_offset(pkt)); + if (left < sizeof(odph_icmphdr_t)) + continue;
- process_icmp_pkt(thr, thr_args, icmp); + process_icmp_pkt(thr, thr_args, + (uint8_t *)odp_packet_data(pkt) + + offset); } } }
commit a37fda78cb7c7d4804c0d9ae1c67801977ce1de5 Author: Bogdan Pricope bogdan.pricope@linaro.org Date: Mon Jan 8 16:00:55 2018 +0200
example: generator: add direct mode packet RX
Update packet RX processing by adding direct pktin mode. Direct mode should increase throughput on RX side.
Signed-off-by: Bogdan Pricope bogdan.pricope@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c index b37fc7b1..586c3ede 100644 --- a/example/generator/odp_generator.c +++ b/example/generator/odp_generator.c @@ -114,8 +114,6 @@ typedef struct { } tx; struct { odp_pktin_queue_t pktin; /**< Packet input queue */ - interface_t *ifs; /**< Interfaces array */ - int ifs_count; /**< Interfaces array size */ } rx; }; odp_pool_t pool; /**< Pool for packet IO */ @@ -777,19 +775,18 @@ static int gen_send_thread(void *arg) /** * Process icmp packets * + * @param thr worker id + * @param thr_args worker argument * @param icmp icmp header address - * @param msg output buffer */
-static void process_icmp_pkt(thread_args_t *thr_args, - odph_icmphdr_t *icmp, char *msg) +static void process_icmp_pkt(int thr, thread_args_t *thr_args, + odph_icmphdr_t *icmp) { uint64_t trecv; uint64_t tsend; uint64_t rtt_ms, rtt_us;
- msg[0] = 0; - if (icmp->type == ICMP_ECHOREPLY) { thr_args->counters.ctr_icmp_reply_rcv++;
@@ -799,33 +796,32 @@ static void process_icmp_pkt(thread_args_t *thr_args, rtt_ms = (trecv - tsend) / ODP_TIME_MSEC_IN_NS; rtt_us = (trecv - tsend) / ODP_TIME_USEC_IN_NS - 1000 * rtt_ms; - sprintf(msg, - "ICMP Echo Reply seq %d time %" - PRIu64 ".%.03" PRIu64" ms", + printf(" [%02i] ICMP Echo Reply seq %d time %" + PRIu64 ".%.03" PRIu64" ms\n", thr, odp_be_to_cpu_16(icmp->un.echo.sequence), rtt_ms, rtt_us); } else if (icmp->type == ICMP_ECHO) { - sprintf(msg, "Icmp Echo Request"); + printf(" [%02i] ICMP Echo Request\n", thr); } }
/** - * Print odp packets + * Process odp packets * * @param thr worker id + * @param thr_args worker argument * @param pkt_tbl packets to be print * @param len packet number */ -static void print_pkts(int thr, thread_args_t *thr_args, - odp_packet_t pkt_tbl[], unsigned len) +static void process_pkts(int thr, thread_args_t *thr_args, + odp_packet_t pkt_tbl[], unsigned len) { odp_packet_t pkt; + odp_packet_chksum_status_t csum_status; char *buf; odph_ipv4hdr_t *ip; odph_icmphdr_t *icmp; unsigned i; - size_t offset; - char msg[1024];
for (i = 0; i < len; ++i) { pkt = pkt_tbl[i]; @@ -834,10 +830,21 @@ static void print_pkts(int thr, thread_args_t *thr_args, if (!odp_packet_has_ipv4(pkt)) continue;
+ csum_status = odp_packet_l3_chksum_status(pkt); + if (csum_status == ODP_PACKET_CHKSUM_BAD) + printf("L3 checksum error detected.\n"); + + csum_status = odp_packet_l4_chksum_status(pkt); + if (csum_status == ODP_PACKET_CHKSUM_BAD) + printf("L4 checksum error detected.\n"); + + /* Drop packets with errors */ + if (odp_unlikely(odp_packet_has_error(pkt))) + continue; + thr_args->counters.ctr_pkt_rcv++; buf = odp_packet_data(pkt); ip = (odph_ipv4hdr_t *)(buf + odp_packet_l3_offset(pkt)); - offset = odp_packet_l4_offset(pkt);
/* udp */ if (ip->proto == ODPH_IPPROTO_UDP) @@ -845,16 +852,16 @@ static void print_pkts(int thr, thread_args_t *thr_args,
/* icmp */ if (ip->proto == ODPH_IPPROTO_ICMPV4) { - icmp = (odph_icmphdr_t *)(buf + offset); + icmp = (odph_icmphdr_t *)(buf + + odp_packet_l4_offset(pkt));
- process_icmp_pkt(thr_args, icmp, msg); - printf(" [%02i] %s\n", thr, msg); + process_icmp_pkt(thr, thr_args, icmp); } } }
/** - * Main receive function + * Scheduler receive function * * @param arg thread arguments of type 'thread_args_t *' */ @@ -862,17 +869,16 @@ static int gen_recv_thread(void *arg) { int thr; thread_args_t *thr_args; - odp_packet_t pkts[MAX_RX_BURST], pkt; - odp_event_t events[MAX_RX_BURST]; + odp_packet_t pkts[MAX_RX_BURST]; + odp_event_t events[MAX_RX_BURST], ev; int pkt_cnt, ev_cnt, i; - odp_packet_chksum_status_t csum_status; int burst_size;
thr = odp_thread_id(); thr_args = (thread_args_t *)arg; burst_size = args->rx_burst_size;
- printf(" [%02i] created mode: RECEIVE\n", thr); + printf(" [%02i] created mode: RECEIVE SCHEDULER\n", thr); odp_barrier_wait(&barrier);
for (;;) { @@ -884,29 +890,62 @@ static int gen_recv_thread(void *arg) events, burst_size); if (ev_cnt == 0) continue; + for (i = 0, pkt_cnt = 0; i < ev_cnt; i++) { - pkt = odp_packet_from_event(events[i]); + ev = events[i];
- csum_status = odp_packet_l3_chksum_status(pkt); - if (csum_status == ODP_PACKET_CHKSUM_BAD) - printf("L3 checksum error detected.\n"); + if (odp_event_type(ev) == ODP_EVENT_PACKET) + pkts[pkt_cnt++] = odp_packet_from_event(ev); + else + odp_event_free(ev); + }
- csum_status = odp_packet_l4_chksum_status(pkt); - if (csum_status == ODP_PACKET_CHKSUM_BAD) - printf("L4 checksum error detected.\n"); + if (pkt_cnt) { + process_pkts(thr, thr_args, pkts, pkt_cnt);
- /* Drop packets with errors */ - if (odp_unlikely(odp_packet_has_error(pkt))) { - odp_packet_free(pkt); - continue; - } - pkts[pkt_cnt++] = pkt; + odp_packet_free_multi(pkts, pkt_cnt); } + }
- if (pkt_cnt) { - print_pkts(thr, thr_args, pkts, pkt_cnt); + return 0; +} + +/** + * Direct receive function + * + * @param arg thread arguments of type 'thread_args_t *' + */ +static int gen_recv_direct_thread(void *arg) +{ + int thr; + thread_args_t *thr_args; + odp_packet_t pkts[MAX_RX_BURST]; + int pkt_cnt, burst_size; + odp_pktin_queue_t pktin; + + thr = odp_thread_id(); + thr_args = (thread_args_t *)arg; + pktin = thr_args->rx.pktin; + burst_size = args->rx_burst_size; + + printf(" [%02i] created mode: RECEIVE\n", thr); + odp_barrier_wait(&barrier); + + for (;;) { + if (thr_args->stop) + break; + + pkt_cnt = odp_pktin_recv_tmo(pktin, pkts, burst_size, + ODP_PKTIN_NO_WAIT); + + if (pkt_cnt > 0) { + process_pkts(thr, thr_args, pkts, pkt_cnt);
odp_packet_free_multi(pkts, pkt_cnt); + } else if (pkt_cnt == 0) { + continue; + } else { + break; } }
@@ -1223,8 +1262,8 @@ int main(int argc, char *argv[]) abort(); } thr_args = &args->thread[PING_THR_RX]; - thr_args->rx.ifs = ifs; - thr_args->rx.ifs_count = args->appl.if_count; + if (!args->appl.sched) + thr_args->rx.pktin = ifs[0].pktin[0]; thr_args->pool = pool; thr_args->tp = tp; thr_args->tq = tq; @@ -1241,7 +1280,10 @@ int main(int argc, char *argv[]) thr_args->mode = args->appl.mode;
memset(&thr_params, 0, sizeof(thr_params)); - thr_params.start = gen_recv_thread; + if (args->appl.sched) + thr_params.start = gen_recv_thread; + else + thr_params.start = gen_recv_direct_thread; thr_params.arg = thr_args; thr_params.thr_type = ODP_THREAD_WORKER; thr_params.instance = instance; @@ -1287,21 +1329,24 @@ int main(int argc, char *argv[]) for (i = 0; i < num_workers; ++i) { odp_cpumask_t thd_mask; int (*thr_run_func)(void *); - int if_idx, pktout_idx; + int if_idx, pktq_idx; uint64_t start_seq;
+ if_idx = i % args->appl.if_count; + if (args->appl.mode == APPL_MODE_RCV) { - args->thread[i].rx.ifs = ifs; - args->thread[i].rx.ifs_count = - args->appl.if_count; + pktq_idx = (i / args->appl.if_count) % + ifs[if_idx].pktin_count; + if (!args->appl.sched) + args->thread[i].rx.pktin = + ifs[if_idx].pktin[pktq_idx]; } else { - if_idx = i % args->appl.if_count; - pktout_idx = (i / args->appl.if_count) % + pktq_idx = (i / args->appl.if_count) % ifs[if_idx].pktout_count; start_seq = i * args->tx_burst_size;
args->thread[i].tx.pktout = - ifs[if_idx].pktout[pktout_idx]; + ifs[if_idx].pktout[pktq_idx]; args->thread[i].tx.pktout_cfg = &ifs[if_idx].config.pktout; args->thread[i].counters.ctr_seq = start_seq; @@ -1329,7 +1374,10 @@ int main(int argc, char *argv[]) if (args->appl.mode == APPL_MODE_UDP) { thr_run_func = gen_send_thread; } else if (args->appl.mode == APPL_MODE_RCV) { - thr_run_func = gen_recv_thread; + if (args->appl.sched) + thr_run_func = gen_recv_thread; + else + thr_run_func = gen_recv_direct_thread; } else { EXAMPLE_ERR("ERR MODE\n"); exit(EXIT_FAILURE);
commit 0fe531c4ec9d49f562f91056eab29f81b98f63f6 Author: Bogdan Pricope bogdan.pricope@linaro.org Date: Mon Jan 8 13:25:46 2018 +0200
example: generator: add direct mode pktio configuration
Update interface configuration function to support direct mode in addition to scheduler mode.
Signed-off-by: Bogdan Pricope bogdan.pricope@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c index e7a4315a..b37fc7b1 100644 --- a/example/generator/odp_generator.c +++ b/example/generator/odp_generator.c @@ -55,6 +55,8 @@ typedef struct { odp_pktio_config_t config; odp_pktout_queue_t pktout[MAX_WORKERS]; unsigned pktout_count; + odp_pktin_queue_t pktin[MAX_WORKERS]; + unsigned pktin_count; } interface_t;
/** @@ -111,6 +113,7 @@ typedef struct { odp_pktout_config_opt_t *pktout_cfg; /**< Packet output config*/ } tx; struct { + odp_pktin_queue_t pktin; /**< Packet input queue */ interface_t *ifs; /**< Interfaces array */ int ifs_count; /**< Interfaces array size */ } rx; @@ -520,10 +523,15 @@ static int create_pktio(const char *dev, odp_pool_t pool, odp_pktio_param_t pktio_param; odp_pktin_queue_param_t pktin_param; odp_pktout_queue_param_t pktout_param; - odp_pktio_op_mode_t pktout_mode; + odp_pktio_op_mode_t pktout_mode, pktin_mode; + odp_bool_t sched = args->appl.sched;
odp_pktio_param_init(&pktio_param); - pktio_param.in_mode = ODP_PKTIN_MODE_SCHED; + pktio_param.in_mode = num_rx_queues ? + (sched ? ODP_PKTIN_MODE_SCHED : ODP_PKTIN_MODE_DIRECT) : + ODP_PKTIN_MODE_DISABLED; + pktio_param.out_mode = num_tx_queues ? ODP_PKTOUT_MODE_DIRECT : + ODP_PKTOUT_MODE_DISABLED;
/* Open a packet IO instance */ itf->pktio = odp_pktio_open(dev, pool, &pktio_param); @@ -572,31 +580,47 @@ static int create_pktio(const char *dev, odp_pool_t pool, return -1; }
- if (num_rx_queues > capa.max_input_queues) - num_rx_queues = capa.max_input_queues; - - odp_pktin_queue_param_init(&pktin_param); - pktin_param.num_queues = num_rx_queues; - pktin_param.queue_param.sched.sync = ODP_SCHED_SYNC_ATOMIC; + if (num_rx_queues) { + pktin_mode = ODP_PKTIO_OP_MT_UNSAFE; + if (num_rx_queues > capa.max_input_queues) { + num_rx_queues = capa.max_input_queues; + pktin_mode = ODP_PKTIO_OP_MT; + EXAMPLE_DBG("Warning: Force RX multithread safe mode " + "(slower)on %s\n", dev); + }
- if (odp_pktin_queue_config(itf->pktio, &pktin_param)) { - EXAMPLE_ERR("Error: pktin queue config failed for %s\n", dev); - return -1; + odp_pktin_queue_param_init(&pktin_param); + pktin_param.num_queues = num_rx_queues; + pktin_param.op_mode = pktin_mode; + if (sched) + pktin_param.queue_param.sched.sync = + ODP_SCHED_SYNC_ATOMIC; + + if (odp_pktin_queue_config(itf->pktio, &pktin_param)) { + EXAMPLE_ERR("Error: pktin queue config failed " + "for %s\n", dev); + return -1; + } }
- pktout_mode = ODP_PKTIO_OP_MT_UNSAFE; - if (num_tx_queues > capa.max_output_queues) { - num_tx_queues = capa.max_output_queues; - pktout_mode = ODP_PKTIO_OP_MT; - } + if (num_tx_queues) { + pktout_mode = ODP_PKTIO_OP_MT_UNSAFE; + if (num_tx_queues > capa.max_output_queues) { + num_tx_queues = capa.max_output_queues; + pktout_mode = ODP_PKTIO_OP_MT; + EXAMPLE_DBG("Warning: Force TX multithread safe mode " + "(slower) on %s\n", dev); + }
- odp_pktout_queue_param_init(&pktout_param); - pktout_param.num_queues = num_tx_queues; - pktout_param.op_mode = pktout_mode; + odp_pktout_queue_param_init(&pktout_param); + pktout_param.num_queues = num_tx_queues; + pktout_param.op_mode = pktout_mode;
- if (odp_pktout_queue_config(itf->pktio, &pktout_param)) { - EXAMPLE_ERR("Error: pktout queue config failed for %s\n", dev); - return -1; + if (odp_pktout_queue_config(itf->pktio, &pktout_param)) { + EXAMPLE_ERR("Error: pktout queue config failed for %s\n", + dev); + return -1; + } }
ret = odp_pktio_start(itf->pktio); @@ -604,12 +628,21 @@ static int create_pktio(const char *dev, odp_pool_t pool, EXAMPLE_ABORT("Error: unable to start %s\n", dev);
itf->pktout_count = num_tx_queues; - if (odp_pktout_queue(itf->pktio, itf->pktout, itf->pktout_count) != - (int)itf->pktout_count) { + if (itf->pktout_count && + odp_pktout_queue(itf->pktio, itf->pktout, itf->pktout_count) != + (int)itf->pktout_count) { EXAMPLE_ERR("Error: failed to get output queues for %s\n", dev); return -1; }
+ itf->pktin_count = num_rx_queues; + if (!sched && itf->pktin_count && + odp_pktin_queue(itf->pktio, itf->pktin, itf->pktin_count) != + (int)itf->pktin_count) { + EXAMPLE_ERR("Error: failed to get input queues for %s\n", dev); + return -1; + } + printf(" created pktio:%02" PRIu64 ", dev:%s, queue mode (ATOMIC queues)\n" " default pktio%02" PRIu64 "\n", @@ -1140,28 +1173,29 @@ int main(int argc, char *argv[])
ifs = malloc(sizeof(interface_t) * args->appl.if_count);
- if (args->appl.mode == APPL_MODE_PING || - args->appl.mode == APPL_MODE_UDP) - num_rx_queues = 1; - else - num_rx_queues = num_workers; - - if (args->appl.mode == APPL_MODE_PING || - args->appl.mode == APPL_MODE_RCV) - num_tx_queues = 1; - else { - num_tx_queues = num_workers / args->appl.if_count; - if (num_workers % args->appl.if_count) - num_tx_queues++; - } + for (i = 0; i < args->appl.if_count; ++i) { + if (args->appl.mode == APPL_MODE_PING) { + num_rx_queues = 1; + num_tx_queues = 1; + } else if (args->appl.mode == APPL_MODE_UDP) { + num_rx_queues = 0; + num_tx_queues = num_workers / args->appl.if_count; + if (i < num_workers % args->appl.if_count) + num_tx_queues++; + } else { /* APPL_MODE_RCV*/ + num_rx_queues = num_workers / args->appl.if_count; + if (i < num_workers % args->appl.if_count) + num_rx_queues++; + num_tx_queues = 0; + }
- for (i = 0; i < args->appl.if_count; ++i) if (create_pktio(args->appl.if_names[i], pool, num_rx_queues, num_tx_queues, &ifs[i])) { EXAMPLE_ERR("Error: create interface %s failed.\n", args->appl.if_names[i]); exit(EXIT_FAILURE); } + }
/* Create and init worker threads */ memset(thread_tbl, 0, sizeof(thread_tbl));
commit 8bd76909bea5d4d3a7917d00269a493628c96d5e Author: Bogdan Pricope bogdan.pricope@linaro.org Date: Mon Jan 8 10:59:18 2018 +0200
example: generator: add configuration option for scheduler RX
Add CLI option to enable/disable packet receive with scheduler API. Default: use direct mode API.
Signed-off-by: Bogdan Pricope bogdan.pricope@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c index b516ebf7..e7a4315a 100644 --- a/example/generator/odp_generator.c +++ b/example/generator/odp_generator.c @@ -84,6 +84,7 @@ typedef struct { int rx_burst; /**< number of packets to receive with one API call */ odp_bool_t csum; /**< use platform csum support if available */ + odp_bool_t sched; /**< use scheduler API to receive packets */ } appl_args_t;
/** @@ -1394,10 +1395,11 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) {"udp_tx_burst", required_argument, NULL, 'x'}, {"rx_burst", required_argument, NULL, 'r'}, {"csum", no_argument, NULL, 'y'}, + {"sched", no_argument, NULL, 'z'}, {NULL, 0, NULL, 0} };
- static const char *shortopts = "+I:a:b:s:d:p:i:m:n:t:w:c:x:he:f:yr:"; + static const char *shortopts = "+I:a:b:s:d:p:i:m:n:t:w:c:x:he:f:yr:z";
/* let helper collect its own arguments (e.g. --odph_proc) */ odph_parse_options(argc, argv, shortopts, longopts); @@ -1412,6 +1414,7 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) appl_args->srcport = 0; appl_args->dstport = 0; appl_args->csum = 0; + appl_args->sched = 0;
opterr = 0; /* do not issue errors on helper options */
@@ -1563,6 +1566,9 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) case 'y': appl_args->csum = 1; break; + case 'z': + appl_args->sched = 1; + break; case 'h': usage(argv[0]); exit(EXIT_SUCCESS); @@ -1652,6 +1658,8 @@ static void usage(char *progname) " -r, --rx_burst size of RX burst\n" " -y, --csum use platform checksum support if available\n" " default is disabled\n" + " -z, --sched use scheduler API to receive packets\n" + " default is direct mode API\n" "\n", NO_PATH(progname), NO_PATH(progname) ); }
commit 4c23114ed39db175beaa317f63b782fad02b2c6f Author: Bogdan Pricope bogdan.pricope@linaro.org Date: Wed Dec 13 10:45:59 2017 +0200
example: generator: add configuration option for RX burst size
Add CLI option to configure RX burst size. Bigger RX burst size may increase packet RX rate.
Signed-off-by: Bogdan Pricope bogdan.pricope@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c index 0fc4c9cc..b516ebf7 100644 --- a/example/generator/odp_generator.c +++ b/example/generator/odp_generator.c @@ -28,7 +28,8 @@ #define DEFAULT_PKT_INTERVAL 1000 /* Interval between each packet */ #define DEFAULT_UDP_TX_BURST 16 #define MAX_UDP_TX_BURST 512 -#define MAX_RX_BURST 32 +#define DEFAULT_RX_BURST 32 +#define MAX_RX_BURST 512
#define APPL_MODE_UDP 0 /**< UDP mode */ #define APPL_MODE_PING 1 /**< ping mode */ @@ -80,6 +81,8 @@ typedef struct { each packet */ int udp_tx_burst; /**< number of udp packets to send with one API call */ + int rx_burst; /**< number of packets to receive with one + API call */ odp_bool_t csum; /**< use platform csum support if available */ } appl_args_t;
@@ -130,6 +133,7 @@ typedef struct { /** Global arguments */ int thread_cnt; int tx_burst_size; + int rx_burst_size; } args_t;
/** Global pointer to args */ @@ -828,10 +832,11 @@ static int gen_recv_thread(void *arg) odp_event_t events[MAX_RX_BURST]; int pkt_cnt, ev_cnt, i; odp_packet_chksum_status_t csum_status; + int burst_size;
- (void)arg; thr = odp_thread_id(); thr_args = (thread_args_t *)arg; + burst_size = args->rx_burst_size;
printf(" [%02i] created mode: RECEIVE\n", thr); odp_barrier_wait(&barrier); @@ -842,7 +847,7 @@ static int gen_recv_thread(void *arg)
/* Use schedule to get buf from any input queue */ ev_cnt = odp_schedule_multi(NULL, ODP_SCHED_NO_WAIT, - events, MAX_RX_BURST); + events, burst_size); if (ev_cnt == 0) continue; for (i = 0, pkt_cnt = 0; i < ev_cnt; i++) { @@ -1076,12 +1081,16 @@ int main(int argc, char *argv[]) args->thread_cnt = num_workers;
/* Burst size */ - if (args->appl.mode == APPL_MODE_PING) + if (args->appl.mode == APPL_MODE_PING) { args->tx_burst_size = 1; - else if (args->appl.mode == APPL_MODE_UDP) + args->rx_burst_size = 1; + } else if (args->appl.mode == APPL_MODE_UDP) { args->tx_burst_size = args->appl.udp_tx_burst; - else + args->rx_burst_size = 0; + } else { args->tx_burst_size = 0; + args->rx_burst_size = args->appl.rx_burst; + }
/* Create packet pool */ odp_pool_param_init(¶ms); @@ -1383,11 +1392,12 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) {"interval", required_argument, NULL, 'i'}, {"help", no_argument, NULL, 'h'}, {"udp_tx_burst", required_argument, NULL, 'x'}, + {"rx_burst", required_argument, NULL, 'r'}, {"csum", no_argument, NULL, 'y'}, {NULL, 0, NULL, 0} };
- static const char *shortopts = "+I:a:b:s:d:p:i:m:n:t:w:c:x:he:f:y"; + static const char *shortopts = "+I:a:b:s:d:p:i:m:n:t:w:c:x:he:f:yr:";
/* let helper collect its own arguments (e.g. --odph_proc) */ odph_parse_options(argc, argv, shortopts, longopts); @@ -1398,6 +1408,7 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) appl_args->timeout = -1; appl_args->interval = DEFAULT_PKT_INTERVAL; appl_args->udp_tx_burst = DEFAULT_UDP_TX_BURST; + appl_args->rx_burst = DEFAULT_RX_BURST; appl_args->srcport = 0; appl_args->dstport = 0; appl_args->csum = 0; @@ -1540,6 +1551,14 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) exit(EXIT_FAILURE); } break; + case 'r': + appl_args->rx_burst = atoi(optarg); + if (appl_args->rx_burst > MAX_RX_BURST) { + EXAMPLE_ERR("wrong Rx burst size (max %d)\n", + MAX_RX_BURST); + exit(EXIT_FAILURE); + } + break;
case 'y': appl_args->csum = 1; @@ -1630,6 +1649,7 @@ static void usage(char *progname) " -n, --count the number of packets to be send\n" " -c, --cpumask to set on cores\n" " -x, --udp_tx_burst size of UDP TX burst\n" + " -r, --rx_burst size of RX burst\n" " -y, --csum use platform checksum support if available\n" " default is disabled\n" "\n", NO_PATH(progname), NO_PATH(progname)
-----------------------------------------------------------------------
Summary of changes: example/generator/odp_generator.c | 339 ++++++++++++++++++++++++++------------ test/performance/odp_l2fwd.c | 40 ++--- 2 files changed, 250 insertions(+), 129 deletions(-)
hooks/post-receive