Add burst mode for event timer adapter that can be selected by passing --prod_type_timerdev_burst.
Signed-off-by: Pavan Nikhilesh <pbhagavat...@caviumnetworks.com> --- app/test-eventdev/evt_options.c | 13 +++++++ app/test-eventdev/evt_options.h | 2 ++ app/test-eventdev/test_perf_common.c | 66 +++++++++++++++++++++++++++++++++++- 3 files changed, 80 insertions(+), 1 deletion(-) diff --git a/app/test-eventdev/evt_options.c b/app/test-eventdev/evt_options.c index 49cd9c419..05d6de88b 100644 --- a/app/test-eventdev/evt_options.c +++ b/app/test-eventdev/evt_options.c @@ -98,6 +98,15 @@ evt_parse_timer_prod_type(struct evt_options *opt, const char *arg __rte_unused) return 0; } +static int +evt_parse_timer_prod_type_burst(struct evt_options *opt, + const char *arg __rte_unused) +{ + opt->prod_type = EVT_PROD_TYPE_EVENT_TIMER_ADPTR; + opt->timdev_use_burst = 1; + return 0; +} + static int evt_parse_test_name(struct evt_options *opt, const char *arg) { @@ -185,6 +194,8 @@ usage(char *program) "\t--prod_type_timerdev : use event timer device as producer.\n" "\t x * bkt_tck_nsec would be the timeout\n" "\t in ns.\n" + "\t--prod_type_timerdev_burst : use timer device as producer\n" + "\t burst mode.\n" ); printf("available tests:\n"); evt_test_dump_names(); @@ -247,6 +258,7 @@ static struct option lgopts[] = { { EVT_QUEUE_PRIORITY, 0, 0, 0 }, { EVT_PROD_ETHDEV, 0, 0, 0 }, { EVT_PROD_TIMERDEV, 0, 0, 0 }, + { EVT_PROD_TIMERDEV_BURST, 0, 0, 0 }, { EVT_HELP, 0, 0, 0 }, { NULL, 0, 0, 0 } }; @@ -272,6 +284,7 @@ evt_opts_parse_long(int opt_idx, struct evt_options *opt) { EVT_QUEUE_PRIORITY, evt_parse_queue_priority}, { EVT_PROD_ETHDEV, evt_parse_eth_prod_type}, { EVT_PROD_TIMERDEV, evt_parse_timer_prod_type}, + { EVT_PROD_TIMERDEV_BURST, evt_parse_timer_prod_type_burst}, }; for (i = 0; i < RTE_DIM(parsermap); i++) { diff --git a/app/test-eventdev/evt_options.h b/app/test-eventdev/evt_options.h index 37debae84..03078b21b 100644 --- a/app/test-eventdev/evt_options.h +++ b/app/test-eventdev/evt_options.h @@ -32,6 +32,7 @@ #define EVT_QUEUE_PRIORITY ("queue_priority") #define EVT_PROD_ETHDEV ("prod_type_ethdev") #define EVT_PROD_TIMERDEV ("prod_type_timerdev") +#define EVT_PROD_TIMERDEV_BURST ("prod_type_timerdev_burst") #define EVT_HELP ("help") enum evt_prod_type { @@ -65,6 +66,7 @@ struct evt_options { uint32_t fwd_latency:1; uint32_t q_priority:1; enum evt_prod_type prod_type; + uint8_t timdev_use_burst; uint8_t timdev_cnt; }; diff --git a/app/test-eventdev/test_perf_common.c b/app/test-eventdev/test_perf_common.c index 39072eb5d..6d0db1dc5 100644 --- a/app/test-eventdev/test_perf_common.c +++ b/app/test-eventdev/test_perf_common.c @@ -132,6 +132,66 @@ perf_event_timer_producer(void *arg) return 0; } +static inline int +perf_event_timer_producer_burst(void *arg) +{ + int i; + struct prod_data *p = arg; + struct test_perf *t = p->t; + struct evt_options *opt = t->opt; + uint32_t flow_counter = 0; + uint64_t count = 0; + uint64_t arm_latency = 0; + const uint8_t nb_timer_adptrs = opt->nb_timer_adptrs; + const uint32_t nb_flows = t->nb_flows; + const uint64_t nb_timers = opt->nb_timers; + struct rte_mempool *pool = t->pool; + struct perf_elt *m[BURST_SIZE + 1] = {NULL}; + struct rte_event_timer_adapter **adptr = t->timer_adptr; + uint64_t timeout_ticks = opt->optm_bkt_tck_nsec ? + (opt->nb_bkt_tcks * opt->bkt_tck_nsec) + / opt->optm_bkt_tck_nsec : opt->nb_bkt_tcks; + + timeout_ticks += timeout_ticks ? 0 : 1; + const struct rte_event_timer tim = { + .ev.op = RTE_EVENT_OP_NEW, + .ev.queue_id = p->queue_id, + .ev.sched_type = t->opt->sched_type_list[0], + .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, + .ev.event_type = RTE_EVENT_TYPE_TIMER, + .state = RTE_EVENT_TIMER_NOT_ARMED, + .timeout_ticks = timeout_ticks, + }; + + if (opt->verbose_level > 1) + printf("%s(): lcore %d\n", __func__, rte_lcore_id()); + + while (count < nb_timers && t->done == false) { + if (rte_mempool_get_bulk(pool, (void **)m, BURST_SIZE) < 0) + continue; + for (i = 0; i < BURST_SIZE; i++) { + rte_prefetch0(m[i + 1]); + m[i]->tim = tim; + m[i]->tim.ev.flow_id = flow_counter++ % nb_flows; + m[i]->tim.ev.event_ptr = m[i]; + m[i]->timestamp = rte_get_timer_cycles(); + } + rte_event_timer_arm_tmo_tick_burst( + adptr[flow_counter % nb_timer_adptrs], + (struct rte_event_timer **)m, + tim.timeout_ticks, + BURST_SIZE); + arm_latency += rte_get_timer_cycles() - m[i - 1]->timestamp; + count += BURST_SIZE; + } + fflush(stdout); + rte_delay_ms(1000); + printf("%s(): lcore %d Average event timer arm latency = %.3f us\n", + __func__, rte_lcore_id(), (float)(arm_latency / count) / + (rte_get_timer_hz() / 1000000)); + return 0; +} + static int perf_producer_wrapper(void *arg) { @@ -140,8 +200,12 @@ perf_producer_wrapper(void *arg) /* Launch the producer function only in case of synthetic producer. */ if (t->opt->prod_type == EVT_PROD_TYPE_SYNT) return perf_producer(arg); - else if (t->opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR) + else if (t->opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR && + !t->opt->timdev_use_burst) return perf_event_timer_producer(arg); + else if (t->opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR && + t->opt->timdev_use_burst) + return perf_event_timer_producer_burst(arg); return 0; } -- 2.16.2