[dpdk-dev,v5,1/4] app/eventdev: add event timer adapter as a producer

Message ID 20180406151324.9135-1-pbhagavatula@caviumnetworks.com (mailing list archive)
State Accepted, archived
Delegated to: Jerin Jacob
Headers

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation fail apply issues

Commit Message

Pavan Nikhilesh April 6, 2018, 3:13 p.m. UTC
  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(-)

--
2.17.0
  

Comments

Jerin Jacob April 7, 2018, 9:34 a.m. UTC | #1
-----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.
  
Maxime Coquelin April 17, 2018, 8:18 a.m. UTC | #2
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
  
Pavan Nikhilesh April 17, 2018, 8:22 a.m. UTC | #3
> 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.
  
Maxime Coquelin April 17, 2018, 8:24 a.m. UTC | #4
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.
>
  

Patch

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);