DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 1/4] app/eventdev: add event timer adapter as a producer
@ 2018-03-18 13:12 Pavan Nikhilesh
  2018-03-18 13:12 ` [dpdk-dev] [PATCH 2/4] app/eventdev: add burst mode for event timer adapter Pavan Nikhilesh
                   ` (7 more replies)
  0 siblings, 8 replies; 36+ messages in thread
From: Pavan Nikhilesh @ 2018-03-18 13:12 UTC (permalink / raw)
  To: jerin.jacob, santosh.shukla, erik.g.carrillo; +Cc: dev, Pavan Nikhilesh

Add event timer adapter as producer option that can be selected by
passing --prod_type_timerdev.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
---
 app/test-eventdev/evt_options.c      |  54 ++++++++----
 app/test-eventdev/evt_options.h      |   9 ++
 app/test-eventdev/test_perf_atq.c    |  10 +--
 app/test-eventdev/test_perf_common.c | 166 +++++++++++++++++++++++++++++++++--
 app/test-eventdev/test_perf_common.h |   7 ++
 app/test-eventdev/test_perf_queue.c  |   7 +-
 6 files changed, 217 insertions(+), 36 deletions(-)

diff --git a/app/test-eventdev/evt_options.c b/app/test-eventdev/evt_options.c
index 9683b2224..49cd9c419 100644
--- a/app/test-eventdev/evt_options.c
+++ b/app/test-eventdev/evt_options.c
@@ -27,6 +27,11 @@ evt_options_default(struct evt_options *opt)
 	opt->pool_sz = 16 * 1024;
 	opt->wkr_deq_dep = 16;
 	opt->nb_pkts = (1ULL << 26); /* do ~64M packets */
+	opt->nb_timers = 1E8;
+	opt->nb_timer_adptrs = 1;
+	opt->bkt_tck_nsec = 1E3; /* 1000ns ~ 1us */
+	opt->max_tmo_nsec = 1E5; /* 100us */
+	opt->nb_bkt_tcks = 10;   /* 50us */
 	opt->prod_type = EVT_PROD_TYPE_SYNT;
 }
 
@@ -86,6 +91,13 @@ evt_parse_eth_prod_type(struct evt_options *opt, const char *arg __rte_unused)
 	return 0;
 }
 
+static int
+evt_parse_timer_prod_type(struct evt_options *opt, const char *arg __rte_unused)
+{
+	opt->prod_type = EVT_PROD_TYPE_EVENT_TIMER_ADPTR;
+	return 0;
+}
+
 static int
 evt_parse_test_name(struct evt_options *opt, const char *arg)
 {
@@ -169,7 +181,10 @@ usage(char *program)
 		"\t--worker_deq_depth : dequeue depth of the worker\n"
 		"\t--fwd_latency      : perform fwd_latency measurement\n"
 		"\t--queue_priority   : enable queue priority\n"
-		"\t--prod_type_ethdev : use ethernet device as producer\n."
+		"\t--prod_type_ethdev : use ethernet device as producer.\n"
+		"\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"
 		);
 	printf("available tests:\n");
 	evt_test_dump_names();
@@ -217,22 +232,23 @@ evt_parse_sched_type_list(struct evt_options *opt, const char *arg)
 }
 
 static struct option lgopts[] = {
-	{ EVT_NB_FLOWS,         1, 0, 0 },
-	{ EVT_DEVICE,           1, 0, 0 },
-	{ EVT_VERBOSE,          1, 0, 0 },
-	{ EVT_TEST,             1, 0, 0 },
-	{ EVT_PROD_LCORES,      1, 0, 0 },
-	{ EVT_WORK_LCORES,      1, 0, 0 },
-	{ EVT_SOCKET_ID,        1, 0, 0 },
-	{ EVT_POOL_SZ,          1, 0, 0 },
-	{ EVT_NB_PKTS,          1, 0, 0 },
-	{ EVT_WKR_DEQ_DEP,      1, 0, 0 },
-	{ EVT_SCHED_TYPE_LIST,  1, 0, 0 },
-	{ EVT_FWD_LATENCY,      0, 0, 0 },
-	{ EVT_QUEUE_PRIORITY,   0, 0, 0 },
-	{ EVT_PROD_ETHDEV,      0, 0, 0 },
-	{ EVT_HELP,             0, 0, 0 },
-	{ NULL,                 0, 0, 0 }
+	{ EVT_NB_FLOWS,            1, 0, 0 },
+	{ EVT_DEVICE,              1, 0, 0 },
+	{ EVT_VERBOSE,             1, 0, 0 },
+	{ EVT_TEST,                1, 0, 0 },
+	{ EVT_PROD_LCORES,         1, 0, 0 },
+	{ EVT_WORK_LCORES,         1, 0, 0 },
+	{ EVT_SOCKET_ID,           1, 0, 0 },
+	{ EVT_POOL_SZ,             1, 0, 0 },
+	{ EVT_NB_PKTS,             1, 0, 0 },
+	{ EVT_WKR_DEQ_DEP,         1, 0, 0 },
+	{ EVT_SCHED_TYPE_LIST,     1, 0, 0 },
+	{ EVT_FWD_LATENCY,         0, 0, 0 },
+	{ EVT_QUEUE_PRIORITY,      0, 0, 0 },
+	{ EVT_PROD_ETHDEV,         0, 0, 0 },
+	{ EVT_PROD_TIMERDEV,       0, 0, 0 },
+	{ EVT_HELP,                0, 0, 0 },
+	{ NULL,                    0, 0, 0 }
 };
 
 static int
@@ -255,11 +271,12 @@ evt_opts_parse_long(int opt_idx, struct evt_options *opt)
 		{ EVT_FWD_LATENCY, evt_parse_fwd_latency},
 		{ EVT_QUEUE_PRIORITY, evt_parse_queue_priority},
 		{ EVT_PROD_ETHDEV, evt_parse_eth_prod_type},
+		{ EVT_PROD_TIMERDEV, evt_parse_timer_prod_type},
 	};
 
 	for (i = 0; i < RTE_DIM(parsermap); i++) {
 		if (strncmp(lgopts[opt_idx].name, parsermap[i].lgopt_name,
-				strlen(parsermap[i].lgopt_name)) == 0)
+				strlen(lgopts[opt_idx].name)) == 0)
 			return parsermap[i].parser_fn(opt, optarg);
 	}
 
@@ -305,6 +322,7 @@ evt_options_dump(struct evt_options *opt)
 	evt_dump("pool_sz", "%d", opt->pool_sz);
 	evt_dump("master lcore", "%d", rte_get_master_lcore());
 	evt_dump("nb_pkts", "%"PRIu64, opt->nb_pkts);
+	evt_dump("nb_timers", "%"PRIu64, opt->nb_timers);
 	evt_dump_begin("available lcores");
 	RTE_LCORE_FOREACH(lcore_id)
 		printf("%d ", lcore_id);
diff --git a/app/test-eventdev/evt_options.h b/app/test-eventdev/evt_options.h
index 46d122229..37debae84 100644
--- a/app/test-eventdev/evt_options.h
+++ b/app/test-eventdev/evt_options.h
@@ -31,12 +31,14 @@
 #define EVT_FWD_LATENCY          ("fwd_latency")
 #define EVT_QUEUE_PRIORITY       ("queue_priority")
 #define EVT_PROD_ETHDEV          ("prod_type_ethdev")
+#define EVT_PROD_TIMERDEV        ("prod_type_timerdev")
 #define EVT_HELP                 ("help")
 
 enum evt_prod_type {
 	EVT_PROD_TYPE_NONE,
 	EVT_PROD_TYPE_SYNT,          /* Producer type Synthetic i.e. CPU. */
 	EVT_PROD_TYPE_ETH_RX_ADPTR,  /* Producer type Eth Rx Adapter. */
+	EVT_PROD_TYPE_EVENT_TIMER_ADPTR,  /* Producer type Eth Rx Adapter. */
 	EVT_PROD_TYPE_MAX,
 };
 
@@ -52,11 +54,18 @@ struct evt_options {
 	int nb_stages;
 	int verbose_level;
 	uint64_t nb_pkts;
+	uint8_t nb_timer_adptrs;
+	uint64_t nb_timers;
+	uint64_t bkt_tck_nsec;
+	uint64_t optm_bkt_tck_nsec;
+	uint64_t max_tmo_nsec;
+	uint64_t nb_bkt_tcks;
 	uint16_t wkr_deq_dep;
 	uint8_t dev_id;
 	uint32_t fwd_latency:1;
 	uint32_t q_priority:1;
 	enum evt_prod_type prod_type;
+	uint8_t timdev_cnt;
 };
 
 void evt_options_default(struct evt_options *opt);
diff --git a/app/test-eventdev/test_perf_atq.c b/app/test-eventdev/test_perf_atq.c
index b36b22a77..b3a312722 100644
--- a/app/test-eventdev/test_perf_atq.c
+++ b/app/test-eventdev/test_perf_atq.c
@@ -43,15 +43,12 @@ perf_atq_worker(void *arg, const int enable_fwd_latency)
 	while (t->done == false) {
 		uint16_t event = rte_event_dequeue_burst(dev, port, &ev, 1, 0);
 
-		if (enable_fwd_latency)
-			rte_prefetch0(ev.event_ptr);
-
 		if (!event) {
 			rte_pause();
 			continue;
 		}
 
-		if (enable_fwd_latency)
+		if (enable_fwd_latency && !prod_timer_type)
 		/* first stage in pipeline, mark ts to compute fwd latency */
 			atq_mark_fwd_latency(&ev);
 
@@ -90,7 +87,7 @@ perf_atq_worker_burst(void *arg, const int enable_fwd_latency)
 		}
 
 		for (i = 0; i < nb_rx; i++) {
-			if (enable_fwd_latency) {
+			if (enable_fwd_latency && !prod_timer_type) {
 				rte_prefetch0(ev[i+1].event_ptr);
 				/* first stage in pipeline.
 				 * mark time stamp to compute fwd latency
@@ -163,7 +160,8 @@ perf_atq_eventdev_setup(struct evt_test *test, struct evt_options *opt)
 	struct rte_event_dev_info dev_info;
 
 	nb_ports = evt_nr_active_lcores(opt->wlcores);
-	nb_ports += opt->prod_type == EVT_PROD_TYPE_ETH_RX_ADPTR ? 0 :
+	nb_ports += (opt->prod_type == EVT_PROD_TYPE_ETH_RX_ADPTR ||
+			opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR) ? 0 :
 		evt_nr_active_lcores(opt->plcores);
 
 	nb_queues = atq_nb_event_queues(opt);
diff --git a/app/test-eventdev/test_perf_common.c b/app/test-eventdev/test_perf_common.c
index 59fa0a49e..6ae146d91 100644
--- a/app/test-eventdev/test_perf_common.c
+++ b/app/test-eventdev/test_perf_common.c
@@ -72,6 +72,62 @@ perf_producer(void *arg)
 	return 0;
 }
 
+static inline int
+perf_event_timer_producer(void *arg)
+{
+	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 = NULL;
+	struct rte_event_timer_adapter **adptr = t->timer_adptr;
+	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,
+		.timeout_ticks = opt->optm_bkt_tck_nsec ?
+			(opt->nb_bkt_tcks * opt->bkt_tck_nsec) /
+			opt->optm_bkt_tck_nsec : opt->nb_bkt_tcks,
+	};
+
+	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(pool, (void **)&m) < 0)
+			continue;
+
+		m->tim = tim;
+		m->tim.ev.flow_id = flow_counter++ % nb_flows;
+		m->tim.ev.event_ptr = m;
+		m->timestamp = rte_get_timer_cycles();
+		while (rte_event_timer_arm_burst(
+					adptr[flow_counter % nb_timer_adptrs],
+					(struct rte_event_timer **)&m, 1) < 0) {
+			if (t->done)
+				break;
+			rte_pause();
+			m->timestamp = rte_get_timer_cycles();
+		}
+		arm_latency += rte_get_timer_cycles() - m->timestamp;
+		count++;
+	}
+	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)
 {
@@ -80,6 +136,8 @@ 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)
+		return perf_event_timer_producer(arg);
 	return 0;
 }
 
@@ -146,8 +204,7 @@ perf_launch_lcores(struct evt_test *test, struct evt_options *opt,
 		port_idx++;
 	}
 
-	const uint64_t total_pkts = opt->nb_pkts *
-			evt_nr_active_lcores(opt->plcores);
+	const uint64_t total_pkts = t->outstand_pkts;
 
 	uint64_t dead_lock_cycles = rte_get_timer_cycles();
 	int64_t dead_lock_remaining  =  total_pkts;
@@ -189,7 +246,9 @@ perf_launch_lcores(struct evt_test *test, struct evt_options *opt,
 
 			if (remaining <= 0) {
 				t->result = EVT_TEST_SUCCESS;
-				if (opt->prod_type == EVT_PROD_TYPE_SYNT) {
+				if (opt->prod_type == EVT_PROD_TYPE_SYNT ||
+					opt->prod_type ==
+					EVT_PROD_TYPE_EVENT_TIMER_ADPTR) {
 					t->done = true;
 					rte_smp_wmb();
 					break;
@@ -283,6 +342,65 @@ perf_event_rx_adapter_setup(struct evt_options *opt, uint8_t stride,
 	return ret;
 }
 
+static int
+perf_event_timer_adapter_setup(struct test_perf *t)
+{
+	int i;
+	int ret;
+	struct rte_event_timer_adapter_info adapter_info;
+	struct rte_event_timer_adapter *wl;
+	uint8_t nb_producers = evt_nr_active_lcores(t->opt->plcores);
+	uint8_t flags = RTE_EVENT_TIMER_ADAPTER_F_ADJUST_RES;
+
+	if (nb_producers == 1)
+		flags |= RTE_EVENT_TIMER_ADAPTER_F_SP_PUT;
+
+	for (i = 0; i < t->opt->nb_timer_adptrs; i++) {
+		struct rte_event_timer_adapter_conf config = {
+			.event_dev_id = t->opt->dev_id,
+			.timer_adapter_id = i,
+			.timer_tick_ns = t->opt->bkt_tck_nsec,
+			.max_tmo_ns = t->opt->max_tmo_nsec,
+			.nb_timers = 2 * 1024 * 1024,
+			.flags = flags,
+		};
+
+		wl = rte_event_timer_adapter_create(&config);
+		if (wl == NULL) {
+			evt_err("failed to create event timer ring %d", i);
+			return rte_errno;
+		}
+
+		memset(&adapter_info, 0,
+				sizeof(struct rte_event_timer_adapter_info));
+		rte_event_timer_adapter_get_info(wl, &adapter_info);
+		t->opt->optm_bkt_tck_nsec = adapter_info.min_resolution_ns;
+
+		if (!(adapter_info.caps &
+				RTE_EVENT_TIMER_ADAPTER_CAP_INTERNAL_PORT)) {
+			uint32_t service_id;
+
+			rte_event_timer_adapter_service_id_get(wl,
+					&service_id);
+			ret = evt_service_setup(service_id);
+			if (ret) {
+				evt_err("Failed to setup service core"
+						" for timer adapter\n");
+				return ret;
+			}
+			rte_service_runstate_set(service_id, 1);
+		}
+
+		ret = rte_event_timer_adapter_start(wl);
+		if (ret) {
+			evt_err("failed to Start event timer adapter %d", i);
+			return ret;
+		}
+		t->timer_adptr[i] = wl;
+	}
+	return 0;
+}
+
 int
 perf_event_dev_port_setup(struct evt_test *test, struct evt_options *opt,
 				uint8_t stride, uint8_t nb_queues,
@@ -326,6 +444,18 @@ perf_event_dev_port_setup(struct evt_test *test, struct evt_options *opt,
 		ret = perf_event_rx_adapter_setup(opt, stride, *port_conf);
 		if (ret)
 			return ret;
+	} else if (opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR) {
+		prod = 0;
+		for ( ; port < perf_nb_event_ports(opt); port++) {
+			struct prod_data *p = &t->prod[port];
+			p->queue_id = prod * stride;
+			p->t = t;
+			prod++;
+		}
+
+		ret = perf_event_timer_adapter_setup(t);
+		if (ret)
+			return ret;
 	} else {
 		prod = 0;
 		for ( ; port < perf_nb_event_ports(opt); port++) {
@@ -415,10 +545,13 @@ perf_opt_check(struct evt_options *opt, uint64_t nb_queues)
 	}
 
 	/* Fixups */
-	if (opt->nb_stages == 1 && opt->fwd_latency) {
+	if ((opt->nb_stages == 1 &&
+			opt->prod_type != EVT_PROD_TYPE_EVENT_TIMER_ADPTR) &&
+			opt->fwd_latency) {
 		evt_info("fwd_latency is valid when nb_stages > 1, disabling");
 		opt->fwd_latency = 0;
 	}
+
 	if (opt->fwd_latency && !opt->q_priority) {
 		evt_info("enabled queue priority for latency measurement");
 		opt->q_priority = 1;
@@ -447,8 +580,13 @@ perf_opt_dump(struct evt_options *opt, uint8_t nb_queues)
 void
 perf_eventdev_destroy(struct evt_test *test, struct evt_options *opt)
 {
-	RTE_SET_USED(test);
+	int i;
+	struct test_perf *t = evt_test_priv(test);
 
+	if (opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR) {
+		for (i = 0; i < opt->nb_timer_adptrs; i++)
+			rte_event_timer_adapter_stop(t->timer_adptr[i]);
+	}
 	rte_event_dev_stop(opt->dev_id);
 	rte_event_dev_close(opt->dev_id);
 }
@@ -488,7 +626,8 @@ perf_ethdev_setup(struct evt_test *test, struct evt_options *opt)
 		},
 	};
 
-	if (opt->prod_type == EVT_PROD_TYPE_SYNT)
+	if (opt->prod_type == EVT_PROD_TYPE_SYNT ||
+			opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR)
 		return 0;
 
 	if (!rte_eth_dev_count()) {
@@ -544,7 +683,8 @@ perf_mempool_setup(struct evt_test *test, struct evt_options *opt)
 {
 	struct test_perf *t = evt_test_priv(test);
 
-	if (opt->prod_type == EVT_PROD_TYPE_SYNT) {
+	if (opt->prod_type == EVT_PROD_TYPE_SYNT ||
+			opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR) {
 		t->pool = rte_mempool_create(test->name, /* mempool name */
 				opt->pool_sz, /* number of elements*/
 				sizeof(struct perf_elt), /* element size*/
@@ -594,10 +734,18 @@ perf_test_setup(struct evt_test *test, struct evt_options *opt)
 
 	struct test_perf *t = evt_test_priv(test);
 
-	t->outstand_pkts = opt->nb_pkts * evt_nr_active_lcores(opt->plcores);
+	if (opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR) {
+		t->outstand_pkts = opt->nb_timers *
+			evt_nr_active_lcores(opt->plcores);
+		t->nb_pkts = opt->nb_timers;
+	} else {
+		t->outstand_pkts = opt->nb_pkts *
+			evt_nr_active_lcores(opt->plcores);
+		t->nb_pkts = opt->nb_pkts;
+	}
+
 	t->nb_workers = evt_nr_active_lcores(opt->wlcores);
 	t->done = false;
-	t->nb_pkts = opt->nb_pkts;
 	t->nb_flows = opt->nb_flows;
 	t->result = EVT_TEST_FAILED;
 	t->opt = opt;
diff --git a/app/test-eventdev/test_perf_common.h b/app/test-eventdev/test_perf_common.h
index 9ad99733b..4e96f229c 100644
--- a/app/test-eventdev/test_perf_common.h
+++ b/app/test-eventdev/test_perf_common.h
@@ -13,6 +13,7 @@
 #include <rte_ethdev.h>
 #include <rte_eventdev.h>
 #include <rte_event_eth_rx_adapter.h>
+#include <rte_event_timer_adapter.h>
 #include <rte_lcore.h>
 #include <rte_malloc.h>
 #include <rte_mempool.h>
@@ -39,6 +40,7 @@ struct prod_data {
 	struct test_perf *t;
 } __rte_cache_aligned;
 
+
 struct test_perf {
 	/* Don't change the offset of "done". Signal handler use this memory
 	 * to terminate all lcores work.
@@ -54,9 +56,12 @@ struct test_perf {
 	struct worker_data worker[EVT_MAX_PORTS];
 	struct evt_options *opt;
 	uint8_t sched_type_list[EVT_MAX_STAGES] __rte_cache_aligned;
+	struct rte_event_timer_adapter *timer_adptr[
+		RTE_EVENT_TIMER_ADAPTER_NUM_MAX] __rte_cache_aligned;
 } __rte_cache_aligned;
 
 struct perf_elt {
+	struct rte_event_timer tim;
 	uint64_t timestamp;
 } __rte_cache_aligned;
 
@@ -68,6 +73,8 @@ struct perf_elt {
 	struct evt_options *opt = t->opt;\
 	const uint8_t dev = w->dev_id;\
 	const uint8_t port = w->port_id;\
+	const uint8_t prod_timer_type = \
+		opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR;\
 	uint8_t *const sched_type_list = &t->sched_type_list[0];\
 	struct rte_mempool *const pool = t->pool;\
 	const uint8_t nb_stages = t->opt->nb_stages;\
diff --git a/app/test-eventdev/test_perf_queue.c b/app/test-eventdev/test_perf_queue.c
index db8f2f3e5..74469a5ee 100644
--- a/app/test-eventdev/test_perf_queue.c
+++ b/app/test-eventdev/test_perf_queue.c
@@ -49,7 +49,7 @@ perf_queue_worker(void *arg, const int enable_fwd_latency)
 			rte_pause();
 			continue;
 		}
-		if (enable_fwd_latency)
+		if (enable_fwd_latency && !prod_timer_type)
 		/* first q in pipeline, mark timestamp to compute fwd latency */
 			mark_fwd_latency(&ev, nb_stages);
 
@@ -88,7 +88,7 @@ perf_queue_worker_burst(void *arg, const int enable_fwd_latency)
 		}
 
 		for (i = 0; i < nb_rx; i++) {
-			if (enable_fwd_latency) {
+			if (enable_fwd_latency && !prod_timer_type) {
 				rte_prefetch0(ev[i+1].event_ptr);
 				/* first queue in pipeline.
 				 * mark time stamp to compute fwd latency
@@ -161,7 +161,8 @@ perf_queue_eventdev_setup(struct evt_test *test, struct evt_options *opt)
 	struct rte_event_dev_info dev_info;
 
 	nb_ports = evt_nr_active_lcores(opt->wlcores);
-	nb_ports += opt->prod_type == EVT_PROD_TYPE_ETH_RX_ADPTR ? 0 :
+	nb_ports += opt->prod_type == EVT_PROD_TYPE_ETH_RX_ADPTR ||
+		 opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR ? 0 :
 		evt_nr_active_lcores(opt->plcores);
 
 	nb_queues = perf_queue_nb_event_queues(opt);
-- 
2.16.2

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [dpdk-dev] [PATCH 2/4] app/eventdev: add burst mode for event timer adapter
  2018-03-18 13:12 [dpdk-dev] [PATCH 1/4] app/eventdev: add event timer adapter as a producer Pavan Nikhilesh
@ 2018-03-18 13:12 ` Pavan Nikhilesh
  2018-03-30 19:54   ` Carrillo, Erik G
  2018-03-18 13:12 ` [dpdk-dev] [PATCH 3/4] app/eventdev: add options to configure " Pavan Nikhilesh
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 36+ messages in thread
From: Pavan Nikhilesh @ 2018-03-18 13:12 UTC (permalink / raw)
  To: jerin.jacob, santosh.shukla, erik.g.carrillo; +Cc: dev, Pavan Nikhilesh

Add burst mode for event timer adapter that can be selected by passing
--prod_type_timerdev_burst.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
---
 app/test-eventdev/evt_options.c      | 13 ++++++++
 app/test-eventdev/evt_options.h      |  2 ++
 app/test-eventdev/test_perf_common.c | 61 +++++++++++++++++++++++++++++++++++-
 3 files changed, 75 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 6ae146d91..072b5f8cf 100644
--- a/app/test-eventdev/test_perf_common.c
+++ b/app/test-eventdev/test_perf_common.c
@@ -128,6 +128,61 @@ 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;
+	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,
+		.timeout_ticks = (opt->nb_bkt_tcks * opt->bkt_tck_nsec) /
+			opt->optm_bkt_tck_nsec,
+	};
+
+	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)
 {
@@ -136,8 +191,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

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [dpdk-dev] [PATCH 3/4] app/eventdev: add options to configure event timer adapter
  2018-03-18 13:12 [dpdk-dev] [PATCH 1/4] app/eventdev: add event timer adapter as a producer Pavan Nikhilesh
  2018-03-18 13:12 ` [dpdk-dev] [PATCH 2/4] app/eventdev: add burst mode for event timer adapter Pavan Nikhilesh
@ 2018-03-18 13:12 ` Pavan Nikhilesh
  2018-03-18 13:12 ` [dpdk-dev] [PATCH 4/4] doc: update test eventdev documentation Pavan Nikhilesh
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 36+ messages in thread
From: Pavan Nikhilesh @ 2018-03-18 13:12 UTC (permalink / raw)
  To: jerin.jacob, santosh.shukla, erik.g.carrillo; +Cc: dev, Pavan Nikhilesh

Add options to configure expiry timeout, max number of timers and number
of event timer adapters through command line paramters.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
---
 app/test-eventdev/evt_options.c | 65 +++++++++++++++++++++++++++++++++++++++++
 app/test-eventdev/evt_options.h |  5 ++++
 2 files changed, 70 insertions(+)

diff --git a/app/test-eventdev/evt_options.c b/app/test-eventdev/evt_options.c
index 05d6de88b..a04ffea8f 100644
--- a/app/test-eventdev/evt_options.c
+++ b/app/test-eventdev/evt_options.c
@@ -140,6 +140,56 @@ evt_parse_nb_pkts(struct evt_options *opt, const char *arg)
 	return ret;
 }
 
+static int
+evt_parse_nb_timers(struct evt_options *opt, const char *arg)
+{
+	int ret;
+
+	ret = parser_read_uint64(&(opt->nb_timers), arg);
+
+	return ret;
+}
+
+static int
+evt_parse_bkt_tck_nsec(struct evt_options *opt, const char *arg)
+{
+	int ret;
+
+	ret = parser_read_uint64(&(opt->bkt_tck_nsec), arg);
+
+	return ret;
+}
+
+static int
+evt_parse_max_tmo_nsec(struct evt_options *opt, const char *arg)
+{
+	int ret;
+
+	ret = parser_read_uint64(&(opt->max_tmo_nsec), arg);
+
+	return ret;
+}
+
+static int
+evt_parse_nb_bkt_tcks(struct evt_options *opt, const char *arg)
+{
+	int ret;
+
+	ret = parser_read_uint64(&(opt->nb_bkt_tcks), arg);
+
+	return ret;
+}
+
+static int
+evt_parse_nb_timer_adptrs(struct evt_options *opt, const char *arg)
+{
+	int ret;
+
+	ret = parser_read_uint8(&(opt->nb_timer_adptrs), arg);
+
+	return ret;
+}
+
 static int
 evt_parse_pool_sz(struct evt_options *opt, const char *arg)
 {
@@ -196,6 +246,11 @@ usage(char *program)
 		"\t                     in ns.\n"
 		"\t--prod_type_timerdev_burst : use timer device as producer\n"
 		"\t                             burst mode.\n"
+		"\t--nb_timers        : number of timers to arm.\n"
+		"\t--nb_timer_adptrs  : number of timer adapters to use.\n"
+		"\t--bkt_tck_nsec     : timer bucket tick interval in ns.\n"
+		"\t--max_tmo_nsec     : max timeout interval in ns.\n"
+		"\t--nb_bkt_tcks      : number of bucket ticks for each timer\n"
 		);
 	printf("available tests:\n");
 	evt_test_dump_names();
@@ -259,6 +314,11 @@ static struct option lgopts[] = {
 	{ EVT_PROD_ETHDEV,         0, 0, 0 },
 	{ EVT_PROD_TIMERDEV,       0, 0, 0 },
 	{ EVT_PROD_TIMERDEV_BURST, 0, 0, 0 },
+	{ EVT_NB_TIMERS,           1, 0, 0 },
+	{ EVT_NB_TIMER_ADPTRS,     1, 0, 0 },
+	{ EVT_BKT_TCK_NSEC,        1, 0, 0 },
+	{ EVT_MAX_TMO_NSEC,        1, 0, 0 },
+	{ EVT_NB_BKT_TCKS,         1, 0, 0 },
 	{ EVT_HELP,                0, 0, 0 },
 	{ NULL,                    0, 0, 0 }
 };
@@ -285,6 +345,11 @@ evt_opts_parse_long(int opt_idx, struct evt_options *opt)
 		{ 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},
+		{ EVT_NB_TIMERS, evt_parse_nb_timers},
+		{ EVT_NB_TIMER_ADPTRS, evt_parse_nb_timer_adptrs},
+		{ EVT_BKT_TCK_NSEC, evt_parse_bkt_tck_nsec},
+		{ EVT_MAX_TMO_NSEC, evt_parse_max_tmo_nsec},
+		{ EVT_NB_BKT_TCKS, evt_parse_nb_bkt_tcks},
 	};
 
 	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 03078b21b..80a9ebd8f 100644
--- a/app/test-eventdev/evt_options.h
+++ b/app/test-eventdev/evt_options.h
@@ -33,6 +33,11 @@
 #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_NB_TIMERS            ("nb_timers")
+#define EVT_NB_TIMER_ADPTRS      ("nb_timer_adptrs")
+#define EVT_BKT_TCK_NSEC         ("bkt_tck_nsec")
+#define EVT_MAX_TMO_NSEC         ("max_tmo_nsec")
+#define EVT_NB_BKT_TCKS          ("nb_bkt_tcks")
 #define EVT_HELP                 ("help")
 
 enum evt_prod_type {
-- 
2.16.2

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [dpdk-dev]  [PATCH 4/4] doc: update test eventdev documentation
  2018-03-18 13:12 [dpdk-dev] [PATCH 1/4] app/eventdev: add event timer adapter as a producer Pavan Nikhilesh
  2018-03-18 13:12 ` [dpdk-dev] [PATCH 2/4] app/eventdev: add burst mode for event timer adapter Pavan Nikhilesh
  2018-03-18 13:12 ` [dpdk-dev] [PATCH 3/4] app/eventdev: add options to configure " Pavan Nikhilesh
@ 2018-03-18 13:12 ` Pavan Nikhilesh
  2018-03-30 19:50 ` [dpdk-dev] [PATCH 1/4] app/eventdev: add event timer adapter as a producer Carrillo, Erik G
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 36+ messages in thread
From: Pavan Nikhilesh @ 2018-03-18 13:12 UTC (permalink / raw)
  To: jerin.jacob, santosh.shukla, erik.g.carrillo; +Cc: dev, Pavan Nikhilesh

Update documentation to include new options added for using event timer
adapter as a producer.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
---
 doc/guides/tools/testeventdev.rst | 60 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/doc/guides/tools/testeventdev.rst b/doc/guides/tools/testeventdev.rst
index 77480ffe9..ab07c0284 100644
--- a/doc/guides/tools/testeventdev.rst
+++ b/doc/guides/tools/testeventdev.rst
@@ -123,6 +123,36 @@ The following are the application command-line options:
 
         Use ethernet device as producer.
 
+* ``--prod_type_timerdev``
+
+        Use event timer adapter as producer.
+
+ * ``--prod_type_timerdev_burst``
+
+        Use burst mode event timer adapter as producer.
+
+ * ``--bkt_tck_nsec``
+
+        Used to dictate number of nano seconds between bucket traversal of the
+        event timer adapter. Refer `rte_event_timer_adapter_conf`.
+
+ * ``--max_tmo_nsec``
+
+        Used to configure event timer adapter max arm timeout in nano seconds.
+
+ * ``--nb_bkt_tcks``
+
+        Dictate the number of bucket ticks after which the event timer expires.
+
+ * ``--nb_timers``
+
+        Number of event timers each producer cores will generate.
+
+ * ``--nb_timer_adptrs``
+
+        Number of event timer adapters to be used. Each adapter is used in
+        round robin manner by the producer cores.
+
 Eventdev Tests
 --------------
 
@@ -347,6 +377,13 @@ Supported application command line options are following::
         --fwd_latency
         --queue_priority
         --prod_type_ethdev
+        --prod_type_timerdev_burst
+        --prod_type_timerdev
+        --bkt_tck_nsec
+        --max_tmo_nsec
+        --nb_bkt_tcks
+        --nb_timers
+        --nb_timer_adptrs
 
 Example
 ^^^^^^^
@@ -365,6 +402,14 @@ Example command to run perf queue test with ethernet ports:
    sudo build/app/dpdk-test-eventdev --vdev=event_sw0 -- \
         --test=perf_queue --plcores=2 --wlcore=3 --stlist=p --prod_type_ethdev
 
+Example command to run perf queue test with event timer adapter:
+
+.. code-block:: console
+
+   sudo  build/app/dpdk-test-eventdev --vdev="event_octeontx" -- \
+                --wlcores 4 --plcores 12 --test perf_queue --stlist=a \
+                --prod_type_timerdev --fwd_latency
+
 PERF_ATQ Test
 ~~~~~~~~~~~~~~~
 
@@ -431,6 +476,13 @@ Supported application command line options are following::
         --worker_deq_depth
         --fwd_latency
         --prod_type_ethdev
+        --prod_type_timerdev_burst
+        --prod_type_timerdev
+        --bkt_tck_nsec
+        --max_tmo_nsec
+        --nb_bkt_tcks
+        --nb_timers
+        --nb_timer_adptrs
 
 Example
 ^^^^^^^
@@ -442,6 +494,14 @@ Example command to run perf ``all types queue`` test:
    sudo build/app/dpdk-test-eventdev --vdev=event_octeontx -- \
                 --test=perf_atq --plcores=2 --wlcore=3 --stlist=p --nb_pkts=0
 
+Example command to run perf ``all types queue`` test with event timer adapter:
+
+.. code-block:: console
+
+   sudo  build/app/dpdk-test-eventdev --vdev="event_octeontx" -- \
+                --wlcores 4 --plcores 12 --test perf_atq --verbose 20 \
+                --stlist=a --prod_type_timerdev --fwd_latency
+
 
 PIPELINE_QUEUE Test
 ~~~~~~~~~~~~~~~~~~~
-- 
2.16.2

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [dpdk-dev] [PATCH 1/4] app/eventdev: add event timer adapter as a producer
  2018-03-18 13:12 [dpdk-dev] [PATCH 1/4] app/eventdev: add event timer adapter as a producer Pavan Nikhilesh
                   ` (2 preceding siblings ...)
  2018-03-18 13:12 ` [dpdk-dev] [PATCH 4/4] doc: update test eventdev documentation Pavan Nikhilesh
@ 2018-03-30 19:50 ` Carrillo, Erik G
  2018-04-03 16:01 ` [dpdk-dev] [PATCH v2 " Pavan Nikhilesh
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 36+ messages in thread
From: Carrillo, Erik G @ 2018-03-30 19:50 UTC (permalink / raw)
  To: Pavan Nikhilesh, jerin.jacob, santosh.shukla; +Cc: dev

Hi Pavan,

Some comments in-line:

> -----Original Message-----
> From: Pavan Nikhilesh [mailto:pbhagavatula@caviumnetworks.com]
> Sent: Sunday, March 18, 2018 8:12 AM
> To: jerin.jacob@caviumnetworks.com;
> santosh.shukla@caviumnetworks.com; Carrillo, Erik G
> <erik.g.carrillo@intel.com>
> Cc: dev@dpdk.org; Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
> Subject: [dpdk-dev] [PATCH 1/4] app/eventdev: add event timer adapter as
> a producer
> 
> Add event timer adapter as producer option that can be selected by passing -
> -prod_type_timerdev.
> 
> Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
> ---

<...snipped...>

> diff --git a/app/test-eventdev/test_perf_common.c b/app/test-
> eventdev/test_perf_common.c
> index 59fa0a49e..6ae146d91 100644
> --- a/app/test-eventdev/test_perf_common.c
> +++ b/app/test-eventdev/test_perf_common.c
> @@ -72,6 +72,62 @@ perf_producer(void *arg)
>  	return 0;
>  }
> 
> +static inline int
> +perf_event_timer_producer(void *arg)
> +{
> +	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 = NULL;
> +	struct rte_event_timer_adapter **adptr = t->timer_adptr;
> +	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,
> +		.timeout_ticks = opt->optm_bkt_tck_nsec ?
> +			(opt->nb_bkt_tcks * opt->bkt_tck_nsec) /
> +			opt->optm_bkt_tck_nsec : opt->nb_bkt_tcks,

We should also initialize .state = RTE_EVENT_TIMER_NOT_ARMED.

Also, would it be better to take the ceiling instead of the floor when scaling the ticks with:

((opt->nb_bkt_tcks * opt->bkt_tck_nsec) + opt->optm_bkt_tck_nsec - 1) / opt->optm_bkt_tck_nsec

If the fraction is less than one in the current form, then truncation would return 0, which at least in the case of the software impl would be treated as RTE_EVENT_TIMER_ERROR_TOOEARLY.

Thoughts?

Regards,
Gabriel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [dpdk-dev] [PATCH 2/4] app/eventdev: add burst mode for event timer adapter
  2018-03-18 13:12 ` [dpdk-dev] [PATCH 2/4] app/eventdev: add burst mode for event timer adapter Pavan Nikhilesh
@ 2018-03-30 19:54   ` Carrillo, Erik G
  0 siblings, 0 replies; 36+ messages in thread
From: Carrillo, Erik G @ 2018-03-30 19:54 UTC (permalink / raw)
  To: Pavan Nikhilesh, jerin.jacob, santosh.shukla; +Cc: dev

Hi Pavan,

One comment in-line:

> -----Original Message-----
> From: Pavan Nikhilesh [mailto:pbhagavatula@caviumnetworks.com]
> Sent: Sunday, March 18, 2018 8:12 AM
> To: jerin.jacob@caviumnetworks.com;
> santosh.shukla@caviumnetworks.com; Carrillo, Erik G
> <erik.g.carrillo@intel.com>
> Cc: dev@dpdk.org; Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
> Subject: [dpdk-dev] [PATCH 2/4] app/eventdev: add burst mode for event
> timer adapter
> 
> Add burst mode for event timer adapter that can be selected by passing --
> prod_type_timerdev_burst.
> 
> Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
> ---

<...snipped...> 

> diff --git a/app/test-eventdev/test_perf_common.c b/app/test-
> eventdev/test_perf_common.c
> index 6ae146d91..072b5f8cf 100644
> --- a/app/test-eventdev/test_perf_common.c
> +++ b/app/test-eventdev/test_perf_common.c
> @@ -128,6 +128,61 @@ 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;
> +	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,
> +		.timeout_ticks = (opt->nb_bkt_tcks * opt->bkt_tck_nsec) /
> +			opt->optm_bkt_tck_nsec,
> +	};

We should also initialize .state = RTE_EVENT_TIMER_NOT_ARMED here.  Also, if we decide to use the ceiling of the fraction in the prior patch, then the same would apply here.

Thanks,
Gabriel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [dpdk-dev] [PATCH v2 1/4] app/eventdev: add event timer adapter as a producer
  2018-03-18 13:12 [dpdk-dev] [PATCH 1/4] app/eventdev: add event timer adapter as a producer Pavan Nikhilesh
                   ` (3 preceding siblings ...)
  2018-03-30 19:50 ` [dpdk-dev] [PATCH 1/4] app/eventdev: add event timer adapter as a producer Carrillo, Erik G
@ 2018-04-03 16:01 ` Pavan Nikhilesh
  2018-04-03 16:01   ` [dpdk-dev] [PATCH v2 2/4] app/eventdev: add burst mode for event timer adapter Pavan Nikhilesh
                     ` (3 more replies)
  2018-04-05 11:53 ` [dpdk-dev] [PATCH v3 " Pavan Nikhilesh
                   ` (2 subsequent siblings)
  7 siblings, 4 replies; 36+ messages in thread
From: Pavan Nikhilesh @ 2018-04-03 16:01 UTC (permalink / raw)
  To: jerin.jacob, santosh.shukla, erik.g.carrillo; +Cc: dev, Pavan Nikhilesh

Add event timer adapter as producer option that can be selected by
passing --prod_type_timerdev.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
---

 v2 Changes:
 - set timer to NOT_ARMED before trying to arm it.
 - prevent edge cases for timeout_ticks being set to 0.

 app/test-eventdev/evt_options.c      |  54 +++++++----
 app/test-eventdev/evt_options.h      |   9 ++
 app/test-eventdev/test_perf_atq.c    |  10 +--
 app/test-eventdev/test_perf_common.c | 170 +++++++++++++++++++++++++++++++++--
 app/test-eventdev/test_perf_common.h |   7 ++
 app/test-eventdev/test_perf_queue.c  |   7 +-
 6 files changed, 221 insertions(+), 36 deletions(-)

diff --git a/app/test-eventdev/evt_options.c b/app/test-eventdev/evt_options.c
index 9683b2224..49cd9c419 100644
--- a/app/test-eventdev/evt_options.c
+++ b/app/test-eventdev/evt_options.c
@@ -27,6 +27,11 @@ evt_options_default(struct evt_options *opt)
 	opt->pool_sz = 16 * 1024;
 	opt->wkr_deq_dep = 16;
 	opt->nb_pkts = (1ULL << 26); /* do ~64M packets */
+	opt->nb_timers = 1E8;
+	opt->nb_timer_adptrs = 1;
+	opt->bkt_tck_nsec = 1E3; /* 1000ns ~ 1us */
+	opt->max_tmo_nsec = 1E5; /* 100us */
+	opt->nb_bkt_tcks = 10;   /* 50us */
 	opt->prod_type = EVT_PROD_TYPE_SYNT;
 }

@@ -86,6 +91,13 @@ evt_parse_eth_prod_type(struct evt_options *opt, const char *arg __rte_unused)
 	return 0;
 }

+static int
+evt_parse_timer_prod_type(struct evt_options *opt, const char *arg __rte_unused)
+{
+	opt->prod_type = EVT_PROD_TYPE_EVENT_TIMER_ADPTR;
+	return 0;
+}
+
 static int
 evt_parse_test_name(struct evt_options *opt, const char *arg)
 {
@@ -169,7 +181,10 @@ usage(char *program)
 		"\t--worker_deq_depth : dequeue depth of the worker\n"
 		"\t--fwd_latency      : perform fwd_latency measurement\n"
 		"\t--queue_priority   : enable queue priority\n"
-		"\t--prod_type_ethdev : use ethernet device as producer\n."
+		"\t--prod_type_ethdev : use ethernet device as producer.\n"
+		"\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"
 		);
 	printf("available tests:\n");
 	evt_test_dump_names();
@@ -217,22 +232,23 @@ evt_parse_sched_type_list(struct evt_options *opt, const char *arg)
 }

 static struct option lgopts[] = {
-	{ EVT_NB_FLOWS,         1, 0, 0 },
-	{ EVT_DEVICE,           1, 0, 0 },
-	{ EVT_VERBOSE,          1, 0, 0 },
-	{ EVT_TEST,             1, 0, 0 },
-	{ EVT_PROD_LCORES,      1, 0, 0 },
-	{ EVT_WORK_LCORES,      1, 0, 0 },
-	{ EVT_SOCKET_ID,        1, 0, 0 },
-	{ EVT_POOL_SZ,          1, 0, 0 },
-	{ EVT_NB_PKTS,          1, 0, 0 },
-	{ EVT_WKR_DEQ_DEP,      1, 0, 0 },
-	{ EVT_SCHED_TYPE_LIST,  1, 0, 0 },
-	{ EVT_FWD_LATENCY,      0, 0, 0 },
-	{ EVT_QUEUE_PRIORITY,   0, 0, 0 },
-	{ EVT_PROD_ETHDEV,      0, 0, 0 },
-	{ EVT_HELP,             0, 0, 0 },
-	{ NULL,                 0, 0, 0 }
+	{ EVT_NB_FLOWS,            1, 0, 0 },
+	{ EVT_DEVICE,              1, 0, 0 },
+	{ EVT_VERBOSE,             1, 0, 0 },
+	{ EVT_TEST,                1, 0, 0 },
+	{ EVT_PROD_LCORES,         1, 0, 0 },
+	{ EVT_WORK_LCORES,         1, 0, 0 },
+	{ EVT_SOCKET_ID,           1, 0, 0 },
+	{ EVT_POOL_SZ,             1, 0, 0 },
+	{ EVT_NB_PKTS,             1, 0, 0 },
+	{ EVT_WKR_DEQ_DEP,         1, 0, 0 },
+	{ EVT_SCHED_TYPE_LIST,     1, 0, 0 },
+	{ EVT_FWD_LATENCY,         0, 0, 0 },
+	{ EVT_QUEUE_PRIORITY,      0, 0, 0 },
+	{ EVT_PROD_ETHDEV,         0, 0, 0 },
+	{ EVT_PROD_TIMERDEV,       0, 0, 0 },
+	{ EVT_HELP,                0, 0, 0 },
+	{ NULL,                    0, 0, 0 }
 };

 static int
@@ -255,11 +271,12 @@ evt_opts_parse_long(int opt_idx, struct evt_options *opt)
 		{ EVT_FWD_LATENCY, evt_parse_fwd_latency},
 		{ EVT_QUEUE_PRIORITY, evt_parse_queue_priority},
 		{ EVT_PROD_ETHDEV, evt_parse_eth_prod_type},
+		{ EVT_PROD_TIMERDEV, evt_parse_timer_prod_type},
 	};

 	for (i = 0; i < RTE_DIM(parsermap); i++) {
 		if (strncmp(lgopts[opt_idx].name, parsermap[i].lgopt_name,
-				strlen(parsermap[i].lgopt_name)) == 0)
+				strlen(lgopts[opt_idx].name)) == 0)
 			return parsermap[i].parser_fn(opt, optarg);
 	}

@@ -305,6 +322,7 @@ evt_options_dump(struct evt_options *opt)
 	evt_dump("pool_sz", "%d", opt->pool_sz);
 	evt_dump("master lcore", "%d", rte_get_master_lcore());
 	evt_dump("nb_pkts", "%"PRIu64, opt->nb_pkts);
+	evt_dump("nb_timers", "%"PRIu64, opt->nb_timers);
 	evt_dump_begin("available lcores");
 	RTE_LCORE_FOREACH(lcore_id)
 		printf("%d ", lcore_id);
diff --git a/app/test-eventdev/evt_options.h b/app/test-eventdev/evt_options.h
index 46d122229..37debae84 100644
--- a/app/test-eventdev/evt_options.h
+++ b/app/test-eventdev/evt_options.h
@@ -31,12 +31,14 @@
 #define EVT_FWD_LATENCY          ("fwd_latency")
 #define EVT_QUEUE_PRIORITY       ("queue_priority")
 #define EVT_PROD_ETHDEV          ("prod_type_ethdev")
+#define EVT_PROD_TIMERDEV        ("prod_type_timerdev")
 #define EVT_HELP                 ("help")

 enum evt_prod_type {
 	EVT_PROD_TYPE_NONE,
 	EVT_PROD_TYPE_SYNT,          /* Producer type Synthetic i.e. CPU. */
 	EVT_PROD_TYPE_ETH_RX_ADPTR,  /* Producer type Eth Rx Adapter. */
+	EVT_PROD_TYPE_EVENT_TIMER_ADPTR,  /* Producer type Eth Rx Adapter. */
 	EVT_PROD_TYPE_MAX,
 };

@@ -52,11 +54,18 @@ struct evt_options {
 	int nb_stages;
 	int verbose_level;
 	uint64_t nb_pkts;
+	uint8_t nb_timer_adptrs;
+	uint64_t nb_timers;
+	uint64_t bkt_tck_nsec;
+	uint64_t optm_bkt_tck_nsec;
+	uint64_t max_tmo_nsec;
+	uint64_t nb_bkt_tcks;
 	uint16_t wkr_deq_dep;
 	uint8_t dev_id;
 	uint32_t fwd_latency:1;
 	uint32_t q_priority:1;
 	enum evt_prod_type prod_type;
+	uint8_t timdev_cnt;
 };

 void evt_options_default(struct evt_options *opt);
diff --git a/app/test-eventdev/test_perf_atq.c b/app/test-eventdev/test_perf_atq.c
index b36b22a77..b3a312722 100644
--- a/app/test-eventdev/test_perf_atq.c
+++ b/app/test-eventdev/test_perf_atq.c
@@ -43,15 +43,12 @@ perf_atq_worker(void *arg, const int enable_fwd_latency)
 	while (t->done == false) {
 		uint16_t event = rte_event_dequeue_burst(dev, port, &ev, 1, 0);

-		if (enable_fwd_latency)
-			rte_prefetch0(ev.event_ptr);
-
 		if (!event) {
 			rte_pause();
 			continue;
 		}

-		if (enable_fwd_latency)
+		if (enable_fwd_latency && !prod_timer_type)
 		/* first stage in pipeline, mark ts to compute fwd latency */
 			atq_mark_fwd_latency(&ev);

@@ -90,7 +87,7 @@ perf_atq_worker_burst(void *arg, const int enable_fwd_latency)
 		}

 		for (i = 0; i < nb_rx; i++) {
-			if (enable_fwd_latency) {
+			if (enable_fwd_latency && !prod_timer_type) {
 				rte_prefetch0(ev[i+1].event_ptr);
 				/* first stage in pipeline.
 				 * mark time stamp to compute fwd latency
@@ -163,7 +160,8 @@ perf_atq_eventdev_setup(struct evt_test *test, struct evt_options *opt)
 	struct rte_event_dev_info dev_info;

 	nb_ports = evt_nr_active_lcores(opt->wlcores);
-	nb_ports += opt->prod_type == EVT_PROD_TYPE_ETH_RX_ADPTR ? 0 :
+	nb_ports += (opt->prod_type == EVT_PROD_TYPE_ETH_RX_ADPTR ||
+			opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR) ? 0 :
 		evt_nr_active_lcores(opt->plcores);

 	nb_queues = atq_nb_event_queues(opt);
diff --git a/app/test-eventdev/test_perf_common.c b/app/test-eventdev/test_perf_common.c
index 59fa0a49e..39072eb5d 100644
--- a/app/test-eventdev/test_perf_common.c
+++ b/app/test-eventdev/test_perf_common.c
@@ -72,6 +72,66 @@ perf_producer(void *arg)
 	return 0;
 }

+static inline int
+perf_event_timer_producer(void *arg)
+{
+	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 = 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(pool, (void **)&m) < 0)
+			continue;
+
+		m->tim = tim;
+		m->tim.ev.flow_id = flow_counter++ % nb_flows;
+		m->tim.ev.event_ptr = m;
+		m->timestamp = rte_get_timer_cycles();
+		while (rte_event_timer_arm_burst(
+				adptr[flow_counter % nb_timer_adptrs],
+				(struct rte_event_timer **)&m, 1) != 1) {
+			if (t->done)
+				break;
+			rte_pause();
+			m->timestamp = rte_get_timer_cycles();
+		}
+		arm_latency += rte_get_timer_cycles() - m->timestamp;
+		count++;
+	}
+	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)
 {
@@ -80,6 +140,8 @@ 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)
+		return perf_event_timer_producer(arg);
 	return 0;
 }

@@ -146,8 +208,7 @@ perf_launch_lcores(struct evt_test *test, struct evt_options *opt,
 		port_idx++;
 	}

-	const uint64_t total_pkts = opt->nb_pkts *
-			evt_nr_active_lcores(opt->plcores);
+	const uint64_t total_pkts = t->outstand_pkts;

 	uint64_t dead_lock_cycles = rte_get_timer_cycles();
 	int64_t dead_lock_remaining  =  total_pkts;
@@ -189,7 +250,9 @@ perf_launch_lcores(struct evt_test *test, struct evt_options *opt,

 			if (remaining <= 0) {
 				t->result = EVT_TEST_SUCCESS;
-				if (opt->prod_type == EVT_PROD_TYPE_SYNT) {
+				if (opt->prod_type == EVT_PROD_TYPE_SYNT ||
+					opt->prod_type ==
+					EVT_PROD_TYPE_EVENT_TIMER_ADPTR) {
 					t->done = true;
 					rte_smp_wmb();
 					break;
@@ -283,6 +346,65 @@ perf_event_rx_adapter_setup(struct evt_options *opt, uint8_t stride,
 	return ret;
 }

+static int
+perf_event_timer_adapter_setup(struct test_perf *t)
+{
+	int i;
+	int ret;
+	struct rte_event_timer_adapter_info adapter_info;
+	struct rte_event_timer_adapter *wl;
+	uint8_t nb_producers = evt_nr_active_lcores(t->opt->plcores);
+	uint8_t flags = RTE_EVENT_TIMER_ADAPTER_F_ADJUST_RES;
+
+	if (nb_producers == 1)
+		flags |= RTE_EVENT_TIMER_ADAPTER_F_SP_PUT;
+
+	for (i = 0; i < t->opt->nb_timer_adptrs; i++) {
+		struct rte_event_timer_adapter_conf config = {
+			.event_dev_id = t->opt->dev_id,
+			.timer_adapter_id = i,
+			.timer_tick_ns = t->opt->bkt_tck_nsec,
+			.max_tmo_ns = t->opt->max_tmo_nsec,
+			.nb_timers = 2 * 1024 * 1024,
+			.flags = flags,
+		};
+
+		wl = rte_event_timer_adapter_create(&config);
+		if (wl == NULL) {
+			evt_err("failed to create event timer ring %d", i);
+			return rte_errno;
+		}
+
+		memset(&adapter_info, 0,
+				sizeof(struct rte_event_timer_adapter_info));
+		rte_event_timer_adapter_get_info(wl, &adapter_info);
+		t->opt->optm_bkt_tck_nsec = adapter_info.min_resolution_ns;
+
+		if (!(adapter_info.caps &
+				RTE_EVENT_TIMER_ADAPTER_CAP_INTERNAL_PORT)) {
+			uint32_t service_id;
+
+			rte_event_timer_adapter_service_id_get(wl,
+					&service_id);
+			ret = evt_service_setup(service_id);
+			if (ret) {
+				evt_err("Failed to setup service core"
+						" for timer adapter\n");
+				return ret;
+			}
+			rte_service_runstate_set(service_id, 1);
+		}
+
+		ret = rte_event_timer_adapter_start(wl);
+		if (ret) {
+			evt_err("failed to Start event timer adapter %d", i);
+			return ret;
+		}
+		t->timer_adptr[i] = wl;
+	}
+	return 0;
+}
+
 int
 perf_event_dev_port_setup(struct evt_test *test, struct evt_options *opt,
 				uint8_t stride, uint8_t nb_queues,
@@ -326,6 +448,18 @@ perf_event_dev_port_setup(struct evt_test *test, struct evt_options *opt,
 		ret = perf_event_rx_adapter_setup(opt, stride, *port_conf);
 		if (ret)
 			return ret;
+	} else if (opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR) {
+		prod = 0;
+		for ( ; port < perf_nb_event_ports(opt); port++) {
+			struct prod_data *p = &t->prod[port];
+			p->queue_id = prod * stride;
+			p->t = t;
+			prod++;
+		}
+
+		ret = perf_event_timer_adapter_setup(t);
+		if (ret)
+			return ret;
 	} else {
 		prod = 0;
 		for ( ; port < perf_nb_event_ports(opt); port++) {
@@ -415,10 +549,13 @@ perf_opt_check(struct evt_options *opt, uint64_t nb_queues)
 	}

 	/* Fixups */
-	if (opt->nb_stages == 1 && opt->fwd_latency) {
+	if ((opt->nb_stages == 1 &&
+			opt->prod_type != EVT_PROD_TYPE_EVENT_TIMER_ADPTR) &&
+			opt->fwd_latency) {
 		evt_info("fwd_latency is valid when nb_stages > 1, disabling");
 		opt->fwd_latency = 0;
 	}
+
 	if (opt->fwd_latency && !opt->q_priority) {
 		evt_info("enabled queue priority for latency measurement");
 		opt->q_priority = 1;
@@ -447,8 +584,13 @@ perf_opt_dump(struct evt_options *opt, uint8_t nb_queues)
 void
 perf_eventdev_destroy(struct evt_test *test, struct evt_options *opt)
 {
-	RTE_SET_USED(test);
+	int i;
+	struct test_perf *t = evt_test_priv(test);

+	if (opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR) {
+		for (i = 0; i < opt->nb_timer_adptrs; i++)
+			rte_event_timer_adapter_stop(t->timer_adptr[i]);
+	}
 	rte_event_dev_stop(opt->dev_id);
 	rte_event_dev_close(opt->dev_id);
 }
@@ -488,7 +630,8 @@ perf_ethdev_setup(struct evt_test *test, struct evt_options *opt)
 		},
 	};

-	if (opt->prod_type == EVT_PROD_TYPE_SYNT)
+	if (opt->prod_type == EVT_PROD_TYPE_SYNT ||
+			opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR)
 		return 0;

 	if (!rte_eth_dev_count()) {
@@ -544,7 +687,8 @@ perf_mempool_setup(struct evt_test *test, struct evt_options *opt)
 {
 	struct test_perf *t = evt_test_priv(test);

-	if (opt->prod_type == EVT_PROD_TYPE_SYNT) {
+	if (opt->prod_type == EVT_PROD_TYPE_SYNT ||
+			opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR) {
 		t->pool = rte_mempool_create(test->name, /* mempool name */
 				opt->pool_sz, /* number of elements*/
 				sizeof(struct perf_elt), /* element size*/
@@ -594,10 +738,18 @@ perf_test_setup(struct evt_test *test, struct evt_options *opt)

 	struct test_perf *t = evt_test_priv(test);

-	t->outstand_pkts = opt->nb_pkts * evt_nr_active_lcores(opt->plcores);
+	if (opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR) {
+		t->outstand_pkts = opt->nb_timers *
+			evt_nr_active_lcores(opt->plcores);
+		t->nb_pkts = opt->nb_timers;
+	} else {
+		t->outstand_pkts = opt->nb_pkts *
+			evt_nr_active_lcores(opt->plcores);
+		t->nb_pkts = opt->nb_pkts;
+	}
+
 	t->nb_workers = evt_nr_active_lcores(opt->wlcores);
 	t->done = false;
-	t->nb_pkts = opt->nb_pkts;
 	t->nb_flows = opt->nb_flows;
 	t->result = EVT_TEST_FAILED;
 	t->opt = opt;
diff --git a/app/test-eventdev/test_perf_common.h b/app/test-eventdev/test_perf_common.h
index 9ad99733b..4e96f229c 100644
--- a/app/test-eventdev/test_perf_common.h
+++ b/app/test-eventdev/test_perf_common.h
@@ -13,6 +13,7 @@
 #include <rte_ethdev.h>
 #include <rte_eventdev.h>
 #include <rte_event_eth_rx_adapter.h>
+#include <rte_event_timer_adapter.h>
 #include <rte_lcore.h>
 #include <rte_malloc.h>
 #include <rte_mempool.h>
@@ -39,6 +40,7 @@ struct prod_data {
 	struct test_perf *t;
 } __rte_cache_aligned;

+
 struct test_perf {
 	/* Don't change the offset of "done". Signal handler use this memory
 	 * to terminate all lcores work.
@@ -54,9 +56,12 @@ struct test_perf {
 	struct worker_data worker[EVT_MAX_PORTS];
 	struct evt_options *opt;
 	uint8_t sched_type_list[EVT_MAX_STAGES] __rte_cache_aligned;
+	struct rte_event_timer_adapter *timer_adptr[
+		RTE_EVENT_TIMER_ADAPTER_NUM_MAX] __rte_cache_aligned;
 } __rte_cache_aligned;

 struct perf_elt {
+	struct rte_event_timer tim;
 	uint64_t timestamp;
 } __rte_cache_aligned;

@@ -68,6 +73,8 @@ struct perf_elt {
 	struct evt_options *opt = t->opt;\
 	const uint8_t dev = w->dev_id;\
 	const uint8_t port = w->port_id;\
+	const uint8_t prod_timer_type = \
+		opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR;\
 	uint8_t *const sched_type_list = &t->sched_type_list[0];\
 	struct rte_mempool *const pool = t->pool;\
 	const uint8_t nb_stages = t->opt->nb_stages;\
diff --git a/app/test-eventdev/test_perf_queue.c b/app/test-eventdev/test_perf_queue.c
index db8f2f3e5..74469a5ee 100644
--- a/app/test-eventdev/test_perf_queue.c
+++ b/app/test-eventdev/test_perf_queue.c
@@ -49,7 +49,7 @@ perf_queue_worker(void *arg, const int enable_fwd_latency)
 			rte_pause();
 			continue;
 		}
-		if (enable_fwd_latency)
+		if (enable_fwd_latency && !prod_timer_type)
 		/* first q in pipeline, mark timestamp to compute fwd latency */
 			mark_fwd_latency(&ev, nb_stages);

@@ -88,7 +88,7 @@ perf_queue_worker_burst(void *arg, const int enable_fwd_latency)
 		}

 		for (i = 0; i < nb_rx; i++) {
-			if (enable_fwd_latency) {
+			if (enable_fwd_latency && !prod_timer_type) {
 				rte_prefetch0(ev[i+1].event_ptr);
 				/* first queue in pipeline.
 				 * mark time stamp to compute fwd latency
@@ -161,7 +161,8 @@ perf_queue_eventdev_setup(struct evt_test *test, struct evt_options *opt)
 	struct rte_event_dev_info dev_info;

 	nb_ports = evt_nr_active_lcores(opt->wlcores);
-	nb_ports += opt->prod_type == EVT_PROD_TYPE_ETH_RX_ADPTR ? 0 :
+	nb_ports += opt->prod_type == EVT_PROD_TYPE_ETH_RX_ADPTR ||
+		 opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR ? 0 :
 		evt_nr_active_lcores(opt->plcores);

 	nb_queues = perf_queue_nb_event_queues(opt);
--
2.16.2

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [dpdk-dev] [PATCH v2 2/4] app/eventdev: add burst mode for event timer adapter
  2018-04-03 16:01 ` [dpdk-dev] [PATCH v2 " Pavan Nikhilesh
@ 2018-04-03 16:01   ` Pavan Nikhilesh
  2018-04-04 21:07     ` Carrillo, Erik G
  2018-04-03 16:01   ` [dpdk-dev] [PATCH v2 3/4] app/eventdev: add options to configure " Pavan Nikhilesh
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 36+ messages in thread
From: Pavan Nikhilesh @ 2018-04-03 16:01 UTC (permalink / raw)
  To: jerin.jacob, santosh.shukla, erik.g.carrillo; +Cc: dev, Pavan Nikhilesh

Add burst mode for event timer adapter that can be selected by passing
--prod_type_timerdev_burst.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@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

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [dpdk-dev] [PATCH v2 3/4] app/eventdev: add options to configure event timer adapter
  2018-04-03 16:01 ` [dpdk-dev] [PATCH v2 " Pavan Nikhilesh
  2018-04-03 16:01   ` [dpdk-dev] [PATCH v2 2/4] app/eventdev: add burst mode for event timer adapter Pavan Nikhilesh
@ 2018-04-03 16:01   ` Pavan Nikhilesh
  2018-04-04 21:10     ` Carrillo, Erik G
  2018-04-03 16:01   ` [dpdk-dev] [PATCH v2 4/4] doc: update test eventdev documentation Pavan Nikhilesh
  2018-04-03 20:21   ` [dpdk-dev] [PATCH v2 1/4] app/eventdev: add event timer adapter as a producer Carrillo, Erik G
  3 siblings, 1 reply; 36+ messages in thread
From: Pavan Nikhilesh @ 2018-04-03 16:01 UTC (permalink / raw)
  To: jerin.jacob, santosh.shukla, erik.g.carrillo; +Cc: dev, Pavan Nikhilesh

Add options to configure expiry timeout, max number of timers and number
of event timer adapters through command line parameters.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
---
 app/test-eventdev/evt_options.c | 65 +++++++++++++++++++++++++++++++++++++++++
 app/test-eventdev/evt_options.h |  5 ++++
 2 files changed, 70 insertions(+)

diff --git a/app/test-eventdev/evt_options.c b/app/test-eventdev/evt_options.c
index 05d6de88b..a04ffea8f 100644
--- a/app/test-eventdev/evt_options.c
+++ b/app/test-eventdev/evt_options.c
@@ -140,6 +140,56 @@ evt_parse_nb_pkts(struct evt_options *opt, const char *arg)
 	return ret;
 }
 
+static int
+evt_parse_nb_timers(struct evt_options *opt, const char *arg)
+{
+	int ret;
+
+	ret = parser_read_uint64(&(opt->nb_timers), arg);
+
+	return ret;
+}
+
+static int
+evt_parse_bkt_tck_nsec(struct evt_options *opt, const char *arg)
+{
+	int ret;
+
+	ret = parser_read_uint64(&(opt->bkt_tck_nsec), arg);
+
+	return ret;
+}
+
+static int
+evt_parse_max_tmo_nsec(struct evt_options *opt, const char *arg)
+{
+	int ret;
+
+	ret = parser_read_uint64(&(opt->max_tmo_nsec), arg);
+
+	return ret;
+}
+
+static int
+evt_parse_nb_bkt_tcks(struct evt_options *opt, const char *arg)
+{
+	int ret;
+
+	ret = parser_read_uint64(&(opt->nb_bkt_tcks), arg);
+
+	return ret;
+}
+
+static int
+evt_parse_nb_timer_adptrs(struct evt_options *opt, const char *arg)
+{
+	int ret;
+
+	ret = parser_read_uint8(&(opt->nb_timer_adptrs), arg);
+
+	return ret;
+}
+
 static int
 evt_parse_pool_sz(struct evt_options *opt, const char *arg)
 {
@@ -196,6 +246,11 @@ usage(char *program)
 		"\t                     in ns.\n"
 		"\t--prod_type_timerdev_burst : use timer device as producer\n"
 		"\t                             burst mode.\n"
+		"\t--nb_timers        : number of timers to arm.\n"
+		"\t--nb_timer_adptrs  : number of timer adapters to use.\n"
+		"\t--bkt_tck_nsec     : timer bucket tick interval in ns.\n"
+		"\t--max_tmo_nsec     : max timeout interval in ns.\n"
+		"\t--nb_bkt_tcks      : number of bucket ticks for each timer\n"
 		);
 	printf("available tests:\n");
 	evt_test_dump_names();
@@ -259,6 +314,11 @@ static struct option lgopts[] = {
 	{ EVT_PROD_ETHDEV,         0, 0, 0 },
 	{ EVT_PROD_TIMERDEV,       0, 0, 0 },
 	{ EVT_PROD_TIMERDEV_BURST, 0, 0, 0 },
+	{ EVT_NB_TIMERS,           1, 0, 0 },
+	{ EVT_NB_TIMER_ADPTRS,     1, 0, 0 },
+	{ EVT_BKT_TCK_NSEC,        1, 0, 0 },
+	{ EVT_MAX_TMO_NSEC,        1, 0, 0 },
+	{ EVT_NB_BKT_TCKS,         1, 0, 0 },
 	{ EVT_HELP,                0, 0, 0 },
 	{ NULL,                    0, 0, 0 }
 };
@@ -285,6 +345,11 @@ evt_opts_parse_long(int opt_idx, struct evt_options *opt)
 		{ 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},
+		{ EVT_NB_TIMERS, evt_parse_nb_timers},
+		{ EVT_NB_TIMER_ADPTRS, evt_parse_nb_timer_adptrs},
+		{ EVT_BKT_TCK_NSEC, evt_parse_bkt_tck_nsec},
+		{ EVT_MAX_TMO_NSEC, evt_parse_max_tmo_nsec},
+		{ EVT_NB_BKT_TCKS, evt_parse_nb_bkt_tcks},
 	};
 
 	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 03078b21b..80a9ebd8f 100644
--- a/app/test-eventdev/evt_options.h
+++ b/app/test-eventdev/evt_options.h
@@ -33,6 +33,11 @@
 #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_NB_TIMERS            ("nb_timers")
+#define EVT_NB_TIMER_ADPTRS      ("nb_timer_adptrs")
+#define EVT_BKT_TCK_NSEC         ("bkt_tck_nsec")
+#define EVT_MAX_TMO_NSEC         ("max_tmo_nsec")
+#define EVT_NB_BKT_TCKS          ("nb_bkt_tcks")
 #define EVT_HELP                 ("help")
 
 enum evt_prod_type {
-- 
2.16.2

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [dpdk-dev] [PATCH v2 4/4] doc: update test eventdev documentation
  2018-04-03 16:01 ` [dpdk-dev] [PATCH v2 " Pavan Nikhilesh
  2018-04-03 16:01   ` [dpdk-dev] [PATCH v2 2/4] app/eventdev: add burst mode for event timer adapter Pavan Nikhilesh
  2018-04-03 16:01   ` [dpdk-dev] [PATCH v2 3/4] app/eventdev: add options to configure " Pavan Nikhilesh
@ 2018-04-03 16:01   ` Pavan Nikhilesh
  2018-04-04 21:16     ` Carrillo, Erik G
  2018-04-03 20:21   ` [dpdk-dev] [PATCH v2 1/4] app/eventdev: add event timer adapter as a producer Carrillo, Erik G
  3 siblings, 1 reply; 36+ messages in thread
From: Pavan Nikhilesh @ 2018-04-03 16:01 UTC (permalink / raw)
  To: jerin.jacob, santosh.shukla, erik.g.carrillo; +Cc: dev, Pavan Nikhilesh

Update documentation to include new options added for using event timer
adapter as a producer.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
---
 doc/guides/tools/testeventdev.rst | 60 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/doc/guides/tools/testeventdev.rst b/doc/guides/tools/testeventdev.rst
index 77480ffe9..ab07c0284 100644
--- a/doc/guides/tools/testeventdev.rst
+++ b/doc/guides/tools/testeventdev.rst
@@ -123,6 +123,36 @@ The following are the application command-line options:
 
         Use ethernet device as producer.
 
+* ``--prod_type_timerdev``
+
+        Use event timer adapter as producer.
+
+ * ``--prod_type_timerdev_burst``
+
+        Use burst mode event timer adapter as producer.
+
+ * ``--bkt_tck_nsec``
+
+        Used to dictate number of nano seconds between bucket traversal of the
+        event timer adapter. Refer `rte_event_timer_adapter_conf`.
+
+ * ``--max_tmo_nsec``
+
+        Used to configure event timer adapter max arm timeout in nano seconds.
+
+ * ``--nb_bkt_tcks``
+
+        Dictate the number of bucket ticks after which the event timer expires.
+
+ * ``--nb_timers``
+
+        Number of event timers each producer cores will generate.
+
+ * ``--nb_timer_adptrs``
+
+        Number of event timer adapters to be used. Each adapter is used in
+        round robin manner by the producer cores.
+
 Eventdev Tests
 --------------
 
@@ -347,6 +377,13 @@ Supported application command line options are following::
         --fwd_latency
         --queue_priority
         --prod_type_ethdev
+        --prod_type_timerdev_burst
+        --prod_type_timerdev
+        --bkt_tck_nsec
+        --max_tmo_nsec
+        --nb_bkt_tcks
+        --nb_timers
+        --nb_timer_adptrs
 
 Example
 ^^^^^^^
@@ -365,6 +402,14 @@ Example command to run perf queue test with ethernet ports:
    sudo build/app/dpdk-test-eventdev --vdev=event_sw0 -- \
         --test=perf_queue --plcores=2 --wlcore=3 --stlist=p --prod_type_ethdev
 
+Example command to run perf queue test with event timer adapter:
+
+.. code-block:: console
+
+   sudo  build/app/dpdk-test-eventdev --vdev="event_octeontx" -- \
+                --wlcores 4 --plcores 12 --test perf_queue --stlist=a \
+                --prod_type_timerdev --fwd_latency
+
 PERF_ATQ Test
 ~~~~~~~~~~~~~~~
 
@@ -431,6 +476,13 @@ Supported application command line options are following::
         --worker_deq_depth
         --fwd_latency
         --prod_type_ethdev
+        --prod_type_timerdev_burst
+        --prod_type_timerdev
+        --bkt_tck_nsec
+        --max_tmo_nsec
+        --nb_bkt_tcks
+        --nb_timers
+        --nb_timer_adptrs
 
 Example
 ^^^^^^^
@@ -442,6 +494,14 @@ Example command to run perf ``all types queue`` test:
    sudo build/app/dpdk-test-eventdev --vdev=event_octeontx -- \
                 --test=perf_atq --plcores=2 --wlcore=3 --stlist=p --nb_pkts=0
 
+Example command to run perf ``all types queue`` test with event timer adapter:
+
+.. code-block:: console
+
+   sudo  build/app/dpdk-test-eventdev --vdev="event_octeontx" -- \
+                --wlcores 4 --plcores 12 --test perf_atq --verbose 20 \
+                --stlist=a --prod_type_timerdev --fwd_latency
+
 
 PIPELINE_QUEUE Test
 ~~~~~~~~~~~~~~~~~~~
-- 
2.16.2

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [dpdk-dev] [PATCH v2 1/4] app/eventdev: add event timer adapter as a producer
  2018-04-03 16:01 ` [dpdk-dev] [PATCH v2 " Pavan Nikhilesh
                     ` (2 preceding siblings ...)
  2018-04-03 16:01   ` [dpdk-dev] [PATCH v2 4/4] doc: update test eventdev documentation Pavan Nikhilesh
@ 2018-04-03 20:21   ` Carrillo, Erik G
  2018-04-04 21:20     ` Carrillo, Erik G
  3 siblings, 1 reply; 36+ messages in thread
From: Carrillo, Erik G @ 2018-04-03 20:21 UTC (permalink / raw)
  To: Pavan Nikhilesh, jerin.jacob, santosh.shukla; +Cc: dev

Hi Pavan,

One comment in-line:

> -----Original Message-----
> From: Pavan Nikhilesh [mailto:pbhagavatula@caviumnetworks.com]
> Sent: Tuesday, April 3, 2018 11:02 AM
> To: jerin.jacob@caviumnetworks.com;
> santosh.shukla@caviumnetworks.com; Carrillo, Erik G
> <erik.g.carrillo@intel.com>
> Cc: dev@dpdk.org; Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
> Subject: [dpdk-dev] [PATCH v2 1/4] app/eventdev: add event timer adapter
> as a producer
> 
> Add event timer adapter as producer option that can be selected by passing -
> -prod_type_timerdev.
> 
> Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
> ---

<...snipped...>

> diff --git a/app/test-eventdev/evt_options.h b/app/test-
> eventdev/evt_options.h index 46d122229..37debae84 100644
> --- a/app/test-eventdev/evt_options.h
> +++ b/app/test-eventdev/evt_options.h
> @@ -31,12 +31,14 @@
>  #define EVT_FWD_LATENCY          ("fwd_latency")
>  #define EVT_QUEUE_PRIORITY       ("queue_priority")
>  #define EVT_PROD_ETHDEV          ("prod_type_ethdev")
> +#define EVT_PROD_TIMERDEV        ("prod_type_timerdev")
>  #define EVT_HELP                 ("help")
> 
>  enum evt_prod_type {
>  	EVT_PROD_TYPE_NONE,
>  	EVT_PROD_TYPE_SYNT,          /* Producer type Synthetic i.e. CPU. */
>  	EVT_PROD_TYPE_ETH_RX_ADPTR,  /* Producer type Eth Rx Adapter.
> */
> +	EVT_PROD_TYPE_EVENT_TIMER_ADPTR,  /* Producer type Eth Rx
> Adapter. */

Comment didn't get updated here.

>  	EVT_PROD_TYPE_MAX,
>  };
> 
> @@ -52,11 +54,18 @@ struct evt_options {
>  	int nb_stages;
>  	int verbose_level;
>  	uint64_t nb_pkts;
> +	uint8_t nb_timer_adptrs;
> +	uint64_t nb_timers;
> +	uint64_t bkt_tck_nsec;
> +	uint64_t optm_bkt_tck_nsec;
> +	uint64_t max_tmo_nsec;
> +	uint64_t nb_bkt_tcks;
>  	uint16_t wkr_deq_dep;
>  	uint8_t dev_id;
>  	uint32_t fwd_latency:1;
>  	uint32_t q_priority:1;
>  	enum evt_prod_type prod_type;
> +	uint8_t timdev_cnt;
>  };
> 
>  void evt_options_default(struct evt_options *opt); diff --git a/app/test-
> eventdev/test_perf_atq.c b/app/test-eventdev/test_perf_atq.c
> index b36b22a77..b3a312722 100644

<...snipped...>

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [dpdk-dev] [PATCH v2 2/4] app/eventdev: add burst mode for event timer adapter
  2018-04-03 16:01   ` [dpdk-dev] [PATCH v2 2/4] app/eventdev: add burst mode for event timer adapter Pavan Nikhilesh
@ 2018-04-04 21:07     ` Carrillo, Erik G
  0 siblings, 0 replies; 36+ messages in thread
From: Carrillo, Erik G @ 2018-04-04 21:07 UTC (permalink / raw)
  To: Pavan Nikhilesh, jerin.jacob, santosh.shukla; +Cc: dev

> -----Original Message-----
> From: Pavan Nikhilesh [mailto:pbhagavatula@caviumnetworks.com]
> Sent: Tuesday, April 3, 2018 11:02 AM
> To: jerin.jacob@caviumnetworks.com;
> santosh.shukla@caviumnetworks.com; Carrillo, Erik G
> <erik.g.carrillo@intel.com>
> Cc: dev@dpdk.org; Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
> Subject: [dpdk-dev] [PATCH v2 2/4] app/eventdev: add burst mode for
> event timer adapter
> 
> Add burst mode for event timer adapter that can be selected by passing --
> prod_type_timerdev_burst.
> 
> Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
> ---

Acked-by: Erik Gabriel Carrillo <erik.g.carrillo@intel.com>

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [dpdk-dev] [PATCH v2 3/4] app/eventdev: add options to configure event timer adapter
  2018-04-03 16:01   ` [dpdk-dev] [PATCH v2 3/4] app/eventdev: add options to configure " Pavan Nikhilesh
@ 2018-04-04 21:10     ` Carrillo, Erik G
  0 siblings, 0 replies; 36+ messages in thread
From: Carrillo, Erik G @ 2018-04-04 21:10 UTC (permalink / raw)
  To: Pavan Nikhilesh, jerin.jacob, santosh.shukla; +Cc: dev

> -----Original Message-----
> From: Pavan Nikhilesh [mailto:pbhagavatula@caviumnetworks.com]
> Sent: Tuesday, April 3, 2018 11:02 AM
> To: jerin.jacob@caviumnetworks.com;
> santosh.shukla@caviumnetworks.com; Carrillo, Erik G
> <erik.g.carrillo@intel.com>
> Cc: dev@dpdk.org; Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
> Subject: [dpdk-dev] [PATCH v2 3/4] app/eventdev: add options to configure
> event timer adapter
> 
> Add options to configure expiry timeout, max number of timers and number
> of event timer adapters through command line parameters.
> 
> Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
> ---

Acked-by: Erik Gabriel Carrillo <erik.g.carrillo@intel.com>

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [dpdk-dev] [PATCH v2 4/4] doc: update test eventdev documentation
  2018-04-03 16:01   ` [dpdk-dev] [PATCH v2 4/4] doc: update test eventdev documentation Pavan Nikhilesh
@ 2018-04-04 21:16     ` Carrillo, Erik G
  0 siblings, 0 replies; 36+ messages in thread
From: Carrillo, Erik G @ 2018-04-04 21:16 UTC (permalink / raw)
  To: Pavan Nikhilesh, jerin.jacob, santosh.shukla; +Cc: dev



> -----Original Message-----
> From: Pavan Nikhilesh [mailto:pbhagavatula@caviumnetworks.com]
> Sent: Tuesday, April 3, 2018 11:02 AM
> To: jerin.jacob@caviumnetworks.com;
> santosh.shukla@caviumnetworks.com; Carrillo, Erik G
> <erik.g.carrillo@intel.com>
> Cc: dev@dpdk.org; Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
> Subject: [dpdk-dev] [PATCH v2 4/4] doc: update test eventdev
> documentation
> 
> Update documentation to include new options added for using event timer
> adapter as a producer.
> 
> Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
> ---
>  doc/guides/tools/testeventdev.rst | 60
> +++++++++++++++++++++++++++++++++++++++
>  1 file changed, 60 insertions(+)
> 
> diff --git a/doc/guides/tools/testeventdev.rst
> b/doc/guides/tools/testeventdev.rst
> index 77480ffe9..ab07c0284 100644
> --- a/doc/guides/tools/testeventdev.rst
> +++ b/doc/guides/tools/testeventdev.rst
> @@ -123,6 +123,36 @@ The following are the application command-line
> options:
> 
>          Use ethernet device as producer.
> 
> +* ``--prod_type_timerdev``
> +
> +        Use event timer adapter as producer.
> +
> + * ``--prod_type_timerdev_burst``
> +
> +        Use burst mode event timer adapter as producer.
> +
> + * ``--bkt_tck_nsec``
> +
> +        Used to dictate number of nano seconds between bucket traversal of
> the
> +        event timer adapter. Refer `rte_event_timer_adapter_conf`.
> +
> + * ``--max_tmo_nsec``
> +
> +        Used to configure event timer adapter max arm timeout in nano
> seconds.
> +
> + * ``--nb_bkt_tcks``
> +
> +        Dictate the number of bucket ticks after which the event timer expires.
> +
> + * ``--nb_timers``
> +
> +        Number of event timers each producer cores will generate.

s/cores/core/

> +
> + * ``--nb_timer_adptrs``
> +
> +        Number of event timer adapters to be used. Each adapter is used in
> +        round robin manner by the producer cores.
> +
>  Eventdev Tests
>  --------------

<...snipped...>

One minor grammatical edit, and with that:

Acked-by: Erik Gabriel Carrillo <erik.g.carrillo@intel.com>

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [dpdk-dev] [PATCH v2 1/4] app/eventdev: add event timer adapter as a producer
  2018-04-03 20:21   ` [dpdk-dev] [PATCH v2 1/4] app/eventdev: add event timer adapter as a producer Carrillo, Erik G
@ 2018-04-04 21:20     ` Carrillo, Erik G
  0 siblings, 0 replies; 36+ messages in thread
From: Carrillo, Erik G @ 2018-04-04 21:20 UTC (permalink / raw)
  To: 'Pavan Nikhilesh',
	'jerin.jacob@caviumnetworks.com',
	'santosh.shukla@caviumnetworks.com'
  Cc: 'dev@dpdk.org'

> -----Original Message-----
> From: Carrillo, Erik G
> Sent: Tuesday, April 3, 2018 3:21 PM
> To: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>;
> jerin.jacob@caviumnetworks.com; santosh.shukla@caviumnetworks.com
> Cc: dev@dpdk.org
> Subject: RE: [dpdk-dev] [PATCH v2 1/4] app/eventdev: add event timer
> adapter as a producer
> 
> Hi Pavan,
> 
> One comment in-line:
> 
> > -----Original Message-----
> > From: Pavan Nikhilesh [mailto:pbhagavatula@caviumnetworks.com]
> > Sent: Tuesday, April 3, 2018 11:02 AM
> > To: jerin.jacob@caviumnetworks.com;
> > santosh.shukla@caviumnetworks.com; Carrillo, Erik G
> > <erik.g.carrillo@intel.com>
> > Cc: dev@dpdk.org; Pavan Nikhilesh
> <pbhagavatula@caviumnetworks.com>
> > Subject: [dpdk-dev] [PATCH v2 1/4] app/eventdev: add event timer
> > adapter as a producer
> >
> > Add event timer adapter as producer option that can be selected by
> > passing - -prod_type_timerdev.
> >
> > Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
> > ---
> 
> <...snipped...>
> 
> > diff --git a/app/test-eventdev/evt_options.h b/app/test-
> > eventdev/evt_options.h index 46d122229..37debae84 100644
> > --- a/app/test-eventdev/evt_options.h
> > +++ b/app/test-eventdev/evt_options.h
> > @@ -31,12 +31,14 @@
> >  #define EVT_FWD_LATENCY          ("fwd_latency")
> >  #define EVT_QUEUE_PRIORITY       ("queue_priority")
> >  #define EVT_PROD_ETHDEV          ("prod_type_ethdev")
> > +#define EVT_PROD_TIMERDEV        ("prod_type_timerdev")
> >  #define EVT_HELP                 ("help")
> >
> >  enum evt_prod_type {
> >  	EVT_PROD_TYPE_NONE,
> >  	EVT_PROD_TYPE_SYNT,          /* Producer type Synthetic i.e. CPU. */
> >  	EVT_PROD_TYPE_ETH_RX_ADPTR,  /* Producer type Eth Rx Adapter.
> > */
> > +	EVT_PROD_TYPE_EVENT_TIMER_ADPTR,  /* Producer type Eth Rx
> > Adapter. */
> 
> Comment didn't get updated here.
> 

With that edit:

Acked-by: Erik Gabriel Carrillo <erik.g.carrillo@intel.com>

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [dpdk-dev] [PATCH v3 1/4] app/eventdev: add event timer adapter as a producer
  2018-03-18 13:12 [dpdk-dev] [PATCH 1/4] app/eventdev: add event timer adapter as a producer Pavan Nikhilesh
                   ` (4 preceding siblings ...)
  2018-04-03 16:01 ` [dpdk-dev] [PATCH v2 " Pavan Nikhilesh
@ 2018-04-05 11:53 ` Pavan Nikhilesh
  2018-04-05 11:53   ` [dpdk-dev] [PATCH v3 2/4] app/eventdev: add burst mode for event timer adapter Pavan Nikhilesh
                     ` (4 more replies)
  2018-04-06 14:55 ` [dpdk-dev] [PATCH v4 " Pavan Nikhilesh
  2018-04-06 15:13 ` [dpdk-dev] [PATCH v5 1/4] app/eventdev: add event timer adapter as a producer Pavan Nikhilesh
  7 siblings, 5 replies; 36+ messages in thread
From: Pavan Nikhilesh @ 2018-04-05 11:53 UTC (permalink / raw)
  To: jerin.jacob, santosh.shukla, erik.g.carrillo; +Cc: dev, Pavan Nikhilesh

Add event timer adapter as producer option that can be selected by
passing --prod_type_timerdev.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
---

 v3 Changes:
 - Add detailed options dump.
 - Fix few typos.

 v2 Changes:
 - set timer to NOT_ARMED before trying to arm it.
 - prevent edge cases for timeout_ticks being set to 0.

 app/test-eventdev/evt_options.c      |  54 +++++++----
 app/test-eventdev/evt_options.h      |  24 +++++
 app/test-eventdev/test_perf_atq.c    |  10 +--
 app/test-eventdev/test_perf_common.c | 170 +++++++++++++++++++++++++++++++++--
 app/test-eventdev/test_perf_common.h |   7 ++
 app/test-eventdev/test_perf_queue.c  |   7 +-
 6 files changed, 236 insertions(+), 36 deletions(-)

diff --git a/app/test-eventdev/evt_options.c b/app/test-eventdev/evt_options.c
index 9683b2224..49cd9c419 100644
--- a/app/test-eventdev/evt_options.c
+++ b/app/test-eventdev/evt_options.c
@@ -27,6 +27,11 @@ evt_options_default(struct evt_options *opt)
 	opt->pool_sz = 16 * 1024;
 	opt->wkr_deq_dep = 16;
 	opt->nb_pkts = (1ULL << 26); /* do ~64M packets */
+	opt->nb_timers = 1E8;
+	opt->nb_timer_adptrs = 1;
+	opt->bkt_tck_nsec = 1E3; /* 1000ns ~ 1us */
+	opt->max_tmo_nsec = 1E5; /* 100us */
+	opt->nb_bkt_tcks = 10;   /* 50us */
 	opt->prod_type = EVT_PROD_TYPE_SYNT;
 }

@@ -86,6 +91,13 @@ evt_parse_eth_prod_type(struct evt_options *opt, const char *arg __rte_unused)
 	return 0;
 }

+static int
+evt_parse_timer_prod_type(struct evt_options *opt, const char *arg __rte_unused)
+{
+	opt->prod_type = EVT_PROD_TYPE_EVENT_TIMER_ADPTR;
+	return 0;
+}
+
 static int
 evt_parse_test_name(struct evt_options *opt, const char *arg)
 {
@@ -169,7 +181,10 @@ usage(char *program)
 		"\t--worker_deq_depth : dequeue depth of the worker\n"
 		"\t--fwd_latency      : perform fwd_latency measurement\n"
 		"\t--queue_priority   : enable queue priority\n"
-		"\t--prod_type_ethdev : use ethernet device as producer\n."
+		"\t--prod_type_ethdev : use ethernet device as producer.\n"
+		"\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"
 		);
 	printf("available tests:\n");
 	evt_test_dump_names();
@@ -217,22 +232,23 @@ evt_parse_sched_type_list(struct evt_options *opt, const char *arg)
 }

 static struct option lgopts[] = {
-	{ EVT_NB_FLOWS,         1, 0, 0 },
-	{ EVT_DEVICE,           1, 0, 0 },
-	{ EVT_VERBOSE,          1, 0, 0 },
-	{ EVT_TEST,             1, 0, 0 },
-	{ EVT_PROD_LCORES,      1, 0, 0 },
-	{ EVT_WORK_LCORES,      1, 0, 0 },
-	{ EVT_SOCKET_ID,        1, 0, 0 },
-	{ EVT_POOL_SZ,          1, 0, 0 },
-	{ EVT_NB_PKTS,          1, 0, 0 },
-	{ EVT_WKR_DEQ_DEP,      1, 0, 0 },
-	{ EVT_SCHED_TYPE_LIST,  1, 0, 0 },
-	{ EVT_FWD_LATENCY,      0, 0, 0 },
-	{ EVT_QUEUE_PRIORITY,   0, 0, 0 },
-	{ EVT_PROD_ETHDEV,      0, 0, 0 },
-	{ EVT_HELP,             0, 0, 0 },
-	{ NULL,                 0, 0, 0 }
+	{ EVT_NB_FLOWS,            1, 0, 0 },
+	{ EVT_DEVICE,              1, 0, 0 },
+	{ EVT_VERBOSE,             1, 0, 0 },
+	{ EVT_TEST,                1, 0, 0 },
+	{ EVT_PROD_LCORES,         1, 0, 0 },
+	{ EVT_WORK_LCORES,         1, 0, 0 },
+	{ EVT_SOCKET_ID,           1, 0, 0 },
+	{ EVT_POOL_SZ,             1, 0, 0 },
+	{ EVT_NB_PKTS,             1, 0, 0 },
+	{ EVT_WKR_DEQ_DEP,         1, 0, 0 },
+	{ EVT_SCHED_TYPE_LIST,     1, 0, 0 },
+	{ EVT_FWD_LATENCY,         0, 0, 0 },
+	{ EVT_QUEUE_PRIORITY,      0, 0, 0 },
+	{ EVT_PROD_ETHDEV,         0, 0, 0 },
+	{ EVT_PROD_TIMERDEV,       0, 0, 0 },
+	{ EVT_HELP,                0, 0, 0 },
+	{ NULL,                    0, 0, 0 }
 };

 static int
@@ -255,11 +271,12 @@ evt_opts_parse_long(int opt_idx, struct evt_options *opt)
 		{ EVT_FWD_LATENCY, evt_parse_fwd_latency},
 		{ EVT_QUEUE_PRIORITY, evt_parse_queue_priority},
 		{ EVT_PROD_ETHDEV, evt_parse_eth_prod_type},
+		{ EVT_PROD_TIMERDEV, evt_parse_timer_prod_type},
 	};

 	for (i = 0; i < RTE_DIM(parsermap); i++) {
 		if (strncmp(lgopts[opt_idx].name, parsermap[i].lgopt_name,
-				strlen(parsermap[i].lgopt_name)) == 0)
+				strlen(lgopts[opt_idx].name)) == 0)
 			return parsermap[i].parser_fn(opt, optarg);
 	}

@@ -305,6 +322,7 @@ evt_options_dump(struct evt_options *opt)
 	evt_dump("pool_sz", "%d", opt->pool_sz);
 	evt_dump("master lcore", "%d", rte_get_master_lcore());
 	evt_dump("nb_pkts", "%"PRIu64, opt->nb_pkts);
+	evt_dump("nb_timers", "%"PRIu64, opt->nb_timers);
 	evt_dump_begin("available lcores");
 	RTE_LCORE_FOREACH(lcore_id)
 		printf("%d ", lcore_id);
diff --git a/app/test-eventdev/evt_options.h b/app/test-eventdev/evt_options.h
index 46d122229..1fb340ac9 100644
--- a/app/test-eventdev/evt_options.h
+++ b/app/test-eventdev/evt_options.h
@@ -9,6 +9,7 @@
 #include <stdbool.h>

 #include <rte_common.h>
+#include <rte_ethdev.h>
 #include <rte_eventdev.h>
 #include <rte_lcore.h>

@@ -31,12 +32,14 @@
 #define EVT_FWD_LATENCY          ("fwd_latency")
 #define EVT_QUEUE_PRIORITY       ("queue_priority")
 #define EVT_PROD_ETHDEV          ("prod_type_ethdev")
+#define EVT_PROD_TIMERDEV        ("prod_type_timerdev")
 #define EVT_HELP                 ("help")

 enum evt_prod_type {
 	EVT_PROD_TYPE_NONE,
 	EVT_PROD_TYPE_SYNT,          /* Producer type Synthetic i.e. CPU. */
 	EVT_PROD_TYPE_ETH_RX_ADPTR,  /* Producer type Eth Rx Adapter. */
+	EVT_PROD_TYPE_EVENT_TIMER_ADPTR,  /* Producer type Timer Adapter. */
 	EVT_PROD_TYPE_MAX,
 };

@@ -52,11 +55,18 @@ struct evt_options {
 	int nb_stages;
 	int verbose_level;
 	uint64_t nb_pkts;
+	uint8_t nb_timer_adptrs;
+	uint64_t nb_timers;
+	uint64_t bkt_tck_nsec;
+	uint64_t optm_bkt_tck_nsec;
+	uint64_t max_tmo_nsec;
+	uint64_t nb_bkt_tcks;
 	uint16_t wkr_deq_dep;
 	uint8_t dev_id;
 	uint32_t fwd_latency:1;
 	uint32_t q_priority:1;
 	enum evt_prod_type prod_type;
+	uint8_t timdev_cnt;
 };

 void evt_options_default(struct evt_options *opt);
@@ -262,6 +272,20 @@ evt_dump_producer_type(struct evt_options *opt)
 	case EVT_PROD_TYPE_ETH_RX_ADPTR:
 		snprintf(name, EVT_PROD_MAX_NAME_LEN,
 				"Ethdev Rx Adapter producers");
+		evt_dump("nb_ethdev", "%d", rte_eth_dev_count());
+		break;
+	case EVT_PROD_TYPE_EVENT_TIMER_ADPTR:
+		snprintf(name, EVT_PROD_MAX_NAME_LEN,
+				"Event timer adapter producer");
+		evt_dump("nb_timer_adapters", "%d", opt->nb_timer_adptrs);
+		evt_dump("max_tmo_nsec", "%"PRIu64"", opt->max_tmo_nsec);
+		evt_dump("nb_bkt_tcks", "%"PRIu64"", opt->nb_bkt_tcks);
+		if (opt->optm_bkt_tck_nsec)
+			evt_dump("bkt_tck_nsec", "%"PRIu64"",
+					opt->optm_bkt_tck_nsec);
+		else
+			evt_dump("bkt_tck_nsec", "%"PRIu64"",
+					opt->bkt_tck_nsec);
 		break;
 	}
 	evt_dump("prod_type", "%s", name);
diff --git a/app/test-eventdev/test_perf_atq.c b/app/test-eventdev/test_perf_atq.c
index b36b22a77..b3a312722 100644
--- a/app/test-eventdev/test_perf_atq.c
+++ b/app/test-eventdev/test_perf_atq.c
@@ -43,15 +43,12 @@ perf_atq_worker(void *arg, const int enable_fwd_latency)
 	while (t->done == false) {
 		uint16_t event = rte_event_dequeue_burst(dev, port, &ev, 1, 0);

-		if (enable_fwd_latency)
-			rte_prefetch0(ev.event_ptr);
-
 		if (!event) {
 			rte_pause();
 			continue;
 		}

-		if (enable_fwd_latency)
+		if (enable_fwd_latency && !prod_timer_type)
 		/* first stage in pipeline, mark ts to compute fwd latency */
 			atq_mark_fwd_latency(&ev);

@@ -90,7 +87,7 @@ perf_atq_worker_burst(void *arg, const int enable_fwd_latency)
 		}

 		for (i = 0; i < nb_rx; i++) {
-			if (enable_fwd_latency) {
+			if (enable_fwd_latency && !prod_timer_type) {
 				rte_prefetch0(ev[i+1].event_ptr);
 				/* first stage in pipeline.
 				 * mark time stamp to compute fwd latency
@@ -163,7 +160,8 @@ perf_atq_eventdev_setup(struct evt_test *test, struct evt_options *opt)
 	struct rte_event_dev_info dev_info;

 	nb_ports = evt_nr_active_lcores(opt->wlcores);
-	nb_ports += opt->prod_type == EVT_PROD_TYPE_ETH_RX_ADPTR ? 0 :
+	nb_ports += (opt->prod_type == EVT_PROD_TYPE_ETH_RX_ADPTR ||
+			opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR) ? 0 :
 		evt_nr_active_lcores(opt->plcores);

 	nb_queues = atq_nb_event_queues(opt);
diff --git a/app/test-eventdev/test_perf_common.c b/app/test-eventdev/test_perf_common.c
index 59fa0a49e..39072eb5d 100644
--- a/app/test-eventdev/test_perf_common.c
+++ b/app/test-eventdev/test_perf_common.c
@@ -72,6 +72,66 @@ perf_producer(void *arg)
 	return 0;
 }

+static inline int
+perf_event_timer_producer(void *arg)
+{
+	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 = 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(pool, (void **)&m) < 0)
+			continue;
+
+		m->tim = tim;
+		m->tim.ev.flow_id = flow_counter++ % nb_flows;
+		m->tim.ev.event_ptr = m;
+		m->timestamp = rte_get_timer_cycles();
+		while (rte_event_timer_arm_burst(
+				adptr[flow_counter % nb_timer_adptrs],
+				(struct rte_event_timer **)&m, 1) != 1) {
+			if (t->done)
+				break;
+			rte_pause();
+			m->timestamp = rte_get_timer_cycles();
+		}
+		arm_latency += rte_get_timer_cycles() - m->timestamp;
+		count++;
+	}
+	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)
 {
@@ -80,6 +140,8 @@ 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)
+		return perf_event_timer_producer(arg);
 	return 0;
 }

@@ -146,8 +208,7 @@ perf_launch_lcores(struct evt_test *test, struct evt_options *opt,
 		port_idx++;
 	}

-	const uint64_t total_pkts = opt->nb_pkts *
-			evt_nr_active_lcores(opt->plcores);
+	const uint64_t total_pkts = t->outstand_pkts;

 	uint64_t dead_lock_cycles = rte_get_timer_cycles();
 	int64_t dead_lock_remaining  =  total_pkts;
@@ -189,7 +250,9 @@ perf_launch_lcores(struct evt_test *test, struct evt_options *opt,

 			if (remaining <= 0) {
 				t->result = EVT_TEST_SUCCESS;
-				if (opt->prod_type == EVT_PROD_TYPE_SYNT) {
+				if (opt->prod_type == EVT_PROD_TYPE_SYNT ||
+					opt->prod_type ==
+					EVT_PROD_TYPE_EVENT_TIMER_ADPTR) {
 					t->done = true;
 					rte_smp_wmb();
 					break;
@@ -283,6 +346,65 @@ perf_event_rx_adapter_setup(struct evt_options *opt, uint8_t stride,
 	return ret;
 }

+static int
+perf_event_timer_adapter_setup(struct test_perf *t)
+{
+	int i;
+	int ret;
+	struct rte_event_timer_adapter_info adapter_info;
+	struct rte_event_timer_adapter *wl;
+	uint8_t nb_producers = evt_nr_active_lcores(t->opt->plcores);
+	uint8_t flags = RTE_EVENT_TIMER_ADAPTER_F_ADJUST_RES;
+
+	if (nb_producers == 1)
+		flags |= RTE_EVENT_TIMER_ADAPTER_F_SP_PUT;
+
+	for (i = 0; i < t->opt->nb_timer_adptrs; i++) {
+		struct rte_event_timer_adapter_conf config = {
+			.event_dev_id = t->opt->dev_id,
+			.timer_adapter_id = i,
+			.timer_tick_ns = t->opt->bkt_tck_nsec,
+			.max_tmo_ns = t->opt->max_tmo_nsec,
+			.nb_timers = 2 * 1024 * 1024,
+			.flags = flags,
+		};
+
+		wl = rte_event_timer_adapter_create(&config);
+		if (wl == NULL) {
+			evt_err("failed to create event timer ring %d", i);
+			return rte_errno;
+		}
+
+		memset(&adapter_info, 0,
+				sizeof(struct rte_event_timer_adapter_info));
+		rte_event_timer_adapter_get_info(wl, &adapter_info);
+		t->opt->optm_bkt_tck_nsec = adapter_info.min_resolution_ns;
+
+		if (!(adapter_info.caps &
+				RTE_EVENT_TIMER_ADAPTER_CAP_INTERNAL_PORT)) {
+			uint32_t service_id;
+
+			rte_event_timer_adapter_service_id_get(wl,
+					&service_id);
+			ret = evt_service_setup(service_id);
+			if (ret) {
+				evt_err("Failed to setup service core"
+						" for timer adapter\n");
+				return ret;
+			}
+			rte_service_runstate_set(service_id, 1);
+		}
+
+		ret = rte_event_timer_adapter_start(wl);
+		if (ret) {
+			evt_err("failed to Start event timer adapter %d", i);
+			return ret;
+		}
+		t->timer_adptr[i] = wl;
+	}
+	return 0;
+}
+
 int
 perf_event_dev_port_setup(struct evt_test *test, struct evt_options *opt,
 				uint8_t stride, uint8_t nb_queues,
@@ -326,6 +448,18 @@ perf_event_dev_port_setup(struct evt_test *test, struct evt_options *opt,
 		ret = perf_event_rx_adapter_setup(opt, stride, *port_conf);
 		if (ret)
 			return ret;
+	} else if (opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR) {
+		prod = 0;
+		for ( ; port < perf_nb_event_ports(opt); port++) {
+			struct prod_data *p = &t->prod[port];
+			p->queue_id = prod * stride;
+			p->t = t;
+			prod++;
+		}
+
+		ret = perf_event_timer_adapter_setup(t);
+		if (ret)
+			return ret;
 	} else {
 		prod = 0;
 		for ( ; port < perf_nb_event_ports(opt); port++) {
@@ -415,10 +549,13 @@ perf_opt_check(struct evt_options *opt, uint64_t nb_queues)
 	}

 	/* Fixups */
-	if (opt->nb_stages == 1 && opt->fwd_latency) {
+	if ((opt->nb_stages == 1 &&
+			opt->prod_type != EVT_PROD_TYPE_EVENT_TIMER_ADPTR) &&
+			opt->fwd_latency) {
 		evt_info("fwd_latency is valid when nb_stages > 1, disabling");
 		opt->fwd_latency = 0;
 	}
+
 	if (opt->fwd_latency && !opt->q_priority) {
 		evt_info("enabled queue priority for latency measurement");
 		opt->q_priority = 1;
@@ -447,8 +584,13 @@ perf_opt_dump(struct evt_options *opt, uint8_t nb_queues)
 void
 perf_eventdev_destroy(struct evt_test *test, struct evt_options *opt)
 {
-	RTE_SET_USED(test);
+	int i;
+	struct test_perf *t = evt_test_priv(test);

+	if (opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR) {
+		for (i = 0; i < opt->nb_timer_adptrs; i++)
+			rte_event_timer_adapter_stop(t->timer_adptr[i]);
+	}
 	rte_event_dev_stop(opt->dev_id);
 	rte_event_dev_close(opt->dev_id);
 }
@@ -488,7 +630,8 @@ perf_ethdev_setup(struct evt_test *test, struct evt_options *opt)
 		},
 	};

-	if (opt->prod_type == EVT_PROD_TYPE_SYNT)
+	if (opt->prod_type == EVT_PROD_TYPE_SYNT ||
+			opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR)
 		return 0;

 	if (!rte_eth_dev_count()) {
@@ -544,7 +687,8 @@ perf_mempool_setup(struct evt_test *test, struct evt_options *opt)
 {
 	struct test_perf *t = evt_test_priv(test);

-	if (opt->prod_type == EVT_PROD_TYPE_SYNT) {
+	if (opt->prod_type == EVT_PROD_TYPE_SYNT ||
+			opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR) {
 		t->pool = rte_mempool_create(test->name, /* mempool name */
 				opt->pool_sz, /* number of elements*/
 				sizeof(struct perf_elt), /* element size*/
@@ -594,10 +738,18 @@ perf_test_setup(struct evt_test *test, struct evt_options *opt)

 	struct test_perf *t = evt_test_priv(test);

-	t->outstand_pkts = opt->nb_pkts * evt_nr_active_lcores(opt->plcores);
+	if (opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR) {
+		t->outstand_pkts = opt->nb_timers *
+			evt_nr_active_lcores(opt->plcores);
+		t->nb_pkts = opt->nb_timers;
+	} else {
+		t->outstand_pkts = opt->nb_pkts *
+			evt_nr_active_lcores(opt->plcores);
+		t->nb_pkts = opt->nb_pkts;
+	}
+
 	t->nb_workers = evt_nr_active_lcores(opt->wlcores);
 	t->done = false;
-	t->nb_pkts = opt->nb_pkts;
 	t->nb_flows = opt->nb_flows;
 	t->result = EVT_TEST_FAILED;
 	t->opt = opt;
diff --git a/app/test-eventdev/test_perf_common.h b/app/test-eventdev/test_perf_common.h
index 9ad99733b..4e96f229c 100644
--- a/app/test-eventdev/test_perf_common.h
+++ b/app/test-eventdev/test_perf_common.h
@@ -13,6 +13,7 @@
 #include <rte_ethdev.h>
 #include <rte_eventdev.h>
 #include <rte_event_eth_rx_adapter.h>
+#include <rte_event_timer_adapter.h>
 #include <rte_lcore.h>
 #include <rte_malloc.h>
 #include <rte_mempool.h>
@@ -39,6 +40,7 @@ struct prod_data {
 	struct test_perf *t;
 } __rte_cache_aligned;

+
 struct test_perf {
 	/* Don't change the offset of "done". Signal handler use this memory
 	 * to terminate all lcores work.
@@ -54,9 +56,12 @@ struct test_perf {
 	struct worker_data worker[EVT_MAX_PORTS];
 	struct evt_options *opt;
 	uint8_t sched_type_list[EVT_MAX_STAGES] __rte_cache_aligned;
+	struct rte_event_timer_adapter *timer_adptr[
+		RTE_EVENT_TIMER_ADAPTER_NUM_MAX] __rte_cache_aligned;
 } __rte_cache_aligned;

 struct perf_elt {
+	struct rte_event_timer tim;
 	uint64_t timestamp;
 } __rte_cache_aligned;

@@ -68,6 +73,8 @@ struct perf_elt {
 	struct evt_options *opt = t->opt;\
 	const uint8_t dev = w->dev_id;\
 	const uint8_t port = w->port_id;\
+	const uint8_t prod_timer_type = \
+		opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR;\
 	uint8_t *const sched_type_list = &t->sched_type_list[0];\
 	struct rte_mempool *const pool = t->pool;\
 	const uint8_t nb_stages = t->opt->nb_stages;\
diff --git a/app/test-eventdev/test_perf_queue.c b/app/test-eventdev/test_perf_queue.c
index db8f2f3e5..74469a5ee 100644
--- a/app/test-eventdev/test_perf_queue.c
+++ b/app/test-eventdev/test_perf_queue.c
@@ -49,7 +49,7 @@ perf_queue_worker(void *arg, const int enable_fwd_latency)
 			rte_pause();
 			continue;
 		}
-		if (enable_fwd_latency)
+		if (enable_fwd_latency && !prod_timer_type)
 		/* first q in pipeline, mark timestamp to compute fwd latency */
 			mark_fwd_latency(&ev, nb_stages);

@@ -88,7 +88,7 @@ perf_queue_worker_burst(void *arg, const int enable_fwd_latency)
 		}

 		for (i = 0; i < nb_rx; i++) {
-			if (enable_fwd_latency) {
+			if (enable_fwd_latency && !prod_timer_type) {
 				rte_prefetch0(ev[i+1].event_ptr);
 				/* first queue in pipeline.
 				 * mark time stamp to compute fwd latency
@@ -161,7 +161,8 @@ perf_queue_eventdev_setup(struct evt_test *test, struct evt_options *opt)
 	struct rte_event_dev_info dev_info;

 	nb_ports = evt_nr_active_lcores(opt->wlcores);
-	nb_ports += opt->prod_type == EVT_PROD_TYPE_ETH_RX_ADPTR ? 0 :
+	nb_ports += opt->prod_type == EVT_PROD_TYPE_ETH_RX_ADPTR ||
+		 opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR ? 0 :
 		evt_nr_active_lcores(opt->plcores);

 	nb_queues = perf_queue_nb_event_queues(opt);
--
2.16.2

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [dpdk-dev] [PATCH v3 2/4] app/eventdev: add burst mode for event timer adapter
  2018-04-05 11:53 ` [dpdk-dev] [PATCH v3 " Pavan Nikhilesh
@ 2018-04-05 11:53   ` Pavan Nikhilesh
  2018-04-06 11:11     ` Jerin Jacob
  2018-04-05 11:53   ` [dpdk-dev] [PATCH v3 3/4] app/eventdev: add options to configure " Pavan Nikhilesh
                     ` (3 subsequent siblings)
  4 siblings, 1 reply; 36+ messages in thread
From: Pavan Nikhilesh @ 2018-04-05 11:53 UTC (permalink / raw)
  To: jerin.jacob, santosh.shukla, erik.g.carrillo; +Cc: dev, Pavan Nikhilesh

Add burst mode for event timer adapter that can be selected by passing
--prod_type_timerdev_burst.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
---
 app/test-eventdev/evt_options.c      | 13 +++++++
 app/test-eventdev/evt_options.h      |  8 ++++-
 app/test-eventdev/test_perf_common.c | 66 +++++++++++++++++++++++++++++++++++-
 3 files changed, 85 insertions(+), 2 deletions(-)

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 1fb340ac9..2884e0d91 100644
--- a/app/test-eventdev/evt_options.h
+++ b/app/test-eventdev/evt_options.h
@@ -33,6 +33,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 {
@@ -66,6 +67,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;
 };
 
@@ -275,7 +277,11 @@ evt_dump_producer_type(struct evt_options *opt)
 		evt_dump("nb_ethdev", "%d", rte_eth_dev_count());
 		break;
 	case EVT_PROD_TYPE_EVENT_TIMER_ADPTR:
-		snprintf(name, EVT_PROD_MAX_NAME_LEN,
+		if (opt->timdev_use_burst)
+			snprintf(name, EVT_PROD_MAX_NAME_LEN,
+				"Event timer adapter burst mode producer");
+		else
+			snprintf(name, EVT_PROD_MAX_NAME_LEN,
 				"Event timer adapter producer");
 		evt_dump("nb_timer_adapters", "%d", opt->nb_timer_adptrs);
 		evt_dump("max_tmo_nsec", "%"PRIu64"", opt->max_tmo_nsec);
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

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [dpdk-dev] [PATCH v3 3/4] app/eventdev: add options to configure event timer adapter
  2018-04-05 11:53 ` [dpdk-dev] [PATCH v3 " Pavan Nikhilesh
  2018-04-05 11:53   ` [dpdk-dev] [PATCH v3 2/4] app/eventdev: add burst mode for event timer adapter Pavan Nikhilesh
@ 2018-04-05 11:53   ` Pavan Nikhilesh
  2018-04-06 11:15     ` Jerin Jacob
  2018-04-05 11:53   ` [dpdk-dev] [PATCH v3 4/4] doc: update test eventdev documentation Pavan Nikhilesh
                     ` (2 subsequent siblings)
  4 siblings, 1 reply; 36+ messages in thread
From: Pavan Nikhilesh @ 2018-04-05 11:53 UTC (permalink / raw)
  To: jerin.jacob, santosh.shukla, erik.g.carrillo; +Cc: dev, Pavan Nikhilesh

Add options to configure expiry timeout, max number of timers and number
of event timer adapters through command line parameters.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
---
 app/test-eventdev/evt_options.c | 65 +++++++++++++++++++++++++++++++++++++++++
 app/test-eventdev/evt_options.h |  5 ++++
 2 files changed, 70 insertions(+)

diff --git a/app/test-eventdev/evt_options.c b/app/test-eventdev/evt_options.c
index 05d6de88b..a04ffea8f 100644
--- a/app/test-eventdev/evt_options.c
+++ b/app/test-eventdev/evt_options.c
@@ -140,6 +140,56 @@ evt_parse_nb_pkts(struct evt_options *opt, const char *arg)
 	return ret;
 }
 
+static int
+evt_parse_nb_timers(struct evt_options *opt, const char *arg)
+{
+	int ret;
+
+	ret = parser_read_uint64(&(opt->nb_timers), arg);
+
+	return ret;
+}
+
+static int
+evt_parse_bkt_tck_nsec(struct evt_options *opt, const char *arg)
+{
+	int ret;
+
+	ret = parser_read_uint64(&(opt->bkt_tck_nsec), arg);
+
+	return ret;
+}
+
+static int
+evt_parse_max_tmo_nsec(struct evt_options *opt, const char *arg)
+{
+	int ret;
+
+	ret = parser_read_uint64(&(opt->max_tmo_nsec), arg);
+
+	return ret;
+}
+
+static int
+evt_parse_nb_bkt_tcks(struct evt_options *opt, const char *arg)
+{
+	int ret;
+
+	ret = parser_read_uint64(&(opt->nb_bkt_tcks), arg);
+
+	return ret;
+}
+
+static int
+evt_parse_nb_timer_adptrs(struct evt_options *opt, const char *arg)
+{
+	int ret;
+
+	ret = parser_read_uint8(&(opt->nb_timer_adptrs), arg);
+
+	return ret;
+}
+
 static int
 evt_parse_pool_sz(struct evt_options *opt, const char *arg)
 {
@@ -196,6 +246,11 @@ usage(char *program)
 		"\t                     in ns.\n"
 		"\t--prod_type_timerdev_burst : use timer device as producer\n"
 		"\t                             burst mode.\n"
+		"\t--nb_timers        : number of timers to arm.\n"
+		"\t--nb_timer_adptrs  : number of timer adapters to use.\n"
+		"\t--bkt_tck_nsec     : timer bucket tick interval in ns.\n"
+		"\t--max_tmo_nsec     : max timeout interval in ns.\n"
+		"\t--nb_bkt_tcks      : number of bucket ticks for each timer\n"
 		);
 	printf("available tests:\n");
 	evt_test_dump_names();
@@ -259,6 +314,11 @@ static struct option lgopts[] = {
 	{ EVT_PROD_ETHDEV,         0, 0, 0 },
 	{ EVT_PROD_TIMERDEV,       0, 0, 0 },
 	{ EVT_PROD_TIMERDEV_BURST, 0, 0, 0 },
+	{ EVT_NB_TIMERS,           1, 0, 0 },
+	{ EVT_NB_TIMER_ADPTRS,     1, 0, 0 },
+	{ EVT_BKT_TCK_NSEC,        1, 0, 0 },
+	{ EVT_MAX_TMO_NSEC,        1, 0, 0 },
+	{ EVT_NB_BKT_TCKS,         1, 0, 0 },
 	{ EVT_HELP,                0, 0, 0 },
 	{ NULL,                    0, 0, 0 }
 };
@@ -285,6 +345,11 @@ evt_opts_parse_long(int opt_idx, struct evt_options *opt)
 		{ 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},
+		{ EVT_NB_TIMERS, evt_parse_nb_timers},
+		{ EVT_NB_TIMER_ADPTRS, evt_parse_nb_timer_adptrs},
+		{ EVT_BKT_TCK_NSEC, evt_parse_bkt_tck_nsec},
+		{ EVT_MAX_TMO_NSEC, evt_parse_max_tmo_nsec},
+		{ EVT_NB_BKT_TCKS, evt_parse_nb_bkt_tcks},
 	};
 
 	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 2884e0d91..2429b0471 100644
--- a/app/test-eventdev/evt_options.h
+++ b/app/test-eventdev/evt_options.h
@@ -34,6 +34,11 @@
 #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_NB_TIMERS            ("nb_timers")
+#define EVT_NB_TIMER_ADPTRS      ("nb_timer_adptrs")
+#define EVT_BKT_TCK_NSEC         ("bkt_tck_nsec")
+#define EVT_MAX_TMO_NSEC         ("max_tmo_nsec")
+#define EVT_NB_BKT_TCKS          ("nb_bkt_tcks")
 #define EVT_HELP                 ("help")
 
 enum evt_prod_type {
-- 
2.16.2

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [dpdk-dev] [PATCH v3 4/4] doc: update test eventdev documentation
  2018-04-05 11:53 ` [dpdk-dev] [PATCH v3 " Pavan Nikhilesh
  2018-04-05 11:53   ` [dpdk-dev] [PATCH v3 2/4] app/eventdev: add burst mode for event timer adapter Pavan Nikhilesh
  2018-04-05 11:53   ` [dpdk-dev] [PATCH v3 3/4] app/eventdev: add options to configure " Pavan Nikhilesh
@ 2018-04-05 11:53   ` Pavan Nikhilesh
  2018-04-06 11:37     ` Jerin Jacob
  2018-04-06 11:07   ` [dpdk-dev] [PATCH v3 1/4] app/eventdev: add event timer adapter as a producer Jerin Jacob
  2018-04-06 11:18   ` Jerin Jacob
  4 siblings, 1 reply; 36+ messages in thread
From: Pavan Nikhilesh @ 2018-04-05 11:53 UTC (permalink / raw)
  To: jerin.jacob, santosh.shukla, erik.g.carrillo; +Cc: dev, Pavan Nikhilesh

Update documentation to include new options added for using event timer
adapter as a producer.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
---
 doc/guides/tools/testeventdev.rst | 60 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/doc/guides/tools/testeventdev.rst b/doc/guides/tools/testeventdev.rst
index 77480ffe9..eb3bc3ae5 100644
--- a/doc/guides/tools/testeventdev.rst
+++ b/doc/guides/tools/testeventdev.rst
@@ -123,6 +123,36 @@ The following are the application command-line options:
 
         Use ethernet device as producer.
 
+* ``--prod_type_timerdev``
+
+        Use event timer adapter as producer.
+
+ * ``--prod_type_timerdev_burst``
+
+        Use burst mode event timer adapter as producer.
+
+ * ``--bkt_tck_nsec``
+
+        Used to dictate number of nano seconds between bucket traversal of the
+        event timer adapter. Refer `rte_event_timer_adapter_conf`.
+
+ * ``--max_tmo_nsec``
+
+        Used to configure event timer adapter max arm timeout in nano seconds.
+
+ * ``--nb_bkt_tcks``
+
+        Dictate the number of bucket ticks after which the event timer expires.
+
+ * ``--nb_timers``
+
+        Number of event timers each producer core will generate.
+
+ * ``--nb_timer_adptrs``
+
+        Number of event timer adapters to be used. Each adapter is used in
+        round robin manner by the producer cores.
+
 Eventdev Tests
 --------------
 
@@ -347,6 +377,13 @@ Supported application command line options are following::
         --fwd_latency
         --queue_priority
         --prod_type_ethdev
+        --prod_type_timerdev_burst
+        --prod_type_timerdev
+        --bkt_tck_nsec
+        --max_tmo_nsec
+        --nb_bkt_tcks
+        --nb_timers
+        --nb_timer_adptrs
 
 Example
 ^^^^^^^
@@ -365,6 +402,14 @@ Example command to run perf queue test with ethernet ports:
    sudo build/app/dpdk-test-eventdev --vdev=event_sw0 -- \
         --test=perf_queue --plcores=2 --wlcore=3 --stlist=p --prod_type_ethdev
 
+Example command to run perf queue test with event timer adapter:
+
+.. code-block:: console
+
+   sudo  build/app/dpdk-test-eventdev --vdev="event_octeontx" -- \
+                --wlcores 4 --plcores 12 --test perf_queue --stlist=a \
+                --prod_type_timerdev --fwd_latency
+
 PERF_ATQ Test
 ~~~~~~~~~~~~~~~
 
@@ -431,6 +476,13 @@ Supported application command line options are following::
         --worker_deq_depth
         --fwd_latency
         --prod_type_ethdev
+        --prod_type_timerdev_burst
+        --prod_type_timerdev
+        --bkt_tck_nsec
+        --max_tmo_nsec
+        --nb_bkt_tcks
+        --nb_timers
+        --nb_timer_adptrs
 
 Example
 ^^^^^^^
@@ -442,6 +494,14 @@ Example command to run perf ``all types queue`` test:
    sudo build/app/dpdk-test-eventdev --vdev=event_octeontx -- \
                 --test=perf_atq --plcores=2 --wlcore=3 --stlist=p --nb_pkts=0
 
+Example command to run perf ``all types queue`` test with event timer adapter:
+
+.. code-block:: console
+
+   sudo  build/app/dpdk-test-eventdev --vdev="event_octeontx" -- \
+                --wlcores 4 --plcores 12 --test perf_atq --verbose 20 \
+                --stlist=a --prod_type_timerdev --fwd_latency
+
 
 PIPELINE_QUEUE Test
 ~~~~~~~~~~~~~~~~~~~
-- 
2.16.2

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [dpdk-dev] [PATCH v3 1/4] app/eventdev: add event timer adapter as a producer
  2018-04-05 11:53 ` [dpdk-dev] [PATCH v3 " Pavan Nikhilesh
                     ` (2 preceding siblings ...)
  2018-04-05 11:53   ` [dpdk-dev] [PATCH v3 4/4] doc: update test eventdev documentation Pavan Nikhilesh
@ 2018-04-06 11:07   ` Jerin Jacob
  2018-04-06 11:18   ` Jerin Jacob
  4 siblings, 0 replies; 36+ messages in thread
From: Jerin Jacob @ 2018-04-06 11:07 UTC (permalink / raw)
  To: Pavan Nikhilesh; +Cc: santosh.shukla, erik.g.carrillo, dev

-----Original Message-----
> Date: Thu,  5 Apr 2018 17:23:26 +0530
> From: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
> To: jerin.jacob@caviumnetworks.com, santosh.shukla@caviumnetworks.com,
>  erik.g.carrillo@intel.com
> Cc: dev@dpdk.org, Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
> Subject: [dpdk-dev] [PATCH v3 1/4] app/eventdev: add event timer adapter as
>  a producer
> X-Mailer: git-send-email 2.16.3
> 
> Add event timer adapter as producer option that can be selected by
> passing --prod_type_timerdev.
> 
> Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>

Acked-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [dpdk-dev] [PATCH v3 2/4] app/eventdev: add burst mode for event timer adapter
  2018-04-05 11:53   ` [dpdk-dev] [PATCH v3 2/4] app/eventdev: add burst mode for event timer adapter Pavan Nikhilesh
@ 2018-04-06 11:11     ` Jerin Jacob
  0 siblings, 0 replies; 36+ messages in thread
From: Jerin Jacob @ 2018-04-06 11:11 UTC (permalink / raw)
  To: Pavan Nikhilesh; +Cc: santosh.shukla, erik.g.carrillo, dev

-----Original Message-----
> Date: Thu,  5 Apr 2018 17:23:27 +0530
> From: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
> To: jerin.jacob@caviumnetworks.com, santosh.shukla@caviumnetworks.com,
>  erik.g.carrillo@intel.com
> Cc: dev@dpdk.org, Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
> Subject: [dpdk-dev] [PATCH v3 2/4] app/eventdev: add burst mode for event
>  timer adapter
> X-Mailer: git-send-email 2.16.3
> 
> Add burst mode for event timer adapter that can be selected by passing
> --prod_type_timerdev_burst.
> 
> Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>

Acked-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [dpdk-dev] [PATCH v3 3/4] app/eventdev: add options to configure event timer adapter
  2018-04-05 11:53   ` [dpdk-dev] [PATCH v3 3/4] app/eventdev: add options to configure " Pavan Nikhilesh
@ 2018-04-06 11:15     ` Jerin Jacob
  0 siblings, 0 replies; 36+ messages in thread
From: Jerin Jacob @ 2018-04-06 11:15 UTC (permalink / raw)
  To: Pavan Nikhilesh; +Cc: santosh.shukla, erik.g.carrillo, dev

-----Original Message-----
> Date: Thu,  5 Apr 2018 17:23:28 +0530
> From: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
> To: jerin.jacob@caviumnetworks.com, santosh.shukla@caviumnetworks.com,
>  erik.g.carrillo@intel.com
> Cc: dev@dpdk.org, Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
> Subject: [dpdk-dev] [PATCH v3 3/4] app/eventdev: add options to configure
>  event timer adapter
> X-Mailer: git-send-email 2.16.3
> 
> Add options to configure expiry timeout, max number of timers and number
> of event timer adapters through command line parameters.
> 
> Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
Acked-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [dpdk-dev] [PATCH v3 1/4] app/eventdev: add event timer adapter as a producer
  2018-04-05 11:53 ` [dpdk-dev] [PATCH v3 " Pavan Nikhilesh
                     ` (3 preceding siblings ...)
  2018-04-06 11:07   ` [dpdk-dev] [PATCH v3 1/4] app/eventdev: add event timer adapter as a producer Jerin Jacob
@ 2018-04-06 11:18   ` Jerin Jacob
  4 siblings, 0 replies; 36+ messages in thread
From: Jerin Jacob @ 2018-04-06 11:18 UTC (permalink / raw)
  To: Pavan Nikhilesh; +Cc: santosh.shukla, erik.g.carrillo, dev

-----Original Message-----
> Date: Thu,  5 Apr 2018 17:23:26 +0530
> From: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
> To: jerin.jacob@caviumnetworks.com, santosh.shukla@caviumnetworks.com,
>  erik.g.carrillo@intel.com
> Cc: dev@dpdk.org, Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
> Subject: [dpdk-dev] [PATCH v3 1/4] app/eventdev: add event timer adapter as
>  a producer
> X-Mailer: git-send-email 2.16.3
> 
> Add event timer adapter as producer option that can be selected by
> passing --prod_type_timerdev.
> 
> Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
> +static inline int
> +perf_event_timer_producer(void *arg)
> +{
> +	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 = NULL;

NULL assignment is not required.

> +	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;
> +
>  struct perf_elt {
> +	struct rte_event_timer tim;

This will make perf_elf two Cacheline, use union + offset of scheme to
fit timestamp on the first cacheline.

>  	uint64_t timestamp;
>  } __rte_cache_aligned;

With above changes:
Acked-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [dpdk-dev] [PATCH v3 4/4] doc: update test eventdev documentation
  2018-04-05 11:53   ` [dpdk-dev] [PATCH v3 4/4] doc: update test eventdev documentation Pavan Nikhilesh
@ 2018-04-06 11:37     ` Jerin Jacob
  0 siblings, 0 replies; 36+ messages in thread
From: Jerin Jacob @ 2018-04-06 11:37 UTC (permalink / raw)
  To: Pavan Nikhilesh; +Cc: santosh.shukla, erik.g.carrillo, dev

-----Original Message-----
> Date: Thu,  5 Apr 2018 17:23:29 +0530
> From: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
> To: jerin.jacob@caviumnetworks.com, santosh.shukla@caviumnetworks.com,
>  erik.g.carrillo@intel.com
> Cc: dev@dpdk.org, Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
> Subject: [dpdk-dev] [PATCH v3 4/4] doc: update test eventdev documentation
> X-Mailer: git-send-email 2.16.3
> 
> Update documentation to include new options added for using event timer
> adapter as a producer.
> 
> Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
> ---
>  doc/guides/tools/testeventdev.rst | 60 +++++++++++++++++++++++++++++++++++++++
>  1 file changed, 60 insertions(+)
> 
> diff --git a/doc/guides/tools/testeventdev.rst b/doc/guides/tools/testeventdev.rst
> index 77480ffe9..eb3bc3ae5 100644
> --- a/doc/guides/tools/testeventdev.rst
> +++ b/doc/guides/tools/testeventdev.rst
> @@ -123,6 +123,36 @@ The following are the application command-line options:
>  
>          Use ethernet device as producer.
>  
> +* ``--prod_type_timerdev``
> +
> +        Use event timer adapter as producer.
> +
> + * ``--prod_type_timerdev_burst``
> +
> +        Use burst mode event timer adapter as producer.
> +
> + * ``--bkt_tck_nsec``
> +
> +        Used to dictate number of nano seconds between bucket traversal of the
> +        event timer adapter. Refer `rte_event_timer_adapter_conf`.

IMO, instead of "bkt_tck_nsec", it makes sense to call it as
"resolution" or "timer_tick_ns"(it is the term used in
rte_event_timer_adapter_conf spec). If you agree, please change the code and
documentation accordingly.


> +
> + * ``--max_tmo_nsec``
> +
> +        Used to configure event timer adapter max arm timeout in nano seconds.
> +
> + * ``--nb_bkt_tcks``
> +
> +        Dictate the number of bucket ticks after which the event timer expires.

IMO, instead of "nb_bkt_tcks", it makes sense to call it as
"expiry_ns" or something similar. Please express all configuration
option in nano seconds so that user should not know the internals of
implementation.

> +
> + * ``--nb_timers``
> +
> +        Number of event timers each producer core will generate.
> +
> + * ``--nb_timer_adptrs``
> +
> +        Number of event timer adapters to be used. Each adapter is used in
> +        round robin manner by the producer cores.
> +
>  Eventdev Tests
>  --------------
>  
> @@ -347,6 +377,13 @@ Supported application command line options are following::
>          --fwd_latency
>          --queue_priority
>          --prod_type_ethdev
> +        --prod_type_timerdev_burst
> +        --prod_type_timerdev
> +        --bkt_tck_nsec

see above

> +        --max_tmo_nsec
> +        --nb_bkt_tcks

see above

> +        --nb_timers
> +        --nb_timer_adptrs
>  
>  Example
>  ^^^^^^^
> @@ -365,6 +402,14 @@ Example command to run perf queue test with ethernet ports:
>     sudo build/app/dpdk-test-eventdev --vdev=event_sw0 -- \
>          --test=perf_queue --plcores=2 --wlcore=3 --stlist=p --prod_type_ethdev
>  
> +Example command to run perf queue test with event timer adapter:
> +
> +.. code-block:: console
> +
> +   sudo  build/app/dpdk-test-eventdev --vdev="event_octeontx" -- \
> +                --wlcores 4 --plcores 12 --test perf_queue --stlist=a \
> +                --prod_type_timerdev --fwd_latency
> +
>  PERF_ATQ Test
>  ~~~~~~~~~~~~~~~
>  
> @@ -431,6 +476,13 @@ Supported application command line options are following::
>          --worker_deq_depth
>          --fwd_latency
>          --prod_type_ethdev
> +        --prod_type_timerdev_burst
> +        --prod_type_timerdev
> +        --bkt_tck_nsec

see above

> +        --max_tmo_nsec
> +        --nb_bkt_tcks

see above.

> +        --nb_timers
> +        --nb_timer_adptrs

With above name changes in documentation and code:
Acked-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
  

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [dpdk-dev] [PATCH v4 1/4] app/eventdev: add event timer adapter as a producer
  2018-03-18 13:12 [dpdk-dev] [PATCH 1/4] app/eventdev: add event timer adapter as a producer Pavan Nikhilesh
                   ` (5 preceding siblings ...)
  2018-04-05 11:53 ` [dpdk-dev] [PATCH v3 " Pavan Nikhilesh
@ 2018-04-06 14:55 ` Pavan Nikhilesh
  2018-04-06 14:55   ` [dpdk-dev] [PATCH v4 2/4] app/eventdev: add burst mode for event timer adapter Pavan Nikhilesh
                     ` (2 more replies)
  2018-04-06 15:13 ` [dpdk-dev] [PATCH v5 1/4] app/eventdev: add event timer adapter as a producer Pavan Nikhilesh
  7 siblings, 3 replies; 36+ messages in thread
From: Pavan Nikhilesh @ 2018-04-06 14:55 UTC (permalink / raw)
  To: jerin.jacob, santosh.shukla, erik.g.carrillo; +Cc: dev, Pavan Nikhilesh

Add event timer adapter as producer option that can be selected by
passing --prod_type_timerdev.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
---

 v4 Changes:
 - reuse struct rte_event_timer's unused data portion to store timestamp
 instead of spilling timestamp into a new cacheline.
 - change bkt_tck_nsec to timer_tick_nsec
 - change nb_bkt_tcks to expiry_nsec

 v3 Changes:
 - Add detailed options dump.
 - Fix few typos.

 v2 Changes:
 - set timer to NOT_ARMED before trying to arm it.
 - prevent edge cases for timeout_ticks being set to 0.

 app/test-eventdev/evt_options.c      |  54 ++++++---
 app/test-eventdev/evt_options.h      |  24 ++++
 app/test-eventdev/test_perf_atq.c    |  10 +-
 app/test-eventdev/test_perf_common.c | 171 +++++++++++++++++++++++++--
 app/test-eventdev/test_perf_common.h |  14 ++-
 app/test-eventdev/test_perf_queue.c  |   7 +-
 6 files changed, 243 insertions(+), 37 deletions(-)

diff --git a/app/test-eventdev/evt_options.c b/app/test-eventdev/evt_options.c
index 9683b2224..47e37bc9b 100644
--- a/app/test-eventdev/evt_options.c
+++ b/app/test-eventdev/evt_options.c
@@ -27,6 +27,11 @@ evt_options_default(struct evt_options *opt)
 	opt->pool_sz = 16 * 1024;
 	opt->wkr_deq_dep = 16;
 	opt->nb_pkts = (1ULL << 26); /* do ~64M packets */
+	opt->nb_timers = 1E8;
+	opt->nb_timer_adptrs = 1;
+	opt->timer_tick_nsec = 1E3; /* 1000ns ~ 1us */
+	opt->max_tmo_nsec = 1E5;  /* 100000ns ~100us */
+	opt->expiry_nsec = 1E4;   /* 10000ns ~10us */
 	opt->prod_type = EVT_PROD_TYPE_SYNT;
 }

@@ -86,6 +91,13 @@ evt_parse_eth_prod_type(struct evt_options *opt, const char *arg __rte_unused)
 	return 0;
 }

+static int
+evt_parse_timer_prod_type(struct evt_options *opt, const char *arg __rte_unused)
+{
+	opt->prod_type = EVT_PROD_TYPE_EVENT_TIMER_ADPTR;
+	return 0;
+}
+
 static int
 evt_parse_test_name(struct evt_options *opt, const char *arg)
 {
@@ -169,7 +181,10 @@ usage(char *program)
 		"\t--worker_deq_depth : dequeue depth of the worker\n"
 		"\t--fwd_latency      : perform fwd_latency measurement\n"
 		"\t--queue_priority   : enable queue priority\n"
-		"\t--prod_type_ethdev : use ethernet device as producer\n."
+		"\t--prod_type_ethdev : use ethernet device as producer.\n"
+		"\t--prod_type_timerdev : use event timer device as producer.\n"
+		"\t                     expity_nsec would be the timeout\n"
+		"\t                     in ns.\n"
 		);
 	printf("available tests:\n");
 	evt_test_dump_names();
@@ -217,22 +232,23 @@ evt_parse_sched_type_list(struct evt_options *opt, const char *arg)
 }

 static struct option lgopts[] = {
-	{ EVT_NB_FLOWS,         1, 0, 0 },
-	{ EVT_DEVICE,           1, 0, 0 },
-	{ EVT_VERBOSE,          1, 0, 0 },
-	{ EVT_TEST,             1, 0, 0 },
-	{ EVT_PROD_LCORES,      1, 0, 0 },
-	{ EVT_WORK_LCORES,      1, 0, 0 },
-	{ EVT_SOCKET_ID,        1, 0, 0 },
-	{ EVT_POOL_SZ,          1, 0, 0 },
-	{ EVT_NB_PKTS,          1, 0, 0 },
-	{ EVT_WKR_DEQ_DEP,      1, 0, 0 },
-	{ EVT_SCHED_TYPE_LIST,  1, 0, 0 },
-	{ EVT_FWD_LATENCY,      0, 0, 0 },
-	{ EVT_QUEUE_PRIORITY,   0, 0, 0 },
-	{ EVT_PROD_ETHDEV,      0, 0, 0 },
-	{ EVT_HELP,             0, 0, 0 },
-	{ NULL,                 0, 0, 0 }
+	{ EVT_NB_FLOWS,            1, 0, 0 },
+	{ EVT_DEVICE,              1, 0, 0 },
+	{ EVT_VERBOSE,             1, 0, 0 },
+	{ EVT_TEST,                1, 0, 0 },
+	{ EVT_PROD_LCORES,         1, 0, 0 },
+	{ EVT_WORK_LCORES,         1, 0, 0 },
+	{ EVT_SOCKET_ID,           1, 0, 0 },
+	{ EVT_POOL_SZ,             1, 0, 0 },
+	{ EVT_NB_PKTS,             1, 0, 0 },
+	{ EVT_WKR_DEQ_DEP,         1, 0, 0 },
+	{ EVT_SCHED_TYPE_LIST,     1, 0, 0 },
+	{ EVT_FWD_LATENCY,         0, 0, 0 },
+	{ EVT_QUEUE_PRIORITY,      0, 0, 0 },
+	{ EVT_PROD_ETHDEV,         0, 0, 0 },
+	{ EVT_PROD_TIMERDEV,       0, 0, 0 },
+	{ EVT_HELP,                0, 0, 0 },
+	{ NULL,                    0, 0, 0 }
 };

 static int
@@ -255,11 +271,12 @@ evt_opts_parse_long(int opt_idx, struct evt_options *opt)
 		{ EVT_FWD_LATENCY, evt_parse_fwd_latency},
 		{ EVT_QUEUE_PRIORITY, evt_parse_queue_priority},
 		{ EVT_PROD_ETHDEV, evt_parse_eth_prod_type},
+		{ EVT_PROD_TIMERDEV, evt_parse_timer_prod_type},
 	};

 	for (i = 0; i < RTE_DIM(parsermap); i++) {
 		if (strncmp(lgopts[opt_idx].name, parsermap[i].lgopt_name,
-				strlen(parsermap[i].lgopt_name)) == 0)
+				strlen(lgopts[opt_idx].name)) == 0)
 			return parsermap[i].parser_fn(opt, optarg);
 	}

@@ -305,6 +322,7 @@ evt_options_dump(struct evt_options *opt)
 	evt_dump("pool_sz", "%d", opt->pool_sz);
 	evt_dump("master lcore", "%d", rte_get_master_lcore());
 	evt_dump("nb_pkts", "%"PRIu64, opt->nb_pkts);
+	evt_dump("nb_timers", "%"PRIu64, opt->nb_timers);
 	evt_dump_begin("available lcores");
 	RTE_LCORE_FOREACH(lcore_id)
 		printf("%d ", lcore_id);
diff --git a/app/test-eventdev/evt_options.h b/app/test-eventdev/evt_options.h
index 46d122229..b51d8d5b3 100644
--- a/app/test-eventdev/evt_options.h
+++ b/app/test-eventdev/evt_options.h
@@ -9,6 +9,7 @@
 #include <stdbool.h>

 #include <rte_common.h>
+#include <rte_ethdev.h>
 #include <rte_eventdev.h>
 #include <rte_lcore.h>

@@ -31,12 +32,14 @@
 #define EVT_FWD_LATENCY          ("fwd_latency")
 #define EVT_QUEUE_PRIORITY       ("queue_priority")
 #define EVT_PROD_ETHDEV          ("prod_type_ethdev")
+#define EVT_PROD_TIMERDEV        ("prod_type_timerdev")
 #define EVT_HELP                 ("help")

 enum evt_prod_type {
 	EVT_PROD_TYPE_NONE,
 	EVT_PROD_TYPE_SYNT,          /* Producer type Synthetic i.e. CPU. */
 	EVT_PROD_TYPE_ETH_RX_ADPTR,  /* Producer type Eth Rx Adapter. */
+	EVT_PROD_TYPE_EVENT_TIMER_ADPTR,  /* Producer type Timer Adapter. */
 	EVT_PROD_TYPE_MAX,
 };

@@ -52,11 +55,18 @@ struct evt_options {
 	int nb_stages;
 	int verbose_level;
 	uint64_t nb_pkts;
+	uint8_t nb_timer_adptrs;
+	uint64_t nb_timers;
+	uint64_t timer_tick_nsec;
+	uint64_t optm_timer_tick_nsec;
+	uint64_t max_tmo_nsec;
+	uint64_t expiry_nsec;
 	uint16_t wkr_deq_dep;
 	uint8_t dev_id;
 	uint32_t fwd_latency:1;
 	uint32_t q_priority:1;
 	enum evt_prod_type prod_type;
+	uint8_t timdev_cnt;
 };

 void evt_options_default(struct evt_options *opt);
@@ -262,6 +272,20 @@ evt_dump_producer_type(struct evt_options *opt)
 	case EVT_PROD_TYPE_ETH_RX_ADPTR:
 		snprintf(name, EVT_PROD_MAX_NAME_LEN,
 				"Ethdev Rx Adapter producers");
+		evt_dump("nb_ethdev", "%d", rte_eth_dev_count());
+		break;
+	case EVT_PROD_TYPE_EVENT_TIMER_ADPTR:
+		snprintf(name, EVT_PROD_MAX_NAME_LEN,
+				"Event timer adapter producer");
+		evt_dump("nb_timer_adapters", "%d", opt->nb_timer_adptrs);
+		evt_dump("max_tmo_nsec", "%"PRIu64"", opt->max_tmo_nsec);
+		evt_dump("expiry_nsec", "%"PRIu64"", opt->expiry_nsec);
+		if (opt->optm_timer_tick_nsec)
+			evt_dump("optm_timer_tick_ns", "%"PRIu64"",
+					opt->optm_timer_tick_nsec);
+		else
+			evt_dump("timer_tick_ns", "%"PRIu64"",
+					opt->timer_tick_nsec);
 		break;
 	}
 	evt_dump("prod_type", "%s", name);
diff --git a/app/test-eventdev/test_perf_atq.c b/app/test-eventdev/test_perf_atq.c
index b36b22a77..b3a312722 100644
--- a/app/test-eventdev/test_perf_atq.c
+++ b/app/test-eventdev/test_perf_atq.c
@@ -43,15 +43,12 @@ perf_atq_worker(void *arg, const int enable_fwd_latency)
 	while (t->done == false) {
 		uint16_t event = rte_event_dequeue_burst(dev, port, &ev, 1, 0);

-		if (enable_fwd_latency)
-			rte_prefetch0(ev.event_ptr);
-
 		if (!event) {
 			rte_pause();
 			continue;
 		}

-		if (enable_fwd_latency)
+		if (enable_fwd_latency && !prod_timer_type)
 		/* first stage in pipeline, mark ts to compute fwd latency */
 			atq_mark_fwd_latency(&ev);

@@ -90,7 +87,7 @@ perf_atq_worker_burst(void *arg, const int enable_fwd_latency)
 		}

 		for (i = 0; i < nb_rx; i++) {
-			if (enable_fwd_latency) {
+			if (enable_fwd_latency && !prod_timer_type) {
 				rte_prefetch0(ev[i+1].event_ptr);
 				/* first stage in pipeline.
 				 * mark time stamp to compute fwd latency
@@ -163,7 +160,8 @@ perf_atq_eventdev_setup(struct evt_test *test, struct evt_options *opt)
 	struct rte_event_dev_info dev_info;

 	nb_ports = evt_nr_active_lcores(opt->wlcores);
-	nb_ports += opt->prod_type == EVT_PROD_TYPE_ETH_RX_ADPTR ? 0 :
+	nb_ports += (opt->prod_type == EVT_PROD_TYPE_ETH_RX_ADPTR ||
+			opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR) ? 0 :
 		evt_nr_active_lcores(opt->plcores);

 	nb_queues = atq_nb_event_queues(opt);
diff --git a/app/test-eventdev/test_perf_common.c b/app/test-eventdev/test_perf_common.c
index 59fa0a49e..b6cc00e60 100644
--- a/app/test-eventdev/test_perf_common.c
+++ b/app/test-eventdev/test_perf_common.c
@@ -72,6 +72,67 @@ perf_producer(void *arg)
 	return 0;
 }

+static inline int
+perf_event_timer_producer(void *arg)
+{
+	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;
+	struct rte_event_timer_adapter **adptr = t->timer_adptr;
+	uint64_t timeout_ticks = opt->expiry_nsec / opt->timer_tick_nsec;
+
+	timeout_ticks = opt->optm_timer_tick_nsec ?
+			(timeout_ticks * opt->timer_tick_nsec)
+			/ opt->optm_timer_tick_nsec : timeout_ticks;
+	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(pool, (void **)&m) < 0)
+			continue;
+
+		m->tim = tim;
+		m->tim.ev.flow_id = flow_counter++ % nb_flows;
+		m->tim.ev.event_ptr = m;
+		m->timestamp = rte_get_timer_cycles();
+		while (rte_event_timer_arm_burst(
+				adptr[flow_counter % nb_timer_adptrs],
+				(struct rte_event_timer **)&m, 1) != 1) {
+			if (t->done)
+				break;
+			rte_pause();
+			m->timestamp = rte_get_timer_cycles();
+		}
+		arm_latency += rte_get_timer_cycles() - m->timestamp;
+		count++;
+	}
+	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)
 {
@@ -80,6 +141,8 @@ 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)
+		return perf_event_timer_producer(arg);
 	return 0;
 }

@@ -146,8 +209,7 @@ perf_launch_lcores(struct evt_test *test, struct evt_options *opt,
 		port_idx++;
 	}

-	const uint64_t total_pkts = opt->nb_pkts *
-			evt_nr_active_lcores(opt->plcores);
+	const uint64_t total_pkts = t->outstand_pkts;

 	uint64_t dead_lock_cycles = rte_get_timer_cycles();
 	int64_t dead_lock_remaining  =  total_pkts;
@@ -189,7 +251,9 @@ perf_launch_lcores(struct evt_test *test, struct evt_options *opt,

 			if (remaining <= 0) {
 				t->result = EVT_TEST_SUCCESS;
-				if (opt->prod_type == EVT_PROD_TYPE_SYNT) {
+				if (opt->prod_type == EVT_PROD_TYPE_SYNT ||
+					opt->prod_type ==
+					EVT_PROD_TYPE_EVENT_TIMER_ADPTR) {
 					t->done = true;
 					rte_smp_wmb();
 					break;
@@ -283,6 +347,65 @@ perf_event_rx_adapter_setup(struct evt_options *opt, uint8_t stride,
 	return ret;
 }

+static int
+perf_event_timer_adapter_setup(struct test_perf *t)
+{
+	int i;
+	int ret;
+	struct rte_event_timer_adapter_info adapter_info;
+	struct rte_event_timer_adapter *wl;
+	uint8_t nb_producers = evt_nr_active_lcores(t->opt->plcores);
+	uint8_t flags = RTE_EVENT_TIMER_ADAPTER_F_ADJUST_RES;
+
+	if (nb_producers == 1)
+		flags |= RTE_EVENT_TIMER_ADAPTER_F_SP_PUT;
+
+	for (i = 0; i < t->opt->nb_timer_adptrs; i++) {
+		struct rte_event_timer_adapter_conf config = {
+			.event_dev_id = t->opt->dev_id,
+			.timer_adapter_id = i,
+			.timer_tick_ns = t->opt->timer_tick_nsec,
+			.max_tmo_ns = t->opt->max_tmo_nsec,
+			.nb_timers = 2 * 1024 * 1024,
+			.flags = flags,
+		};
+
+		wl = rte_event_timer_adapter_create(&config);
+		if (wl == NULL) {
+			evt_err("failed to create event timer ring %d", i);
+			return rte_errno;
+		}
+
+		memset(&adapter_info, 0,
+				sizeof(struct rte_event_timer_adapter_info));
+		rte_event_timer_adapter_get_info(wl, &adapter_info);
+		t->opt->optm_timer_tick_nsec = adapter_info.min_resolution_ns;
+
+		if (!(adapter_info.caps &
+				RTE_EVENT_TIMER_ADAPTER_CAP_INTERNAL_PORT)) {
+			uint32_t service_id;
+
+			rte_event_timer_adapter_service_id_get(wl,
+					&service_id);
+			ret = evt_service_setup(service_id);
+			if (ret) {
+				evt_err("Failed to setup service core"
+						" for timer adapter\n");
+				return ret;
+			}
+			rte_service_runstate_set(service_id, 1);
+		}
+
+		ret = rte_event_timer_adapter_start(wl);
+		if (ret) {
+			evt_err("failed to Start event timer adapter %d", i);
+			return ret;
+		}
+		t->timer_adptr[i] = wl;
+	}
+	return 0;
+}
+
 int
 perf_event_dev_port_setup(struct evt_test *test, struct evt_options *opt,
 				uint8_t stride, uint8_t nb_queues,
@@ -326,6 +449,18 @@ perf_event_dev_port_setup(struct evt_test *test, struct evt_options *opt,
 		ret = perf_event_rx_adapter_setup(opt, stride, *port_conf);
 		if (ret)
 			return ret;
+	} else if (opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR) {
+		prod = 0;
+		for ( ; port < perf_nb_event_ports(opt); port++) {
+			struct prod_data *p = &t->prod[port];
+			p->queue_id = prod * stride;
+			p->t = t;
+			prod++;
+		}
+
+		ret = perf_event_timer_adapter_setup(t);
+		if (ret)
+			return ret;
 	} else {
 		prod = 0;
 		for ( ; port < perf_nb_event_ports(opt); port++) {
@@ -415,10 +550,13 @@ perf_opt_check(struct evt_options *opt, uint64_t nb_queues)
 	}

 	/* Fixups */
-	if (opt->nb_stages == 1 && opt->fwd_latency) {
+	if ((opt->nb_stages == 1 &&
+			opt->prod_type != EVT_PROD_TYPE_EVENT_TIMER_ADPTR) &&
+			opt->fwd_latency) {
 		evt_info("fwd_latency is valid when nb_stages > 1, disabling");
 		opt->fwd_latency = 0;
 	}
+
 	if (opt->fwd_latency && !opt->q_priority) {
 		evt_info("enabled queue priority for latency measurement");
 		opt->q_priority = 1;
@@ -447,8 +585,13 @@ perf_opt_dump(struct evt_options *opt, uint8_t nb_queues)
 void
 perf_eventdev_destroy(struct evt_test *test, struct evt_options *opt)
 {
-	RTE_SET_USED(test);
+	int i;
+	struct test_perf *t = evt_test_priv(test);

+	if (opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR) {
+		for (i = 0; i < opt->nb_timer_adptrs; i++)
+			rte_event_timer_adapter_stop(t->timer_adptr[i]);
+	}
 	rte_event_dev_stop(opt->dev_id);
 	rte_event_dev_close(opt->dev_id);
 }
@@ -488,7 +631,8 @@ perf_ethdev_setup(struct evt_test *test, struct evt_options *opt)
 		},
 	};

-	if (opt->prod_type == EVT_PROD_TYPE_SYNT)
+	if (opt->prod_type == EVT_PROD_TYPE_SYNT ||
+			opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR)
 		return 0;

 	if (!rte_eth_dev_count()) {
@@ -544,7 +688,8 @@ perf_mempool_setup(struct evt_test *test, struct evt_options *opt)
 {
 	struct test_perf *t = evt_test_priv(test);

-	if (opt->prod_type == EVT_PROD_TYPE_SYNT) {
+	if (opt->prod_type == EVT_PROD_TYPE_SYNT ||
+			opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR) {
 		t->pool = rte_mempool_create(test->name, /* mempool name */
 				opt->pool_sz, /* number of elements*/
 				sizeof(struct perf_elt), /* element size*/
@@ -594,10 +739,18 @@ perf_test_setup(struct evt_test *test, struct evt_options *opt)

 	struct test_perf *t = evt_test_priv(test);

-	t->outstand_pkts = opt->nb_pkts * evt_nr_active_lcores(opt->plcores);
+	if (opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR) {
+		t->outstand_pkts = opt->nb_timers *
+			evt_nr_active_lcores(opt->plcores);
+		t->nb_pkts = opt->nb_timers;
+	} else {
+		t->outstand_pkts = opt->nb_pkts *
+			evt_nr_active_lcores(opt->plcores);
+		t->nb_pkts = opt->nb_pkts;
+	}
+
 	t->nb_workers = evt_nr_active_lcores(opt->wlcores);
 	t->done = false;
-	t->nb_pkts = opt->nb_pkts;
 	t->nb_flows = opt->nb_flows;
 	t->result = EVT_TEST_FAILED;
 	t->opt = opt;
diff --git a/app/test-eventdev/test_perf_common.h b/app/test-eventdev/test_perf_common.h
index 9ad99733b..d8fbee6d8 100644
--- a/app/test-eventdev/test_perf_common.h
+++ b/app/test-eventdev/test_perf_common.h
@@ -13,6 +13,7 @@
 #include <rte_ethdev.h>
 #include <rte_eventdev.h>
 #include <rte_event_eth_rx_adapter.h>
+#include <rte_event_timer_adapter.h>
 #include <rte_lcore.h>
 #include <rte_malloc.h>
 #include <rte_mempool.h>
@@ -39,6 +40,7 @@ struct prod_data {
 	struct test_perf *t;
 } __rte_cache_aligned;

+
 struct test_perf {
 	/* Don't change the offset of "done". Signal handler use this memory
 	 * to terminate all lcores work.
@@ -54,10 +56,18 @@ struct test_perf {
 	struct worker_data worker[EVT_MAX_PORTS];
 	struct evt_options *opt;
 	uint8_t sched_type_list[EVT_MAX_STAGES] __rte_cache_aligned;
+	struct rte_event_timer_adapter *timer_adptr[
+		RTE_EVENT_TIMER_ADAPTER_NUM_MAX] __rte_cache_aligned;
 } __rte_cache_aligned;

 struct perf_elt {
-	uint64_t timestamp;
+	union {
+		struct rte_event_timer tim;
+		struct {
+			char pad[offsetof(struct rte_event_timer, user_meta)];
+			uint64_t timestamp;
+		};
+	};
 } __rte_cache_aligned;

 #define BURST_SIZE 16
@@ -68,6 +78,8 @@ struct perf_elt {
 	struct evt_options *opt = t->opt;\
 	const uint8_t dev = w->dev_id;\
 	const uint8_t port = w->port_id;\
+	const uint8_t prod_timer_type = \
+		opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR;\
 	uint8_t *const sched_type_list = &t->sched_type_list[0];\
 	struct rte_mempool *const pool = t->pool;\
 	const uint8_t nb_stages = t->opt->nb_stages;\
diff --git a/app/test-eventdev/test_perf_queue.c b/app/test-eventdev/test_perf_queue.c
index db8f2f3e5..74469a5ee 100644
--- a/app/test-eventdev/test_perf_queue.c
+++ b/app/test-eventdev/test_perf_queue.c
@@ -49,7 +49,7 @@ perf_queue_worker(void *arg, const int enable_fwd_latency)
 			rte_pause();
 			continue;
 		}
-		if (enable_fwd_latency)
+		if (enable_fwd_latency && !prod_timer_type)
 		/* first q in pipeline, mark timestamp to compute fwd latency */
 			mark_fwd_latency(&ev, nb_stages);

@@ -88,7 +88,7 @@ perf_queue_worker_burst(void *arg, const int enable_fwd_latency)
 		}

 		for (i = 0; i < nb_rx; i++) {
-			if (enable_fwd_latency) {
+			if (enable_fwd_latency && !prod_timer_type) {
 				rte_prefetch0(ev[i+1].event_ptr);
 				/* first queue in pipeline.
 				 * mark time stamp to compute fwd latency
@@ -161,7 +161,8 @@ perf_queue_eventdev_setup(struct evt_test *test, struct evt_options *opt)
 	struct rte_event_dev_info dev_info;

 	nb_ports = evt_nr_active_lcores(opt->wlcores);
-	nb_ports += opt->prod_type == EVT_PROD_TYPE_ETH_RX_ADPTR ? 0 :
+	nb_ports += opt->prod_type == EVT_PROD_TYPE_ETH_RX_ADPTR ||
+		 opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR ? 0 :
 		evt_nr_active_lcores(opt->plcores);

 	nb_queues = perf_queue_nb_event_queues(opt);
--
2.17.0

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [dpdk-dev] [PATCH v4 2/4] app/eventdev: add burst mode for event timer adapter
  2018-04-06 14:55 ` [dpdk-dev] [PATCH v4 " Pavan Nikhilesh
@ 2018-04-06 14:55   ` Pavan Nikhilesh
  2018-04-06 14:55   ` [dpdk-dev] [PATCH v4 3/4] app/eventdev: add options to configure " Pavan Nikhilesh
  2018-04-06 14:55   ` [dpdk-dev] [PATCH v4 4/4] doc: update test eventdev documentation Pavan Nikhilesh
  2 siblings, 0 replies; 36+ messages in thread
From: Pavan Nikhilesh @ 2018-04-06 14:55 UTC (permalink / raw)
  To: jerin.jacob, santosh.shukla, erik.g.carrillo; +Cc: dev, Pavan Nikhilesh

Add burst mode for event timer adapter that can be selected by passing
--prod_type_timerdev_burst.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
---
 app/test-eventdev/evt_options.c      | 13 ++++++
 app/test-eventdev/evt_options.h      |  8 +++-
 app/test-eventdev/test_perf_common.c | 67 +++++++++++++++++++++++++++-
 3 files changed, 86 insertions(+), 2 deletions(-)

diff --git a/app/test-eventdev/evt_options.c b/app/test-eventdev/evt_options.c
index 47e37bc9b..1b60eb2ef 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                     expity_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 b51d8d5b3..e5e632783 100644
--- a/app/test-eventdev/evt_options.h
+++ b/app/test-eventdev/evt_options.h
@@ -33,6 +33,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 {
@@ -66,6 +67,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;
 };
 
@@ -275,7 +277,11 @@ evt_dump_producer_type(struct evt_options *opt)
 		evt_dump("nb_ethdev", "%d", rte_eth_dev_count());
 		break;
 	case EVT_PROD_TYPE_EVENT_TIMER_ADPTR:
-		snprintf(name, EVT_PROD_MAX_NAME_LEN,
+		if (opt->timdev_use_burst)
+			snprintf(name, EVT_PROD_MAX_NAME_LEN,
+				"Event timer adapter burst mode producer");
+		else
+			snprintf(name, EVT_PROD_MAX_NAME_LEN,
 				"Event timer adapter producer");
 		evt_dump("nb_timer_adapters", "%d", opt->nb_timer_adptrs);
 		evt_dump("max_tmo_nsec", "%"PRIu64"", opt->max_tmo_nsec);
diff --git a/app/test-eventdev/test_perf_common.c b/app/test-eventdev/test_perf_common.c
index b6cc00e60..a74ab9a9e 100644
--- a/app/test-eventdev/test_perf_common.c
+++ b/app/test-eventdev/test_perf_common.c
@@ -133,6 +133,67 @@ 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->expiry_nsec / opt->timer_tick_nsec;
+
+	timeout_ticks = opt->optm_timer_tick_nsec ?
+			(timeout_ticks * opt->timer_tick_nsec)
+			/ opt->optm_timer_tick_nsec : timeout_ticks;
+	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)
 {
@@ -141,8 +202,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.17.0

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [dpdk-dev] [PATCH v4 3/4] app/eventdev: add options to configure event timer adapter
  2018-04-06 14:55 ` [dpdk-dev] [PATCH v4 " Pavan Nikhilesh
  2018-04-06 14:55   ` [dpdk-dev] [PATCH v4 2/4] app/eventdev: add burst mode for event timer adapter Pavan Nikhilesh
@ 2018-04-06 14:55   ` Pavan Nikhilesh
  2018-04-06 14:55   ` [dpdk-dev] [PATCH v4 4/4] doc: update test eventdev documentation Pavan Nikhilesh
  2 siblings, 0 replies; 36+ messages in thread
From: Pavan Nikhilesh @ 2018-04-06 14:55 UTC (permalink / raw)
  To: jerin.jacob, santosh.shukla, erik.g.carrillo; +Cc: dev, Pavan Nikhilesh

Add options to configure expiry timeout, max number of timers and number
of event timer adapters through command line parameters.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
---
 app/test-eventdev/evt_options.c | 65 +++++++++++++++++++++++++++++++++
 app/test-eventdev/evt_options.h |  5 +++
 2 files changed, 70 insertions(+)

diff --git a/app/test-eventdev/evt_options.c b/app/test-eventdev/evt_options.c
index 1b60eb2ef..5f311a570 100644
--- a/app/test-eventdev/evt_options.c
+++ b/app/test-eventdev/evt_options.c
@@ -140,6 +140,56 @@ evt_parse_nb_pkts(struct evt_options *opt, const char *arg)
 	return ret;
 }
 
+static int
+evt_parse_nb_timers(struct evt_options *opt, const char *arg)
+{
+	int ret;
+
+	ret = parser_read_uint64(&(opt->nb_timers), arg);
+
+	return ret;
+}
+
+static int
+evt_parse_timer_tick_nsec(struct evt_options *opt, const char *arg)
+{
+	int ret;
+
+	ret = parser_read_uint64(&(opt->timer_tick_nsec), arg);
+
+	return ret;
+}
+
+static int
+evt_parse_max_tmo_nsec(struct evt_options *opt, const char *arg)
+{
+	int ret;
+
+	ret = parser_read_uint64(&(opt->max_tmo_nsec), arg);
+
+	return ret;
+}
+
+static int
+evt_parse_expiry_nsec(struct evt_options *opt, const char *arg)
+{
+	int ret;
+
+	ret = parser_read_uint64(&(opt->expiry_nsec), arg);
+
+	return ret;
+}
+
+static int
+evt_parse_nb_timer_adptrs(struct evt_options *opt, const char *arg)
+{
+	int ret;
+
+	ret = parser_read_uint8(&(opt->nb_timer_adptrs), arg);
+
+	return ret;
+}
+
 static int
 evt_parse_pool_sz(struct evt_options *opt, const char *arg)
 {
@@ -196,6 +246,11 @@ usage(char *program)
 		"\t                     in ns.\n"
 		"\t--prod_type_timerdev_burst : use timer device as producer\n"
 		"\t                             burst mode.\n"
+		"\t--nb_timers        : number of timers to arm.\n"
+		"\t--nb_timer_adptrs  : number of timer adapters to use.\n"
+		"\t--timer_tick_nsec  : timer tick interval in ns.\n"
+		"\t--max_tmo_nsec     : max timeout interval in ns.\n"
+		"\t--expiry_ns        : event timer expiry ns.\n"
 		);
 	printf("available tests:\n");
 	evt_test_dump_names();
@@ -259,6 +314,11 @@ static struct option lgopts[] = {
 	{ EVT_PROD_ETHDEV,         0, 0, 0 },
 	{ EVT_PROD_TIMERDEV,       0, 0, 0 },
 	{ EVT_PROD_TIMERDEV_BURST, 0, 0, 0 },
+	{ EVT_NB_TIMERS,           1, 0, 0 },
+	{ EVT_NB_TIMER_ADPTRS,     1, 0, 0 },
+	{ EVT_TIMER_TICK_NSEC,     1, 0, 0 },
+	{ EVT_MAX_TMO_NSEC,        1, 0, 0 },
+	{ EVT_EXPIRY_NSEC,         1, 0, 0 },
 	{ EVT_HELP,                0, 0, 0 },
 	{ NULL,                    0, 0, 0 }
 };
@@ -285,6 +345,11 @@ evt_opts_parse_long(int opt_idx, struct evt_options *opt)
 		{ 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},
+		{ EVT_NB_TIMERS, evt_parse_nb_timers},
+		{ EVT_NB_TIMER_ADPTRS, evt_parse_nb_timer_adptrs},
+		{ EVT_TIMER_TICK_NSEC, evt_parse_timer_tick_nsec},
+		{ EVT_MAX_TMO_NSEC, evt_parse_max_tmo_nsec},
+		{ EVT_EXPIRY_NSEC, evt_parse_expiry_nsec},
 	};
 
 	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 e5e632783..c059f7084 100644
--- a/app/test-eventdev/evt_options.h
+++ b/app/test-eventdev/evt_options.h
@@ -34,6 +34,11 @@
 #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_NB_TIMERS            ("nb_timers")
+#define EVT_NB_TIMER_ADPTRS      ("nb_timer_adptrs")
+#define EVT_TIMER_TICK_NSEC      ("timer_tick_ns")
+#define EVT_MAX_TMO_NSEC         ("max_tmo_nsec")
+#define EVT_EXPIRY_NSEC          ("expiry_ns")
 #define EVT_HELP                 ("help")
 
 enum evt_prod_type {
-- 
2.17.0

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [dpdk-dev] [PATCH v4 4/4] doc: update test eventdev documentation
  2018-04-06 14:55 ` [dpdk-dev] [PATCH v4 " Pavan Nikhilesh
  2018-04-06 14:55   ` [dpdk-dev] [PATCH v4 2/4] app/eventdev: add burst mode for event timer adapter Pavan Nikhilesh
  2018-04-06 14:55   ` [dpdk-dev] [PATCH v4 3/4] app/eventdev: add options to configure " Pavan Nikhilesh
@ 2018-04-06 14:55   ` Pavan Nikhilesh
  2 siblings, 0 replies; 36+ messages in thread
From: Pavan Nikhilesh @ 2018-04-06 14:55 UTC (permalink / raw)
  To: jerin.jacob, santosh.shukla, erik.g.carrillo; +Cc: dev, Pavan Nikhilesh

Update documentation to include new options added for using event timer
adapter as a producer.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
---
 doc/guides/tools/testeventdev.rst | 60 +++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/doc/guides/tools/testeventdev.rst b/doc/guides/tools/testeventdev.rst
index 77480ffe9..46effd871 100644
--- a/doc/guides/tools/testeventdev.rst
+++ b/doc/guides/tools/testeventdev.rst
@@ -123,6 +123,36 @@ The following are the application command-line options:
 
         Use ethernet device as producer.
 
+* ``--prod_type_timerdev``
+
+        Use event timer adapter as producer.
+
+ * ``--prod_type_timerdev_burst``
+
+        Use burst mode event timer adapter as producer.
+
+ * ``--timer_tick_nsec``
+
+        Used to dictate number of nano seconds between bucket traversal of the
+        event timer adapter. Refer `rte_event_timer_adapter_conf`.
+
+ * ``--max_tmo_nsec``
+
+        Used to configure event timer adapter max arm timeout in nano seconds.
+
+ * ``--expiry_nsec``
+
+        Dictate the number of nano seconds after which the event timer expires.
+
+ * ``--nb_timers``
+
+        Number of event timers each producer core will generate.
+
+ * ``--nb_timer_adptrs``
+
+        Number of event timer adapters to be used. Each adapter is used in
+        round robin manner by the producer cores.
+
 Eventdev Tests
 --------------
 
@@ -347,6 +377,13 @@ Supported application command line options are following::
         --fwd_latency
         --queue_priority
         --prod_type_ethdev
+        --prod_type_timerdev_burst
+        --prod_type_timerdev
+        --timer_tick_nsec
+        --max_tmo_nsec
+        --expiry_nsec
+        --nb_timers
+        --nb_timer_adptrs
 
 Example
 ^^^^^^^
@@ -365,6 +402,14 @@ Example command to run perf queue test with ethernet ports:
    sudo build/app/dpdk-test-eventdev --vdev=event_sw0 -- \
         --test=perf_queue --plcores=2 --wlcore=3 --stlist=p --prod_type_ethdev
 
+Example command to run perf queue test with event timer adapter:
+
+.. code-block:: console
+
+   sudo  build/app/dpdk-test-eventdev --vdev="event_octeontx" -- \
+                --wlcores 4 --plcores 12 --test perf_queue --stlist=a \
+                --prod_type_timerdev --fwd_latency
+
 PERF_ATQ Test
 ~~~~~~~~~~~~~~~
 
@@ -431,6 +476,13 @@ Supported application command line options are following::
         --worker_deq_depth
         --fwd_latency
         --prod_type_ethdev
+        --prod_type_timerdev_burst
+        --prod_type_timerdev
+        --timer_tick_nsec
+        --max_tmo_nsec
+        --expiry_nsec
+        --nb_timers
+        --nb_timer_adptrs
 
 Example
 ^^^^^^^
@@ -442,6 +494,14 @@ Example command to run perf ``all types queue`` test:
    sudo build/app/dpdk-test-eventdev --vdev=event_octeontx -- \
                 --test=perf_atq --plcores=2 --wlcore=3 --stlist=p --nb_pkts=0
 
+Example command to run perf ``all types queue`` test with event timer adapter:
+
+.. code-block:: console
+
+   sudo  build/app/dpdk-test-eventdev --vdev="event_octeontx" -- \
+                --wlcores 4 --plcores 12 --test perf_atq --verbose 20 \
+                --stlist=a --prod_type_timerdev --fwd_latency
+
 
 PIPELINE_QUEUE Test
 ~~~~~~~~~~~~~~~~~~~
-- 
2.17.0

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [dpdk-dev] [PATCH v5 1/4] app/eventdev: add event timer adapter as a producer
  2018-03-18 13:12 [dpdk-dev] [PATCH 1/4] app/eventdev: add event timer adapter as a producer Pavan Nikhilesh
                   ` (6 preceding siblings ...)
  2018-04-06 14:55 ` [dpdk-dev] [PATCH v4 " Pavan Nikhilesh
@ 2018-04-06 15:13 ` Pavan Nikhilesh
  2018-04-06 15:13   ` [dpdk-dev] [PATCH v5 2/4] app/eventdev: add burst mode for event timer adapter Pavan Nikhilesh
                     ` (4 more replies)
  7 siblings, 5 replies; 36+ messages in thread
From: Pavan Nikhilesh @ 2018-04-06 15:13 UTC (permalink / raw)
  To: jerin.jacob, santosh.shukla, erik.g.carrillo; +Cc: dev, Pavan Nikhilesh

Add event timer adapter as producer option that can be selected by
passing --prod_type_timerdev.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
Acked-by: Erik Gabriel Carrillo <erik.g.carrillo@intel.com>
Acked-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
---

 v5 Changes:
 - Resending cause missing Acked-by.

 v4 Changes:
 - reuse struct rte_event_timer's unused data portion to store timestamp
 instead of spilling timestamp into a new cacheline.
 - change bkt_tck_nsec to timer_tick_nsec
 - change nb_bkt_tcks to expiry_nsec

 v3 Changes:
 - Add detailed options dump.
 - Fix few typos.

 v2 Changes:
 - set timer to NOT_ARMED before trying to arm it.
 - prevent edge cases for timeout_ticks being set to 0.

 app/test-eventdev/evt_options.c      |  54 ++++++---
 app/test-eventdev/evt_options.h      |  24 ++++
 app/test-eventdev/test_perf_atq.c    |  10 +-
 app/test-eventdev/test_perf_common.c | 171 +++++++++++++++++++++++++--
 app/test-eventdev/test_perf_common.h |  14 ++-
 app/test-eventdev/test_perf_queue.c  |   7 +-
 6 files changed, 243 insertions(+), 37 deletions(-)

diff --git a/app/test-eventdev/evt_options.c b/app/test-eventdev/evt_options.c
index 9683b2224..47e37bc9b 100644
--- a/app/test-eventdev/evt_options.c
+++ b/app/test-eventdev/evt_options.c
@@ -27,6 +27,11 @@ evt_options_default(struct evt_options *opt)
 	opt->pool_sz = 16 * 1024;
 	opt->wkr_deq_dep = 16;
 	opt->nb_pkts = (1ULL << 26); /* do ~64M packets */
+	opt->nb_timers = 1E8;
+	opt->nb_timer_adptrs = 1;
+	opt->timer_tick_nsec = 1E3; /* 1000ns ~ 1us */
+	opt->max_tmo_nsec = 1E5;  /* 100000ns ~100us */
+	opt->expiry_nsec = 1E4;   /* 10000ns ~10us */
 	opt->prod_type = EVT_PROD_TYPE_SYNT;
 }

@@ -86,6 +91,13 @@ evt_parse_eth_prod_type(struct evt_options *opt, const char *arg __rte_unused)
 	return 0;
 }

+static int
+evt_parse_timer_prod_type(struct evt_options *opt, const char *arg __rte_unused)
+{
+	opt->prod_type = EVT_PROD_TYPE_EVENT_TIMER_ADPTR;
+	return 0;
+}
+
 static int
 evt_parse_test_name(struct evt_options *opt, const char *arg)
 {
@@ -169,7 +181,10 @@ usage(char *program)
 		"\t--worker_deq_depth : dequeue depth of the worker\n"
 		"\t--fwd_latency      : perform fwd_latency measurement\n"
 		"\t--queue_priority   : enable queue priority\n"
-		"\t--prod_type_ethdev : use ethernet device as producer\n."
+		"\t--prod_type_ethdev : use ethernet device as producer.\n"
+		"\t--prod_type_timerdev : use event timer device as producer.\n"
+		"\t                     expity_nsec would be the timeout\n"
+		"\t                     in ns.\n"
 		);
 	printf("available tests:\n");
 	evt_test_dump_names();
@@ -217,22 +232,23 @@ evt_parse_sched_type_list(struct evt_options *opt, const char *arg)
 }

 static struct option lgopts[] = {
-	{ EVT_NB_FLOWS,         1, 0, 0 },
-	{ EVT_DEVICE,           1, 0, 0 },
-	{ EVT_VERBOSE,          1, 0, 0 },
-	{ EVT_TEST,             1, 0, 0 },
-	{ EVT_PROD_LCORES,      1, 0, 0 },
-	{ EVT_WORK_LCORES,      1, 0, 0 },
-	{ EVT_SOCKET_ID,        1, 0, 0 },
-	{ EVT_POOL_SZ,          1, 0, 0 },
-	{ EVT_NB_PKTS,          1, 0, 0 },
-	{ EVT_WKR_DEQ_DEP,      1, 0, 0 },
-	{ EVT_SCHED_TYPE_LIST,  1, 0, 0 },
-	{ EVT_FWD_LATENCY,      0, 0, 0 },
-	{ EVT_QUEUE_PRIORITY,   0, 0, 0 },
-	{ EVT_PROD_ETHDEV,      0, 0, 0 },
-	{ EVT_HELP,             0, 0, 0 },
-	{ NULL,                 0, 0, 0 }
+	{ EVT_NB_FLOWS,            1, 0, 0 },
+	{ EVT_DEVICE,              1, 0, 0 },
+	{ EVT_VERBOSE,             1, 0, 0 },
+	{ EVT_TEST,                1, 0, 0 },
+	{ EVT_PROD_LCORES,         1, 0, 0 },
+	{ EVT_WORK_LCORES,         1, 0, 0 },
+	{ EVT_SOCKET_ID,           1, 0, 0 },
+	{ EVT_POOL_SZ,             1, 0, 0 },
+	{ EVT_NB_PKTS,             1, 0, 0 },
+	{ EVT_WKR_DEQ_DEP,         1, 0, 0 },
+	{ EVT_SCHED_TYPE_LIST,     1, 0, 0 },
+	{ EVT_FWD_LATENCY,         0, 0, 0 },
+	{ EVT_QUEUE_PRIORITY,      0, 0, 0 },
+	{ EVT_PROD_ETHDEV,         0, 0, 0 },
+	{ EVT_PROD_TIMERDEV,       0, 0, 0 },
+	{ EVT_HELP,                0, 0, 0 },
+	{ NULL,                    0, 0, 0 }
 };

 static int
@@ -255,11 +271,12 @@ evt_opts_parse_long(int opt_idx, struct evt_options *opt)
 		{ EVT_FWD_LATENCY, evt_parse_fwd_latency},
 		{ EVT_QUEUE_PRIORITY, evt_parse_queue_priority},
 		{ EVT_PROD_ETHDEV, evt_parse_eth_prod_type},
+		{ EVT_PROD_TIMERDEV, evt_parse_timer_prod_type},
 	};

 	for (i = 0; i < RTE_DIM(parsermap); i++) {
 		if (strncmp(lgopts[opt_idx].name, parsermap[i].lgopt_name,
-				strlen(parsermap[i].lgopt_name)) == 0)
+				strlen(lgopts[opt_idx].name)) == 0)
 			return parsermap[i].parser_fn(opt, optarg);
 	}

@@ -305,6 +322,7 @@ evt_options_dump(struct evt_options *opt)
 	evt_dump("pool_sz", "%d", opt->pool_sz);
 	evt_dump("master lcore", "%d", rte_get_master_lcore());
 	evt_dump("nb_pkts", "%"PRIu64, opt->nb_pkts);
+	evt_dump("nb_timers", "%"PRIu64, opt->nb_timers);
 	evt_dump_begin("available lcores");
 	RTE_LCORE_FOREACH(lcore_id)
 		printf("%d ", lcore_id);
diff --git a/app/test-eventdev/evt_options.h b/app/test-eventdev/evt_options.h
index 46d122229..b51d8d5b3 100644
--- a/app/test-eventdev/evt_options.h
+++ b/app/test-eventdev/evt_options.h
@@ -9,6 +9,7 @@
 #include <stdbool.h>

 #include <rte_common.h>
+#include <rte_ethdev.h>
 #include <rte_eventdev.h>
 #include <rte_lcore.h>

@@ -31,12 +32,14 @@
 #define EVT_FWD_LATENCY          ("fwd_latency")
 #define EVT_QUEUE_PRIORITY       ("queue_priority")
 #define EVT_PROD_ETHDEV          ("prod_type_ethdev")
+#define EVT_PROD_TIMERDEV        ("prod_type_timerdev")
 #define EVT_HELP                 ("help")

 enum evt_prod_type {
 	EVT_PROD_TYPE_NONE,
 	EVT_PROD_TYPE_SYNT,          /* Producer type Synthetic i.e. CPU. */
 	EVT_PROD_TYPE_ETH_RX_ADPTR,  /* Producer type Eth Rx Adapter. */
+	EVT_PROD_TYPE_EVENT_TIMER_ADPTR,  /* Producer type Timer Adapter. */
 	EVT_PROD_TYPE_MAX,
 };

@@ -52,11 +55,18 @@ struct evt_options {
 	int nb_stages;
 	int verbose_level;
 	uint64_t nb_pkts;
+	uint8_t nb_timer_adptrs;
+	uint64_t nb_timers;
+	uint64_t timer_tick_nsec;
+	uint64_t optm_timer_tick_nsec;
+	uint64_t max_tmo_nsec;
+	uint64_t expiry_nsec;
 	uint16_t wkr_deq_dep;
 	uint8_t dev_id;
 	uint32_t fwd_latency:1;
 	uint32_t q_priority:1;
 	enum evt_prod_type prod_type;
+	uint8_t timdev_cnt;
 };

 void evt_options_default(struct evt_options *opt);
@@ -262,6 +272,20 @@ evt_dump_producer_type(struct evt_options *opt)
 	case EVT_PROD_TYPE_ETH_RX_ADPTR:
 		snprintf(name, EVT_PROD_MAX_NAME_LEN,
 				"Ethdev Rx Adapter producers");
+		evt_dump("nb_ethdev", "%d", rte_eth_dev_count());
+		break;
+	case EVT_PROD_TYPE_EVENT_TIMER_ADPTR:
+		snprintf(name, EVT_PROD_MAX_NAME_LEN,
+				"Event timer adapter producer");
+		evt_dump("nb_timer_adapters", "%d", opt->nb_timer_adptrs);
+		evt_dump("max_tmo_nsec", "%"PRIu64"", opt->max_tmo_nsec);
+		evt_dump("expiry_nsec", "%"PRIu64"", opt->expiry_nsec);
+		if (opt->optm_timer_tick_nsec)
+			evt_dump("optm_timer_tick_ns", "%"PRIu64"",
+					opt->optm_timer_tick_nsec);
+		else
+			evt_dump("timer_tick_ns", "%"PRIu64"",
+					opt->timer_tick_nsec);
 		break;
 	}
 	evt_dump("prod_type", "%s", name);
diff --git a/app/test-eventdev/test_perf_atq.c b/app/test-eventdev/test_perf_atq.c
index b36b22a77..b3a312722 100644
--- a/app/test-eventdev/test_perf_atq.c
+++ b/app/test-eventdev/test_perf_atq.c
@@ -43,15 +43,12 @@ perf_atq_worker(void *arg, const int enable_fwd_latency)
 	while (t->done == false) {
 		uint16_t event = rte_event_dequeue_burst(dev, port, &ev, 1, 0);

-		if (enable_fwd_latency)
-			rte_prefetch0(ev.event_ptr);
-
 		if (!event) {
 			rte_pause();
 			continue;
 		}

-		if (enable_fwd_latency)
+		if (enable_fwd_latency && !prod_timer_type)
 		/* first stage in pipeline, mark ts to compute fwd latency */
 			atq_mark_fwd_latency(&ev);

@@ -90,7 +87,7 @@ perf_atq_worker_burst(void *arg, const int enable_fwd_latency)
 		}

 		for (i = 0; i < nb_rx; i++) {
-			if (enable_fwd_latency) {
+			if (enable_fwd_latency && !prod_timer_type) {
 				rte_prefetch0(ev[i+1].event_ptr);
 				/* first stage in pipeline.
 				 * mark time stamp to compute fwd latency
@@ -163,7 +160,8 @@ perf_atq_eventdev_setup(struct evt_test *test, struct evt_options *opt)
 	struct rte_event_dev_info dev_info;

 	nb_ports = evt_nr_active_lcores(opt->wlcores);
-	nb_ports += opt->prod_type == EVT_PROD_TYPE_ETH_RX_ADPTR ? 0 :
+	nb_ports += (opt->prod_type == EVT_PROD_TYPE_ETH_RX_ADPTR ||
+			opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR) ? 0 :
 		evt_nr_active_lcores(opt->plcores);

 	nb_queues = atq_nb_event_queues(opt);
diff --git a/app/test-eventdev/test_perf_common.c b/app/test-eventdev/test_perf_common.c
index 59fa0a49e..b6cc00e60 100644
--- a/app/test-eventdev/test_perf_common.c
+++ b/app/test-eventdev/test_perf_common.c
@@ -72,6 +72,67 @@ perf_producer(void *arg)
 	return 0;
 }

+static inline int
+perf_event_timer_producer(void *arg)
+{
+	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;
+	struct rte_event_timer_adapter **adptr = t->timer_adptr;
+	uint64_t timeout_ticks = opt->expiry_nsec / opt->timer_tick_nsec;
+
+	timeout_ticks = opt->optm_timer_tick_nsec ?
+			(timeout_ticks * opt->timer_tick_nsec)
+			/ opt->optm_timer_tick_nsec : timeout_ticks;
+	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(pool, (void **)&m) < 0)
+			continue;
+
+		m->tim = tim;
+		m->tim.ev.flow_id = flow_counter++ % nb_flows;
+		m->tim.ev.event_ptr = m;
+		m->timestamp = rte_get_timer_cycles();
+		while (rte_event_timer_arm_burst(
+				adptr[flow_counter % nb_timer_adptrs],
+				(struct rte_event_timer **)&m, 1) != 1) {
+			if (t->done)
+				break;
+			rte_pause();
+			m->timestamp = rte_get_timer_cycles();
+		}
+		arm_latency += rte_get_timer_cycles() - m->timestamp;
+		count++;
+	}
+	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)
 {
@@ -80,6 +141,8 @@ 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)
+		return perf_event_timer_producer(arg);
 	return 0;
 }

@@ -146,8 +209,7 @@ perf_launch_lcores(struct evt_test *test, struct evt_options *opt,
 		port_idx++;
 	}

-	const uint64_t total_pkts = opt->nb_pkts *
-			evt_nr_active_lcores(opt->plcores);
+	const uint64_t total_pkts = t->outstand_pkts;

 	uint64_t dead_lock_cycles = rte_get_timer_cycles();
 	int64_t dead_lock_remaining  =  total_pkts;
@@ -189,7 +251,9 @@ perf_launch_lcores(struct evt_test *test, struct evt_options *opt,

 			if (remaining <= 0) {
 				t->result = EVT_TEST_SUCCESS;
-				if (opt->prod_type == EVT_PROD_TYPE_SYNT) {
+				if (opt->prod_type == EVT_PROD_TYPE_SYNT ||
+					opt->prod_type ==
+					EVT_PROD_TYPE_EVENT_TIMER_ADPTR) {
 					t->done = true;
 					rte_smp_wmb();
 					break;
@@ -283,6 +347,65 @@ perf_event_rx_adapter_setup(struct evt_options *opt, uint8_t stride,
 	return ret;
 }

+static int
+perf_event_timer_adapter_setup(struct test_perf *t)
+{
+	int i;
+	int ret;
+	struct rte_event_timer_adapter_info adapter_info;
+	struct rte_event_timer_adapter *wl;
+	uint8_t nb_producers = evt_nr_active_lcores(t->opt->plcores);
+	uint8_t flags = RTE_EVENT_TIMER_ADAPTER_F_ADJUST_RES;
+
+	if (nb_producers == 1)
+		flags |= RTE_EVENT_TIMER_ADAPTER_F_SP_PUT;
+
+	for (i = 0; i < t->opt->nb_timer_adptrs; i++) {
+		struct rte_event_timer_adapter_conf config = {
+			.event_dev_id = t->opt->dev_id,
+			.timer_adapter_id = i,
+			.timer_tick_ns = t->opt->timer_tick_nsec,
+			.max_tmo_ns = t->opt->max_tmo_nsec,
+			.nb_timers = 2 * 1024 * 1024,
+			.flags = flags,
+		};
+
+		wl = rte_event_timer_adapter_create(&config);
+		if (wl == NULL) {
+			evt_err("failed to create event timer ring %d", i);
+			return rte_errno;
+		}
+
+		memset(&adapter_info, 0,
+				sizeof(struct rte_event_timer_adapter_info));
+		rte_event_timer_adapter_get_info(wl, &adapter_info);
+		t->opt->optm_timer_tick_nsec = adapter_info.min_resolution_ns;
+
+		if (!(adapter_info.caps &
+				RTE_EVENT_TIMER_ADAPTER_CAP_INTERNAL_PORT)) {
+			uint32_t service_id;
+
+			rte_event_timer_adapter_service_id_get(wl,
+					&service_id);
+			ret = evt_service_setup(service_id);
+			if (ret) {
+				evt_err("Failed to setup service core"
+						" for timer adapter\n");
+				return ret;
+			}
+			rte_service_runstate_set(service_id, 1);
+		}
+
+		ret = rte_event_timer_adapter_start(wl);
+		if (ret) {
+			evt_err("failed to Start event timer adapter %d", i);
+			return ret;
+		}
+		t->timer_adptr[i] = wl;
+	}
+	return 0;
+}
+
 int
 perf_event_dev_port_setup(struct evt_test *test, struct evt_options *opt,
 				uint8_t stride, uint8_t nb_queues,
@@ -326,6 +449,18 @@ perf_event_dev_port_setup(struct evt_test *test, struct evt_options *opt,
 		ret = perf_event_rx_adapter_setup(opt, stride, *port_conf);
 		if (ret)
 			return ret;
+	} else if (opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR) {
+		prod = 0;
+		for ( ; port < perf_nb_event_ports(opt); port++) {
+			struct prod_data *p = &t->prod[port];
+			p->queue_id = prod * stride;
+			p->t = t;
+			prod++;
+		}
+
+		ret = perf_event_timer_adapter_setup(t);
+		if (ret)
+			return ret;
 	} else {
 		prod = 0;
 		for ( ; port < perf_nb_event_ports(opt); port++) {
@@ -415,10 +550,13 @@ perf_opt_check(struct evt_options *opt, uint64_t nb_queues)
 	}

 	/* Fixups */
-	if (opt->nb_stages == 1 && opt->fwd_latency) {
+	if ((opt->nb_stages == 1 &&
+			opt->prod_type != EVT_PROD_TYPE_EVENT_TIMER_ADPTR) &&
+			opt->fwd_latency) {
 		evt_info("fwd_latency is valid when nb_stages > 1, disabling");
 		opt->fwd_latency = 0;
 	}
+
 	if (opt->fwd_latency && !opt->q_priority) {
 		evt_info("enabled queue priority for latency measurement");
 		opt->q_priority = 1;
@@ -447,8 +585,13 @@ perf_opt_dump(struct evt_options *opt, uint8_t nb_queues)
 void
 perf_eventdev_destroy(struct evt_test *test, struct evt_options *opt)
 {
-	RTE_SET_USED(test);
+	int i;
+	struct test_perf *t = evt_test_priv(test);

+	if (opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR) {
+		for (i = 0; i < opt->nb_timer_adptrs; i++)
+			rte_event_timer_adapter_stop(t->timer_adptr[i]);
+	}
 	rte_event_dev_stop(opt->dev_id);
 	rte_event_dev_close(opt->dev_id);
 }
@@ -488,7 +631,8 @@ perf_ethdev_setup(struct evt_test *test, struct evt_options *opt)
 		},
 	};

-	if (opt->prod_type == EVT_PROD_TYPE_SYNT)
+	if (opt->prod_type == EVT_PROD_TYPE_SYNT ||
+			opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR)
 		return 0;

 	if (!rte_eth_dev_count()) {
@@ -544,7 +688,8 @@ perf_mempool_setup(struct evt_test *test, struct evt_options *opt)
 {
 	struct test_perf *t = evt_test_priv(test);

-	if (opt->prod_type == EVT_PROD_TYPE_SYNT) {
+	if (opt->prod_type == EVT_PROD_TYPE_SYNT ||
+			opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR) {
 		t->pool = rte_mempool_create(test->name, /* mempool name */
 				opt->pool_sz, /* number of elements*/
 				sizeof(struct perf_elt), /* element size*/
@@ -594,10 +739,18 @@ perf_test_setup(struct evt_test *test, struct evt_options *opt)

 	struct test_perf *t = evt_test_priv(test);

-	t->outstand_pkts = opt->nb_pkts * evt_nr_active_lcores(opt->plcores);
+	if (opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR) {
+		t->outstand_pkts = opt->nb_timers *
+			evt_nr_active_lcores(opt->plcores);
+		t->nb_pkts = opt->nb_timers;
+	} else {
+		t->outstand_pkts = opt->nb_pkts *
+			evt_nr_active_lcores(opt->plcores);
+		t->nb_pkts = opt->nb_pkts;
+	}
+
 	t->nb_workers = evt_nr_active_lcores(opt->wlcores);
 	t->done = false;
-	t->nb_pkts = opt->nb_pkts;
 	t->nb_flows = opt->nb_flows;
 	t->result = EVT_TEST_FAILED;
 	t->opt = opt;
diff --git a/app/test-eventdev/test_perf_common.h b/app/test-eventdev/test_perf_common.h
index 9ad99733b..d8fbee6d8 100644
--- a/app/test-eventdev/test_perf_common.h
+++ b/app/test-eventdev/test_perf_common.h
@@ -13,6 +13,7 @@
 #include <rte_ethdev.h>
 #include <rte_eventdev.h>
 #include <rte_event_eth_rx_adapter.h>
+#include <rte_event_timer_adapter.h>
 #include <rte_lcore.h>
 #include <rte_malloc.h>
 #include <rte_mempool.h>
@@ -39,6 +40,7 @@ struct prod_data {
 	struct test_perf *t;
 } __rte_cache_aligned;

+
 struct test_perf {
 	/* Don't change the offset of "done". Signal handler use this memory
 	 * to terminate all lcores work.
@@ -54,10 +56,18 @@ struct test_perf {
 	struct worker_data worker[EVT_MAX_PORTS];
 	struct evt_options *opt;
 	uint8_t sched_type_list[EVT_MAX_STAGES] __rte_cache_aligned;
+	struct rte_event_timer_adapter *timer_adptr[
+		RTE_EVENT_TIMER_ADAPTER_NUM_MAX] __rte_cache_aligned;
 } __rte_cache_aligned;

 struct perf_elt {
-	uint64_t timestamp;
+	union {
+		struct rte_event_timer tim;
+		struct {
+			char pad[offsetof(struct rte_event_timer, user_meta)];
+			uint64_t timestamp;
+		};
+	};
 } __rte_cache_aligned;

 #define BURST_SIZE 16
@@ -68,6 +78,8 @@ struct perf_elt {
 	struct evt_options *opt = t->opt;\
 	const uint8_t dev = w->dev_id;\
 	const uint8_t port = w->port_id;\
+	const uint8_t prod_timer_type = \
+		opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR;\
 	uint8_t *const sched_type_list = &t->sched_type_list[0];\
 	struct rte_mempool *const pool = t->pool;\
 	const uint8_t nb_stages = t->opt->nb_stages;\
diff --git a/app/test-eventdev/test_perf_queue.c b/app/test-eventdev/test_perf_queue.c
index db8f2f3e5..74469a5ee 100644
--- a/app/test-eventdev/test_perf_queue.c
+++ b/app/test-eventdev/test_perf_queue.c
@@ -49,7 +49,7 @@ perf_queue_worker(void *arg, const int enable_fwd_latency)
 			rte_pause();
 			continue;
 		}
-		if (enable_fwd_latency)
+		if (enable_fwd_latency && !prod_timer_type)
 		/* first q in pipeline, mark timestamp to compute fwd latency */
 			mark_fwd_latency(&ev, nb_stages);

@@ -88,7 +88,7 @@ perf_queue_worker_burst(void *arg, const int enable_fwd_latency)
 		}

 		for (i = 0; i < nb_rx; i++) {
-			if (enable_fwd_latency) {
+			if (enable_fwd_latency && !prod_timer_type) {
 				rte_prefetch0(ev[i+1].event_ptr);
 				/* first queue in pipeline.
 				 * mark time stamp to compute fwd latency
@@ -161,7 +161,8 @@ perf_queue_eventdev_setup(struct evt_test *test, struct evt_options *opt)
 	struct rte_event_dev_info dev_info;

 	nb_ports = evt_nr_active_lcores(opt->wlcores);
-	nb_ports += opt->prod_type == EVT_PROD_TYPE_ETH_RX_ADPTR ? 0 :
+	nb_ports += opt->prod_type == EVT_PROD_TYPE_ETH_RX_ADPTR ||
+		 opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR ? 0 :
 		evt_nr_active_lcores(opt->plcores);

 	nb_queues = perf_queue_nb_event_queues(opt);
--
2.17.0

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [dpdk-dev] [PATCH v5 2/4] app/eventdev: add burst mode for event timer adapter
  2018-04-06 15:13 ` [dpdk-dev] [PATCH v5 1/4] app/eventdev: add event timer adapter as a producer Pavan Nikhilesh
@ 2018-04-06 15:13   ` Pavan Nikhilesh
  2018-04-06 15:13   ` [dpdk-dev] [PATCH v5 3/4] app/eventdev: add options to configure " Pavan Nikhilesh
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 36+ messages in thread
From: Pavan Nikhilesh @ 2018-04-06 15:13 UTC (permalink / raw)
  To: jerin.jacob, santosh.shukla, erik.g.carrillo; +Cc: dev, Pavan Nikhilesh

Add burst mode for event timer adapter that can be selected by passing
--prod_type_timerdev_burst.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
Acked-by: Erik Gabriel Carrillo <erik.g.carrillo@intel.com>
Acked-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
---
 app/test-eventdev/evt_options.c      | 13 ++++++
 app/test-eventdev/evt_options.h      |  8 +++-
 app/test-eventdev/test_perf_common.c | 67 +++++++++++++++++++++++++++-
 3 files changed, 86 insertions(+), 2 deletions(-)

diff --git a/app/test-eventdev/evt_options.c b/app/test-eventdev/evt_options.c
index 47e37bc9b..1b60eb2ef 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                     expity_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 b51d8d5b3..e5e632783 100644
--- a/app/test-eventdev/evt_options.h
+++ b/app/test-eventdev/evt_options.h
@@ -33,6 +33,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 {
@@ -66,6 +67,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;
 };
 
@@ -275,7 +277,11 @@ evt_dump_producer_type(struct evt_options *opt)
 		evt_dump("nb_ethdev", "%d", rte_eth_dev_count());
 		break;
 	case EVT_PROD_TYPE_EVENT_TIMER_ADPTR:
-		snprintf(name, EVT_PROD_MAX_NAME_LEN,
+		if (opt->timdev_use_burst)
+			snprintf(name, EVT_PROD_MAX_NAME_LEN,
+				"Event timer adapter burst mode producer");
+		else
+			snprintf(name, EVT_PROD_MAX_NAME_LEN,
 				"Event timer adapter producer");
 		evt_dump("nb_timer_adapters", "%d", opt->nb_timer_adptrs);
 		evt_dump("max_tmo_nsec", "%"PRIu64"", opt->max_tmo_nsec);
diff --git a/app/test-eventdev/test_perf_common.c b/app/test-eventdev/test_perf_common.c
index b6cc00e60..a74ab9a9e 100644
--- a/app/test-eventdev/test_perf_common.c
+++ b/app/test-eventdev/test_perf_common.c
@@ -133,6 +133,67 @@ 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->expiry_nsec / opt->timer_tick_nsec;
+
+	timeout_ticks = opt->optm_timer_tick_nsec ?
+			(timeout_ticks * opt->timer_tick_nsec)
+			/ opt->optm_timer_tick_nsec : timeout_ticks;
+	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)
 {
@@ -141,8 +202,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.17.0

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [dpdk-dev] [PATCH v5 3/4] app/eventdev: add options to configure event timer adapter
  2018-04-06 15:13 ` [dpdk-dev] [PATCH v5 1/4] app/eventdev: add event timer adapter as a producer Pavan Nikhilesh
  2018-04-06 15:13   ` [dpdk-dev] [PATCH v5 2/4] app/eventdev: add burst mode for event timer adapter Pavan Nikhilesh
@ 2018-04-06 15:13   ` Pavan Nikhilesh
  2018-04-06 15:13   ` [dpdk-dev] [PATCH v5 4/4] doc: update test eventdev documentation Pavan Nikhilesh
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 36+ messages in thread
From: Pavan Nikhilesh @ 2018-04-06 15:13 UTC (permalink / raw)
  To: jerin.jacob, santosh.shukla, erik.g.carrillo; +Cc: dev, Pavan Nikhilesh

Add options to configure expiry timeout, max number of timers and number
of event timer adapters through command line parameters.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
Acked-by: Erik Gabriel Carrillo <erik.g.carrillo@intel.com>
Acked-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
---
 app/test-eventdev/evt_options.c | 65 +++++++++++++++++++++++++++++++++
 app/test-eventdev/evt_options.h |  5 +++
 2 files changed, 70 insertions(+)

diff --git a/app/test-eventdev/evt_options.c b/app/test-eventdev/evt_options.c
index 1b60eb2ef..5f311a570 100644
--- a/app/test-eventdev/evt_options.c
+++ b/app/test-eventdev/evt_options.c
@@ -140,6 +140,56 @@ evt_parse_nb_pkts(struct evt_options *opt, const char *arg)
 	return ret;
 }
 
+static int
+evt_parse_nb_timers(struct evt_options *opt, const char *arg)
+{
+	int ret;
+
+	ret = parser_read_uint64(&(opt->nb_timers), arg);
+
+	return ret;
+}
+
+static int
+evt_parse_timer_tick_nsec(struct evt_options *opt, const char *arg)
+{
+	int ret;
+
+	ret = parser_read_uint64(&(opt->timer_tick_nsec), arg);
+
+	return ret;
+}
+
+static int
+evt_parse_max_tmo_nsec(struct evt_options *opt, const char *arg)
+{
+	int ret;
+
+	ret = parser_read_uint64(&(opt->max_tmo_nsec), arg);
+
+	return ret;
+}
+
+static int
+evt_parse_expiry_nsec(struct evt_options *opt, const char *arg)
+{
+	int ret;
+
+	ret = parser_read_uint64(&(opt->expiry_nsec), arg);
+
+	return ret;
+}
+
+static int
+evt_parse_nb_timer_adptrs(struct evt_options *opt, const char *arg)
+{
+	int ret;
+
+	ret = parser_read_uint8(&(opt->nb_timer_adptrs), arg);
+
+	return ret;
+}
+
 static int
 evt_parse_pool_sz(struct evt_options *opt, const char *arg)
 {
@@ -196,6 +246,11 @@ usage(char *program)
 		"\t                     in ns.\n"
 		"\t--prod_type_timerdev_burst : use timer device as producer\n"
 		"\t                             burst mode.\n"
+		"\t--nb_timers        : number of timers to arm.\n"
+		"\t--nb_timer_adptrs  : number of timer adapters to use.\n"
+		"\t--timer_tick_nsec  : timer tick interval in ns.\n"
+		"\t--max_tmo_nsec     : max timeout interval in ns.\n"
+		"\t--expiry_ns        : event timer expiry ns.\n"
 		);
 	printf("available tests:\n");
 	evt_test_dump_names();
@@ -259,6 +314,11 @@ static struct option lgopts[] = {
 	{ EVT_PROD_ETHDEV,         0, 0, 0 },
 	{ EVT_PROD_TIMERDEV,       0, 0, 0 },
 	{ EVT_PROD_TIMERDEV_BURST, 0, 0, 0 },
+	{ EVT_NB_TIMERS,           1, 0, 0 },
+	{ EVT_NB_TIMER_ADPTRS,     1, 0, 0 },
+	{ EVT_TIMER_TICK_NSEC,     1, 0, 0 },
+	{ EVT_MAX_TMO_NSEC,        1, 0, 0 },
+	{ EVT_EXPIRY_NSEC,         1, 0, 0 },
 	{ EVT_HELP,                0, 0, 0 },
 	{ NULL,                    0, 0, 0 }
 };
@@ -285,6 +345,11 @@ evt_opts_parse_long(int opt_idx, struct evt_options *opt)
 		{ 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},
+		{ EVT_NB_TIMERS, evt_parse_nb_timers},
+		{ EVT_NB_TIMER_ADPTRS, evt_parse_nb_timer_adptrs},
+		{ EVT_TIMER_TICK_NSEC, evt_parse_timer_tick_nsec},
+		{ EVT_MAX_TMO_NSEC, evt_parse_max_tmo_nsec},
+		{ EVT_EXPIRY_NSEC, evt_parse_expiry_nsec},
 	};
 
 	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 e5e632783..c059f7084 100644
--- a/app/test-eventdev/evt_options.h
+++ b/app/test-eventdev/evt_options.h
@@ -34,6 +34,11 @@
 #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_NB_TIMERS            ("nb_timers")
+#define EVT_NB_TIMER_ADPTRS      ("nb_timer_adptrs")
+#define EVT_TIMER_TICK_NSEC      ("timer_tick_ns")
+#define EVT_MAX_TMO_NSEC         ("max_tmo_nsec")
+#define EVT_EXPIRY_NSEC          ("expiry_ns")
 #define EVT_HELP                 ("help")
 
 enum evt_prod_type {
-- 
2.17.0

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [dpdk-dev] [PATCH v5 4/4] doc: update test eventdev documentation
  2018-04-06 15:13 ` [dpdk-dev] [PATCH v5 1/4] app/eventdev: add event timer adapter as a producer Pavan Nikhilesh
  2018-04-06 15:13   ` [dpdk-dev] [PATCH v5 2/4] app/eventdev: add burst mode for event timer adapter Pavan Nikhilesh
  2018-04-06 15:13   ` [dpdk-dev] [PATCH v5 3/4] app/eventdev: add options to configure " Pavan Nikhilesh
@ 2018-04-06 15:13   ` Pavan Nikhilesh
  2018-04-07  9:34   ` [dpdk-dev] [PATCH v5 1/4] app/eventdev: add event timer adapter as a producer Jerin Jacob
  2018-04-17  8:18   ` Maxime Coquelin
  4 siblings, 0 replies; 36+ messages in thread
From: Pavan Nikhilesh @ 2018-04-06 15:13 UTC (permalink / raw)
  To: jerin.jacob, santosh.shukla, erik.g.carrillo; +Cc: dev, Pavan Nikhilesh

Update documentation to include new options added for using event timer
adapter as a producer.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
Acked-by: Erik Gabriel Carrillo <erik.g.carrillo@intel.com>
Acked-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
---
 doc/guides/tools/testeventdev.rst | 60 +++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/doc/guides/tools/testeventdev.rst b/doc/guides/tools/testeventdev.rst
index 77480ffe9..46effd871 100644
--- a/doc/guides/tools/testeventdev.rst
+++ b/doc/guides/tools/testeventdev.rst
@@ -123,6 +123,36 @@ The following are the application command-line options:
 
         Use ethernet device as producer.
 
+* ``--prod_type_timerdev``
+
+        Use event timer adapter as producer.
+
+ * ``--prod_type_timerdev_burst``
+
+        Use burst mode event timer adapter as producer.
+
+ * ``--timer_tick_nsec``
+
+        Used to dictate number of nano seconds between bucket traversal of the
+        event timer adapter. Refer `rte_event_timer_adapter_conf`.
+
+ * ``--max_tmo_nsec``
+
+        Used to configure event timer adapter max arm timeout in nano seconds.
+
+ * ``--expiry_nsec``
+
+        Dictate the number of nano seconds after which the event timer expires.
+
+ * ``--nb_timers``
+
+        Number of event timers each producer core will generate.
+
+ * ``--nb_timer_adptrs``
+
+        Number of event timer adapters to be used. Each adapter is used in
+        round robin manner by the producer cores.
+
 Eventdev Tests
 --------------
 
@@ -347,6 +377,13 @@ Supported application command line options are following::
         --fwd_latency
         --queue_priority
         --prod_type_ethdev
+        --prod_type_timerdev_burst
+        --prod_type_timerdev
+        --timer_tick_nsec
+        --max_tmo_nsec
+        --expiry_nsec
+        --nb_timers
+        --nb_timer_adptrs
 
 Example
 ^^^^^^^
@@ -365,6 +402,14 @@ Example command to run perf queue test with ethernet ports:
    sudo build/app/dpdk-test-eventdev --vdev=event_sw0 -- \
         --test=perf_queue --plcores=2 --wlcore=3 --stlist=p --prod_type_ethdev
 
+Example command to run perf queue test with event timer adapter:
+
+.. code-block:: console
+
+   sudo  build/app/dpdk-test-eventdev --vdev="event_octeontx" -- \
+                --wlcores 4 --plcores 12 --test perf_queue --stlist=a \
+                --prod_type_timerdev --fwd_latency
+
 PERF_ATQ Test
 ~~~~~~~~~~~~~~~
 
@@ -431,6 +476,13 @@ Supported application command line options are following::
         --worker_deq_depth
         --fwd_latency
         --prod_type_ethdev
+        --prod_type_timerdev_burst
+        --prod_type_timerdev
+        --timer_tick_nsec
+        --max_tmo_nsec
+        --expiry_nsec
+        --nb_timers
+        --nb_timer_adptrs
 
 Example
 ^^^^^^^
@@ -442,6 +494,14 @@ Example command to run perf ``all types queue`` test:
    sudo build/app/dpdk-test-eventdev --vdev=event_octeontx -- \
                 --test=perf_atq --plcores=2 --wlcore=3 --stlist=p --nb_pkts=0
 
+Example command to run perf ``all types queue`` test with event timer adapter:
+
+.. code-block:: console
+
+   sudo  build/app/dpdk-test-eventdev --vdev="event_octeontx" -- \
+                --wlcores 4 --plcores 12 --test perf_atq --verbose 20 \
+                --stlist=a --prod_type_timerdev --fwd_latency
+
 
 PIPELINE_QUEUE Test
 ~~~~~~~~~~~~~~~~~~~
-- 
2.17.0

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [dpdk-dev] [PATCH v5 1/4] app/eventdev: add event timer adapter as a producer
  2018-04-06 15:13 ` [dpdk-dev] [PATCH v5 1/4] app/eventdev: add event timer adapter as a producer Pavan Nikhilesh
                     ` (2 preceding siblings ...)
  2018-04-06 15:13   ` [dpdk-dev] [PATCH v5 4/4] doc: update test eventdev documentation Pavan Nikhilesh
@ 2018-04-07  9:34   ` Jerin Jacob
  2018-04-17  8:18   ` Maxime Coquelin
  4 siblings, 0 replies; 36+ messages in thread
From: Jerin Jacob @ 2018-04-07  9:34 UTC (permalink / raw)
  To: Pavan Nikhilesh; +Cc: santosh.shukla, erik.g.carrillo, dev

-----Original Message-----
> Date: Fri,  6 Apr 2018 20:43:21 +0530
> From: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
> To: jerin.jacob@caviumnetworks.com, santosh.shukla@caviumnetworks.com,
>  erik.g.carrillo@intel.com
> Cc: dev@dpdk.org, Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
> Subject: [dpdk-dev] [PATCH v5 1/4] app/eventdev: add event timer adapter as
>  a producer
> X-Mailer: git-send-email 2.17.0
> 
> Add event timer adapter as producer option that can be selected by
> passing --prod_type_timerdev.
> 
> Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
> Acked-by: Erik Gabriel Carrillo <erik.g.carrillo@intel.com>
> Acked-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>

Applied this series to dpdk-next-eventdev/master. Thanks.

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [dpdk-dev] [PATCH v5 1/4] app/eventdev: add event timer adapter as a producer
  2018-04-06 15:13 ` [dpdk-dev] [PATCH v5 1/4] app/eventdev: add event timer adapter as a producer Pavan Nikhilesh
                     ` (3 preceding siblings ...)
  2018-04-07  9:34   ` [dpdk-dev] [PATCH v5 1/4] app/eventdev: add event timer adapter as a producer Jerin Jacob
@ 2018-04-17  8:18   ` Maxime Coquelin
  2018-04-17  8:22     ` Pavan Nikhilesh
  4 siblings, 1 reply; 36+ messages in thread
From: Maxime Coquelin @ 2018-04-17  8:18 UTC (permalink / raw)
  To: Pavan Nikhilesh, jerin.jacob, santosh.shukla, erik.g.carrillo; +Cc: dev



On 04/06/2018 05:13 PM, Pavan Nikhilesh wrote:
> Add event timer adapter as producer option that can be selected by
> passing --prod_type_timerdev.
> 
> Signed-off-by: Pavan Nikhilesh <pbhagavatula@caviumnetworks.com>
> Acked-by: Erik Gabriel Carrillo <erik.g.carrillo@intel.com>
> Acked-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> ---
> 
>   v5 Changes:
>   - Resending cause missing Acked-by.
> 
>   v4 Changes:
>   - reuse struct rte_event_timer's unused data portion to store timestamp
>   instead of spilling timestamp into a new cacheline.
>   - change bkt_tck_nsec to timer_tick_nsec
>   - change nb_bkt_tcks to expiry_nsec
> 
>   v3 Changes:
>   - Add detailed options dump.
>   - Fix few typos.
> 
>   v2 Changes:
>   - set timer to NOT_ARMED before trying to arm it.
>   - prevent edge cases for timeout_ticks being set to 0.
> 
>   app/test-eventdev/evt_options.c      |  54 ++++++---
>   app/test-eventdev/evt_options.h      |  24 ++++
>   app/test-eventdev/test_perf_atq.c    |  10 +-
>   app/test-eventdev/test_perf_common.c | 171 +++++++++++++++++++++++++--
>   app/test-eventdev/test_perf_common.h |  14 ++-
>   app/test-eventdev/test_perf_queue.c  |   7 +-
>   6 files changed, 243 insertions(+), 37 deletions(-)
> 
> diff --git a/app/test-eventdev/evt_options.c b/app/test-eventdev/evt_options.c
> index 9683b2224..47e37bc9b 100644
> --- a/app/test-eventdev/evt_options.c
> +++ b/app/test-eventdev/evt_options.c
> @@ -27,6 +27,11 @@ evt_options_default(struct evt_options *opt)
>   	opt->pool_sz = 16 * 1024;
>   	opt->wkr_deq_dep = 16;
>   	opt->nb_pkts = (1ULL << 26); /* do ~64M packets */
> +	opt->nb_timers = 1E8;
> +	opt->nb_timer_adptrs = 1;
> +	opt->timer_tick_nsec = 1E3; /* 1000ns ~ 1us */
> +	opt->max_tmo_nsec = 1E5;  /* 100000ns ~100us */
> +	opt->expiry_nsec = 1E4;   /* 10000ns ~10us */
>   	opt->prod_type = EVT_PROD_TYPE_SYNT;
>   }
> 
> @@ -86,6 +91,13 @@ evt_parse_eth_prod_type(struct evt_options *opt, const char *arg __rte_unused)
>   	return 0;
>   }
> 
> +static int
> +evt_parse_timer_prod_type(struct evt_options *opt, const char *arg __rte_unused)
> +{
> +	opt->prod_type = EVT_PROD_TYPE_EVENT_TIMER_ADPTR;
> +	return 0;
> +}
> +
>   static int
>   evt_parse_test_name(struct evt_options *opt, const char *arg)
>   {
> @@ -169,7 +181,10 @@ usage(char *program)
>   		"\t--worker_deq_depth : dequeue depth of the worker\n"
>   		"\t--fwd_latency      : perform fwd_latency measurement\n"
>   		"\t--queue_priority   : enable queue priority\n"
> -		"\t--prod_type_ethdev : use ethernet device as producer\n."
> +		"\t--prod_type_ethdev : use ethernet device as producer.\n"
> +		"\t--prod_type_timerdev : use event timer device as producer.\n"
> +		"\t                     expity_nsec would be the timeout\n"
> +		"\t                     in ns.\n"
>   		);
>   	printf("available tests:\n");
>   	evt_test_dump_names();
> @@ -217,22 +232,23 @@ evt_parse_sched_type_list(struct evt_options *opt, const char *arg)
>   }
> 
>   static struct option lgopts[] = {
> -	{ EVT_NB_FLOWS,         1, 0, 0 },
> -	{ EVT_DEVICE,           1, 0, 0 },
> -	{ EVT_VERBOSE,          1, 0, 0 },
> -	{ EVT_TEST,             1, 0, 0 },
> -	{ EVT_PROD_LCORES,      1, 0, 0 },
> -	{ EVT_WORK_LCORES,      1, 0, 0 },
> -	{ EVT_SOCKET_ID,        1, 0, 0 },
> -	{ EVT_POOL_SZ,          1, 0, 0 },
> -	{ EVT_NB_PKTS,          1, 0, 0 },
> -	{ EVT_WKR_DEQ_DEP,      1, 0, 0 },
> -	{ EVT_SCHED_TYPE_LIST,  1, 0, 0 },
> -	{ EVT_FWD_LATENCY,      0, 0, 0 },
> -	{ EVT_QUEUE_PRIORITY,   0, 0, 0 },
> -	{ EVT_PROD_ETHDEV,      0, 0, 0 },
> -	{ EVT_HELP,             0, 0, 0 },
> -	{ NULL,                 0, 0, 0 }
> +	{ EVT_NB_FLOWS,            1, 0, 0 },
> +	{ EVT_DEVICE,              1, 0, 0 },
> +	{ EVT_VERBOSE,             1, 0, 0 },
> +	{ EVT_TEST,                1, 0, 0 },
> +	{ EVT_PROD_LCORES,         1, 0, 0 },
> +	{ EVT_WORK_LCORES,         1, 0, 0 },
> +	{ EVT_SOCKET_ID,           1, 0, 0 },
> +	{ EVT_POOL_SZ,             1, 0, 0 },
> +	{ EVT_NB_PKTS,             1, 0, 0 },
> +	{ EVT_WKR_DEQ_DEP,         1, 0, 0 },
> +	{ EVT_SCHED_TYPE_LIST,     1, 0, 0 },
> +	{ EVT_FWD_LATENCY,         0, 0, 0 },
> +	{ EVT_QUEUE_PRIORITY,      0, 0, 0 },
> +	{ EVT_PROD_ETHDEV,         0, 0, 0 },
> +	{ EVT_PROD_TIMERDEV,       0, 0, 0 },
> +	{ EVT_HELP,                0, 0, 0 },
> +	{ NULL,                    0, 0, 0 }
>   };
> 
>   static int
> @@ -255,11 +271,12 @@ evt_opts_parse_long(int opt_idx, struct evt_options *opt)
>   		{ EVT_FWD_LATENCY, evt_parse_fwd_latency},
>   		{ EVT_QUEUE_PRIORITY, evt_parse_queue_priority},
>   		{ EVT_PROD_ETHDEV, evt_parse_eth_prod_type},
> +		{ EVT_PROD_TIMERDEV, evt_parse_timer_prod_type},
>   	};
> 
>   	for (i = 0; i < RTE_DIM(parsermap); i++) {
>   		if (strncmp(lgopts[opt_idx].name, parsermap[i].lgopt_name,
> -				strlen(parsermap[i].lgopt_name)) == 0)
> +				strlen(lgopts[opt_idx].name)) == 0)
>   			return parsermap[i].parser_fn(opt, optarg);
>   	}
> 
> @@ -305,6 +322,7 @@ evt_options_dump(struct evt_options *opt)
>   	evt_dump("pool_sz", "%d", opt->pool_sz);
>   	evt_dump("master lcore", "%d", rte_get_master_lcore());
>   	evt_dump("nb_pkts", "%"PRIu64, opt->nb_pkts);
> +	evt_dump("nb_timers", "%"PRIu64, opt->nb_timers);
>   	evt_dump_begin("available lcores");
>   	RTE_LCORE_FOREACH(lcore_id)
>   		printf("%d ", lcore_id);
> diff --git a/app/test-eventdev/evt_options.h b/app/test-eventdev/evt_options.h
> index 46d122229..b51d8d5b3 100644
> --- a/app/test-eventdev/evt_options.h
> +++ b/app/test-eventdev/evt_options.h
> @@ -9,6 +9,7 @@
>   #include <stdbool.h>
> 
>   #include <rte_common.h>
> +#include <rte_ethdev.h>
>   #include <rte_eventdev.h>
>   #include <rte_lcore.h>
> 
> @@ -31,12 +32,14 @@
>   #define EVT_FWD_LATENCY          ("fwd_latency")
>   #define EVT_QUEUE_PRIORITY       ("queue_priority")
>   #define EVT_PROD_ETHDEV          ("prod_type_ethdev")
> +#define EVT_PROD_TIMERDEV        ("prod_type_timerdev")
>   #define EVT_HELP                 ("help")
> 
>   enum evt_prod_type {
>   	EVT_PROD_TYPE_NONE,
>   	EVT_PROD_TYPE_SYNT,          /* Producer type Synthetic i.e. CPU. */
>   	EVT_PROD_TYPE_ETH_RX_ADPTR,  /* Producer type Eth Rx Adapter. */
> +	EVT_PROD_TYPE_EVENT_TIMER_ADPTR,  /* Producer type Timer Adapter. */
>   	EVT_PROD_TYPE_MAX,
>   };
> 
> @@ -52,11 +55,18 @@ struct evt_options {
>   	int nb_stages;
>   	int verbose_level;
>   	uint64_t nb_pkts;
> +	uint8_t nb_timer_adptrs;
> +	uint64_t nb_timers;
> +	uint64_t timer_tick_nsec;
> +	uint64_t optm_timer_tick_nsec;
> +	uint64_t max_tmo_nsec;
> +	uint64_t expiry_nsec;
>   	uint16_t wkr_deq_dep;
>   	uint8_t dev_id;
>   	uint32_t fwd_latency:1;
>   	uint32_t q_priority:1;
>   	enum evt_prod_type prod_type;
> +	uint8_t timdev_cnt;
>   };
> 
>   void evt_options_default(struct evt_options *opt);
> @@ -262,6 +272,20 @@ evt_dump_producer_type(struct evt_options *opt)
>   	case EVT_PROD_TYPE_ETH_RX_ADPTR:
>   		snprintf(name, EVT_PROD_MAX_NAME_LEN,
>   				"Ethdev Rx Adapter producers");
> +		evt_dump("nb_ethdev", "%d", rte_eth_dev_count());
> +		break;
> +	case EVT_PROD_TYPE_EVENT_TIMER_ADPTR:
> +		snprintf(name, EVT_PROD_MAX_NAME_LEN,
> +				"Event timer adapter producer");
> +		evt_dump("nb_timer_adapters", "%d", opt->nb_timer_adptrs);
> +		evt_dump("max_tmo_nsec", "%"PRIu64"", opt->max_tmo_nsec);
> +		evt_dump("expiry_nsec", "%"PRIu64"", opt->expiry_nsec);
> +		if (opt->optm_timer_tick_nsec)
> +			evt_dump("optm_timer_tick_ns", "%"PRIu64"",
> +					opt->optm_timer_tick_nsec);
> +		else
> +			evt_dump("timer_tick_ns", "%"PRIu64"",
> +					opt->timer_tick_nsec);
>   		break;
>   	}
>   	evt_dump("prod_type", "%s", name);
> diff --git a/app/test-eventdev/test_perf_atq.c b/app/test-eventdev/test_perf_atq.c
> index b36b22a77..b3a312722 100644
> --- a/app/test-eventdev/test_perf_atq.c
> +++ b/app/test-eventdev/test_perf_atq.c
> @@ -43,15 +43,12 @@ perf_atq_worker(void *arg, const int enable_fwd_latency)
>   	while (t->done == false) {
>   		uint16_t event = rte_event_dequeue_burst(dev, port, &ev, 1, 0);
> 
> -		if (enable_fwd_latency)
> -			rte_prefetch0(ev.event_ptr);
> -
>   		if (!event) {
>   			rte_pause();
>   			continue;
>   		}
> 
> -		if (enable_fwd_latency)
> +		if (enable_fwd_latency && !prod_timer_type)
>   		/* first stage in pipeline, mark ts to compute fwd latency */
>   			atq_mark_fwd_latency(&ev);
> 
> @@ -90,7 +87,7 @@ perf_atq_worker_burst(void *arg, const int enable_fwd_latency)
>   		}
> 
>   		for (i = 0; i < nb_rx; i++) {
> -			if (enable_fwd_latency) {
> +			if (enable_fwd_latency && !prod_timer_type) {
>   				rte_prefetch0(ev[i+1].event_ptr);
>   				/* first stage in pipeline.
>   				 * mark time stamp to compute fwd latency
> @@ -163,7 +160,8 @@ perf_atq_eventdev_setup(struct evt_test *test, struct evt_options *opt)
>   	struct rte_event_dev_info dev_info;
> 
>   	nb_ports = evt_nr_active_lcores(opt->wlcores);
> -	nb_ports += opt->prod_type == EVT_PROD_TYPE_ETH_RX_ADPTR ? 0 :
> +	nb_ports += (opt->prod_type == EVT_PROD_TYPE_ETH_RX_ADPTR ||
> +			opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR) ? 0 :
>   		evt_nr_active_lcores(opt->plcores);
> 
>   	nb_queues = atq_nb_event_queues(opt);
> diff --git a/app/test-eventdev/test_perf_common.c b/app/test-eventdev/test_perf_common.c
> index 59fa0a49e..b6cc00e60 100644
> --- a/app/test-eventdev/test_perf_common.c
> +++ b/app/test-eventdev/test_perf_common.c
> @@ -72,6 +72,67 @@ perf_producer(void *arg)
>   	return 0;
>   }
> 
> +static inline int
> +perf_event_timer_producer(void *arg)
> +{
> +	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;
> +	struct rte_event_timer_adapter **adptr = t->timer_adptr;
> +	uint64_t timeout_ticks = opt->expiry_nsec / opt->timer_tick_nsec;
> +
> +	timeout_ticks = opt->optm_timer_tick_nsec ?
> +			(timeout_ticks * opt->timer_tick_nsec)
> +			/ opt->optm_timer_tick_nsec : timeout_ticks;
> +	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,
> +	};

It seems your patch introduce build regression on RHEL 7.5:
$ gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-28)

$ make -j32 install T=x86_64-native-linuxapp-gcc DESTDIR=legacy_destdir

== Build app/test-eventdev
   CC test_perf_common.o
/tmp/dpdk_build/app/test-eventdev/test_perf_common.c: In function 
‘perf_event_timer_producer’:
/tmp/dpdk_build/app/test-eventdev/test_perf_common.c:99:3: error: 
missing initializer for field ‘priority’ of ‘struct <anonymous>’ 
[-Werror=missing-field-initializers]
    .ev.sched_type = t->opt->sched_type_list[0],
    ^
In file included from 
/tmp/dpdk_build/app/test-eventdev/test_perf_common.h:14:0,
                  from 
/tmp/dpdk_build/app/test-eventdev/test_perf_common.c:5:
/tmp/dpdk_build/x86_64-native-linuxapp-gcc/include/rte_eventdev.h:1049:12: 
note: ‘priority’ declared here
     uint8_t priority;
             ^
/tmp/dpdk_build/app/test-eventdev/test_perf_common.c:100:3: error: 
missing initializer for field ‘priority’ of ‘struct <anonymous>’ 
[-Werror=missing-field-initializers]
    .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
    ^
In file included from 
/tmp/dpdk_build/app/test-eventdev/test_perf_common.h:14:0,
                  from 
/tmp/dpdk_build/app/test-eventdev/test_perf_common.c:5:
/tmp/dpdk_build/x86_64-native-linuxapp-gcc/include/rte_eventdev.h:1049:12: 
note: ‘priority’ declared here
     uint8_t priority;
             ^
/tmp/dpdk_build/app/test-eventdev/test_perf_common.c:101:3: error: 
missing initializer for field ‘impl_opaque’ of ‘struct <anonymous>’ 
[-Werror=missing-field-initializers]
    .ev.event_type =  RTE_EVENT_TYPE_TIMER,
    ^
In file included from 
/tmp/dpdk_build/app/test-eventdev/test_perf_common.h:14:0,
                  from 
/tmp/dpdk_build/app/test-eventdev/test_perf_common.c:5:
/tmp/dpdk_build/x86_64-native-linuxapp-gcc/include/rte_eventdev.h:1059:12: 
note: ‘impl_opaque’ declared here
     uint8_t impl_opaque;
             ^
/tmp/dpdk_build/app/test-eventdev/test_perf_common.c:102:3: error: 
missing initializer for field ‘impl_opaque’ of ‘struct <anonymous>’ 
[-Werror=missing-field-initializers]
    .state = RTE_EVENT_TIMER_NOT_ARMED,
    ^
In file included from 
/tmp/dpdk_build/app/test-eventdev/test_perf_common.h:14:0,
                  from 
/tmp/dpdk_build/app/test-eventdev/test_perf_common.c:5:
/tmp/dpdk_build/x86_64-native-linuxapp-gcc/include/rte_eventdev.h:1059:12: 
note: ‘impl_opaque’ declared here
     uint8_t impl_opaque;
             ^
/tmp/dpdk_build/app/test-eventdev/test_perf_common.c: In function 
‘perf_event_timer_producer_burst’:
/tmp/dpdk_build/app/test-eventdev/test_perf_common.c:161:3: error: 
missing initializer for field ‘priority’ of ‘struct <anonymous>’ 
[-Werror=missing-field-initializers]
    .ev.sched_type = t->opt->sched_type_list[0],
    ^
In file included from 
/tmp/dpdk_build/app/test-eventdev/test_perf_common.h:14:0,
                  from 
/tmp/dpdk_build/app/test-eventdev/test_perf_common.c:5:
/tmp/dpdk_build/x86_64-native-linuxapp-gcc/include/rte_eventdev.h:1049:12: 
note: ‘priority’ declared here
     uint8_t priority;
             ^
/tmp/dpdk_build/app/test-eventdev/test_perf_common.c:162:3: error: 
missing initializer for field ‘priority’ of ‘struct <anonymous>’ 
[-Werror=missing-field-initializers]
    .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
    ^
In file included from 
/tmp/dpdk_build/app/test-eventdev/test_perf_common.h:14:0,
                  from 
/tmp/dpdk_build/app/test-eventdev/test_perf_common.c:5:
/tmp/dpdk_build/x86_64-native-linuxapp-gcc/include/rte_eventdev.h:1049:12: 
note: ‘priority’ declared here
     uint8_t priority;
             ^
/tmp/dpdk_build/app/test-eventdev/test_perf_common.c:163:3: error: 
missing initializer for field ‘impl_opaque’ of ‘struct <anonymous>’ 
[-Werror=missing-field-initializers]
    .ev.event_type =  RTE_EVENT_TYPE_TIMER,
    ^
In file included from 
/tmp/dpdk_build/app/test-eventdev/test_perf_common.h:14:0,
                  from 
/tmp/dpdk_build/app/test-eventdev/test_perf_common.c:5:
/tmp/dpdk_build/x86_64-native-linuxapp-gcc/include/rte_eventdev.h:1059:12: 
note: ‘impl_opaque’ declared here
     uint8_t impl_opaque;
             ^
/tmp/dpdk_build/app/test-eventdev/test_perf_common.c:164:3: error: 
missing initializer for field ‘impl_opaque’ of ‘struct <anonymous>’ 
[-Werror=missing-field-initializers]
    .state = RTE_EVENT_TIMER_NOT_ARMED,
    ^
In file included from 
/tmp/dpdk_build/app/test-eventdev/test_perf_common.h:14:0,
                  from 
/tmp/dpdk_build/app/test-eventdev/test_perf_common.c:5:
/tmp/dpdk_build/x86_64-native-linuxapp-gcc/include/rte_eventdev.h:1059:12: 
note: ‘impl_opaque’ declared here
     uint8_t impl_opaque;
             ^
cc1: all warnings being treated as errors
make[5]: *** [test_perf_common.o] Error 1
make[4]: *** [test-eventdev] Error 2
make[3]: *** [app] Error 2
make[2]: *** [all] Error 2
make[1]: *** [pre_install] Error 2
make: *** [install] Error 2

Regards,
Maxime

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [dpdk-dev] [PATCH v5 1/4] app/eventdev: add event timer adapter as a producer
  2018-04-17  8:18   ` Maxime Coquelin
@ 2018-04-17  8:22     ` Pavan Nikhilesh
  2018-04-17  8:24       ` Maxime Coquelin
  0 siblings, 1 reply; 36+ messages in thread
From: Pavan Nikhilesh @ 2018-04-17  8:22 UTC (permalink / raw)
  To: Maxime Coquelin, jerin.jacob, santosh.shukla, erik.g.carrillo; +Cc: dev


> It seems your patch introduce build regression on RHEL 7.5:
> $ gcc --version
> gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-28)
>
> $ make -j32 install T=x86_64-native-linuxapp-gcc DESTDIR=legacy_destdir
>
> == Build app/test-eventdev
>   CC test_perf_common.o
> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c: In function
> ‘perf_event_timer_producer’:
> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:99:3: error: missing
> initializer for field ‘priority’ of ‘struct <anonymous>’
> [-Werror=missing-field-initializers]
>    .ev.sched_type = t->opt->sched_type_list[0],
>    ^
> In file included from
> /tmp/dpdk_build/app/test-eventdev/test_perf_common.h:14:0,
>                  from
> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:5:
> /tmp/dpdk_build/x86_64-native-linuxapp-gcc/include/rte_eventdev.h:1049:12:
> note: ‘priority’ declared here
>     uint8_t priority;
>             ^
> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:100:3: error: missing
> initializer for field ‘priority’ of ‘struct <anonymous>’
> [-Werror=missing-field-initializers]
>    .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
>    ^
> In file included from
> /tmp/dpdk_build/app/test-eventdev/test_perf_common.h:14:0,
>                  from
> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:5:
> /tmp/dpdk_build/x86_64-native-linuxapp-gcc/include/rte_eventdev.h:1049:12:
> note: ‘priority’ declared here
>     uint8_t priority;
>             ^
> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:101:3: error: missing
> initializer for field ‘impl_opaque’ of ‘struct <anonymous>’
> [-Werror=missing-field-initializers]
>    .ev.event_type =  RTE_EVENT_TYPE_TIMER,
>    ^
> In file included from
> /tmp/dpdk_build/app/test-eventdev/test_perf_common.h:14:0,
>                  from
> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:5:
> /tmp/dpdk_build/x86_64-native-linuxapp-gcc/include/rte_eventdev.h:1059:12:
> note: ‘impl_opaque’ declared here
>     uint8_t impl_opaque;
>             ^
> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:102:3: error: missing
> initializer for field ‘impl_opaque’ of ‘struct <anonymous>’
> [-Werror=missing-field-initializers]
>    .state = RTE_EVENT_TIMER_NOT_ARMED,
>    ^
> In file included from
> /tmp/dpdk_build/app/test-eventdev/test_perf_common.h:14:0,
>                  from
> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:5:
> /tmp/dpdk_build/x86_64-native-linuxapp-gcc/include/rte_eventdev.h:1059:12:
> note: ‘impl_opaque’ declared here
>     uint8_t impl_opaque;
>             ^
> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c: In function
> ‘perf_event_timer_producer_burst’:
> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:161:3: error: missing
> initializer for field ‘priority’ of ‘struct <anonymous>’
> [-Werror=missing-field-initializers]
>    .ev.sched_type = t->opt->sched_type_list[0],
>    ^
> In file included from
> /tmp/dpdk_build/app/test-eventdev/test_perf_common.h:14:0,
>                  from
> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:5:
> /tmp/dpdk_build/x86_64-native-linuxapp-gcc/include/rte_eventdev.h:1049:12:
> note: ‘priority’ declared here
>     uint8_t priority;
>             ^
> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:162:3: error: missing
> initializer for field ‘priority’ of ‘struct <anonymous>’
> [-Werror=missing-field-initializers]
>    .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
>    ^
> In file included from
> /tmp/dpdk_build/app/test-eventdev/test_perf_common.h:14:0,
>                  from
> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:5:
> /tmp/dpdk_build/x86_64-native-linuxapp-gcc/include/rte_eventdev.h:1049:12:
> note: ‘priority’ declared here
>     uint8_t priority;
>             ^
> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:163:3: error: missing
> initializer for field ‘impl_opaque’ of ‘struct <anonymous>’
> [-Werror=missing-field-initializers]
>    .ev.event_type =  RTE_EVENT_TYPE_TIMER,
>    ^
> In file included from
> /tmp/dpdk_build/app/test-eventdev/test_perf_common.h:14:0,
>                  from
> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:5:
> /tmp/dpdk_build/x86_64-native-linuxapp-gcc/include/rte_eventdev.h:1059:12:
> note: ‘impl_opaque’ declared here
>     uint8_t impl_opaque;
>             ^
> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:164:3: error: missing
> initializer for field ‘impl_opaque’ of ‘struct <anonymous>’
> [-Werror=missing-field-initializers]
>    .state = RTE_EVENT_TIMER_NOT_ARMED,
>    ^
> In file included from
> /tmp/dpdk_build/app/test-eventdev/test_perf_common.h:14:0,
>                  from
> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:5:
> /tmp/dpdk_build/x86_64-native-linuxapp-gcc/include/rte_eventdev.h:1059:12:
> note: ‘impl_opaque’ declared here
>     uint8_t impl_opaque;
>             ^
> cc1: all warnings being treated as errors
> make[5]: *** [test_perf_common.o] Error 1
> make[4]: *** [test-eventdev] Error 2
> make[3]: *** [app] Error 2
> make[2]: *** [all] Error 2
> make[1]: *** [pre_install] Error 2
> make: *** [install] Error 2
Hi Maxime,

This is already fixed on the HEAD.
Please refer to
http://dpdk.org/dev/patchwork/patch/38189/


>
> Regards,
> Maxime

Thanks,
Pavan.

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [dpdk-dev] [PATCH v5 1/4] app/eventdev: add event timer adapter as a producer
  2018-04-17  8:22     ` Pavan Nikhilesh
@ 2018-04-17  8:24       ` Maxime Coquelin
  0 siblings, 0 replies; 36+ messages in thread
From: Maxime Coquelin @ 2018-04-17  8:24 UTC (permalink / raw)
  To: Pavan Nikhilesh, jerin.jacob, santosh.shukla, erik.g.carrillo; +Cc: dev



On 04/17/2018 10:22 AM, Pavan Nikhilesh wrote:
> 
>> It seems your patch introduce build regression on RHEL 7.5:
>> $ gcc --version
>> gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-28)
>>
>> $ make -j32 install T=x86_64-native-linuxapp-gcc DESTDIR=legacy_destdir
>>
>> == Build app/test-eventdev
>>    CC test_perf_common.o
>> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c: In function
>> ‘perf_event_timer_producer’:
>> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:99:3: error: missing
>> initializer for field ‘priority’ of ‘struct <anonymous>’
>> [-Werror=missing-field-initializers]
>>     .ev.sched_type = t->opt->sched_type_list[0],
>>     ^
>> In file included from
>> /tmp/dpdk_build/app/test-eventdev/test_perf_common.h:14:0,
>>                   from
>> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:5:
>> /tmp/dpdk_build/x86_64-native-linuxapp-gcc/include/rte_eventdev.h:1049:12:
>> note: ‘priority’ declared here
>>      uint8_t priority;
>>              ^
>> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:100:3: error: missing
>> initializer for field ‘priority’ of ‘struct <anonymous>’
>> [-Werror=missing-field-initializers]
>>     .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
>>     ^
>> In file included from
>> /tmp/dpdk_build/app/test-eventdev/test_perf_common.h:14:0,
>>                   from
>> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:5:
>> /tmp/dpdk_build/x86_64-native-linuxapp-gcc/include/rte_eventdev.h:1049:12:
>> note: ‘priority’ declared here
>>      uint8_t priority;
>>              ^
>> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:101:3: error: missing
>> initializer for field ‘impl_opaque’ of ‘struct <anonymous>’
>> [-Werror=missing-field-initializers]
>>     .ev.event_type =  RTE_EVENT_TYPE_TIMER,
>>     ^
>> In file included from
>> /tmp/dpdk_build/app/test-eventdev/test_perf_common.h:14:0,
>>                   from
>> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:5:
>> /tmp/dpdk_build/x86_64-native-linuxapp-gcc/include/rte_eventdev.h:1059:12:
>> note: ‘impl_opaque’ declared here
>>      uint8_t impl_opaque;
>>              ^
>> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:102:3: error: missing
>> initializer for field ‘impl_opaque’ of ‘struct <anonymous>’
>> [-Werror=missing-field-initializers]
>>     .state = RTE_EVENT_TIMER_NOT_ARMED,
>>     ^
>> In file included from
>> /tmp/dpdk_build/app/test-eventdev/test_perf_common.h:14:0,
>>                   from
>> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:5:
>> /tmp/dpdk_build/x86_64-native-linuxapp-gcc/include/rte_eventdev.h:1059:12:
>> note: ‘impl_opaque’ declared here
>>      uint8_t impl_opaque;
>>              ^
>> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c: In function
>> ‘perf_event_timer_producer_burst’:
>> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:161:3: error: missing
>> initializer for field ‘priority’ of ‘struct <anonymous>’
>> [-Werror=missing-field-initializers]
>>     .ev.sched_type = t->opt->sched_type_list[0],
>>     ^
>> In file included from
>> /tmp/dpdk_build/app/test-eventdev/test_perf_common.h:14:0,
>>                   from
>> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:5:
>> /tmp/dpdk_build/x86_64-native-linuxapp-gcc/include/rte_eventdev.h:1049:12:
>> note: ‘priority’ declared here
>>      uint8_t priority;
>>              ^
>> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:162:3: error: missing
>> initializer for field ‘priority’ of ‘struct <anonymous>’
>> [-Werror=missing-field-initializers]
>>     .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
>>     ^
>> In file included from
>> /tmp/dpdk_build/app/test-eventdev/test_perf_common.h:14:0,
>>                   from
>> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:5:
>> /tmp/dpdk_build/x86_64-native-linuxapp-gcc/include/rte_eventdev.h:1049:12:
>> note: ‘priority’ declared here
>>      uint8_t priority;
>>              ^
>> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:163:3: error: missing
>> initializer for field ‘impl_opaque’ of ‘struct <anonymous>’
>> [-Werror=missing-field-initializers]
>>     .ev.event_type =  RTE_EVENT_TYPE_TIMER,
>>     ^
>> In file included from
>> /tmp/dpdk_build/app/test-eventdev/test_perf_common.h:14:0,
>>                   from
>> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:5:
>> /tmp/dpdk_build/x86_64-native-linuxapp-gcc/include/rte_eventdev.h:1059:12:
>> note: ‘impl_opaque’ declared here
>>      uint8_t impl_opaque;
>>              ^
>> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:164:3: error: missing
>> initializer for field ‘impl_opaque’ of ‘struct <anonymous>’
>> [-Werror=missing-field-initializers]
>>     .state = RTE_EVENT_TIMER_NOT_ARMED,
>>     ^
>> In file included from
>> /tmp/dpdk_build/app/test-eventdev/test_perf_common.h:14:0,
>>                   from
>> /tmp/dpdk_build/app/test-eventdev/test_perf_common.c:5:
>> /tmp/dpdk_build/x86_64-native-linuxapp-gcc/include/rte_eventdev.h:1059:12:
>> note: ‘impl_opaque’ declared here
>>      uint8_t impl_opaque;
>>              ^
>> cc1: all warnings being treated as errors
>> make[5]: *** [test_perf_common.o] Error 1
>> make[4]: *** [test-eventdev] Error 2
>> make[3]: *** [app] Error 2
>> make[2]: *** [all] Error 2
>> make[1]: *** [pre_install] Error 2
>> make: *** [install] Error 2
> Hi Maxime,
> 
> This is already fixed on the HEAD.
> Please refer to
> http://dpdk.org/dev/patchwork/patch/38189/

Thanks for the quick reply, I tested with net-next,
so the patch didn't land into it yet.

Regards,
Maxime

> 
>>
>> Regards,
>> Maxime
> 
> Thanks,
> Pavan.
> 

^ permalink raw reply	[flat|nested] 36+ messages in thread

end of thread, other threads:[~2018-04-17  8:24 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-18 13:12 [dpdk-dev] [PATCH 1/4] app/eventdev: add event timer adapter as a producer Pavan Nikhilesh
2018-03-18 13:12 ` [dpdk-dev] [PATCH 2/4] app/eventdev: add burst mode for event timer adapter Pavan Nikhilesh
2018-03-30 19:54   ` Carrillo, Erik G
2018-03-18 13:12 ` [dpdk-dev] [PATCH 3/4] app/eventdev: add options to configure " Pavan Nikhilesh
2018-03-18 13:12 ` [dpdk-dev] [PATCH 4/4] doc: update test eventdev documentation Pavan Nikhilesh
2018-03-30 19:50 ` [dpdk-dev] [PATCH 1/4] app/eventdev: add event timer adapter as a producer Carrillo, Erik G
2018-04-03 16:01 ` [dpdk-dev] [PATCH v2 " Pavan Nikhilesh
2018-04-03 16:01   ` [dpdk-dev] [PATCH v2 2/4] app/eventdev: add burst mode for event timer adapter Pavan Nikhilesh
2018-04-04 21:07     ` Carrillo, Erik G
2018-04-03 16:01   ` [dpdk-dev] [PATCH v2 3/4] app/eventdev: add options to configure " Pavan Nikhilesh
2018-04-04 21:10     ` Carrillo, Erik G
2018-04-03 16:01   ` [dpdk-dev] [PATCH v2 4/4] doc: update test eventdev documentation Pavan Nikhilesh
2018-04-04 21:16     ` Carrillo, Erik G
2018-04-03 20:21   ` [dpdk-dev] [PATCH v2 1/4] app/eventdev: add event timer adapter as a producer Carrillo, Erik G
2018-04-04 21:20     ` Carrillo, Erik G
2018-04-05 11:53 ` [dpdk-dev] [PATCH v3 " Pavan Nikhilesh
2018-04-05 11:53   ` [dpdk-dev] [PATCH v3 2/4] app/eventdev: add burst mode for event timer adapter Pavan Nikhilesh
2018-04-06 11:11     ` Jerin Jacob
2018-04-05 11:53   ` [dpdk-dev] [PATCH v3 3/4] app/eventdev: add options to configure " Pavan Nikhilesh
2018-04-06 11:15     ` Jerin Jacob
2018-04-05 11:53   ` [dpdk-dev] [PATCH v3 4/4] doc: update test eventdev documentation Pavan Nikhilesh
2018-04-06 11:37     ` Jerin Jacob
2018-04-06 11:07   ` [dpdk-dev] [PATCH v3 1/4] app/eventdev: add event timer adapter as a producer Jerin Jacob
2018-04-06 11:18   ` Jerin Jacob
2018-04-06 14:55 ` [dpdk-dev] [PATCH v4 " Pavan Nikhilesh
2018-04-06 14:55   ` [dpdk-dev] [PATCH v4 2/4] app/eventdev: add burst mode for event timer adapter Pavan Nikhilesh
2018-04-06 14:55   ` [dpdk-dev] [PATCH v4 3/4] app/eventdev: add options to configure " Pavan Nikhilesh
2018-04-06 14:55   ` [dpdk-dev] [PATCH v4 4/4] doc: update test eventdev documentation Pavan Nikhilesh
2018-04-06 15:13 ` [dpdk-dev] [PATCH v5 1/4] app/eventdev: add event timer adapter as a producer Pavan Nikhilesh
2018-04-06 15:13   ` [dpdk-dev] [PATCH v5 2/4] app/eventdev: add burst mode for event timer adapter Pavan Nikhilesh
2018-04-06 15:13   ` [dpdk-dev] [PATCH v5 3/4] app/eventdev: add options to configure " Pavan Nikhilesh
2018-04-06 15:13   ` [dpdk-dev] [PATCH v5 4/4] doc: update test eventdev documentation Pavan Nikhilesh
2018-04-07  9:34   ` [dpdk-dev] [PATCH v5 1/4] app/eventdev: add event timer adapter as a producer Jerin Jacob
2018-04-17  8:18   ` Maxime Coquelin
2018-04-17  8:22     ` Pavan Nikhilesh
2018-04-17  8:24       ` Maxime Coquelin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).