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

Maxime Coquelin maxime.coquelin at redhat.com
Tue Apr 17 10:18:55 CEST 2018



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 at caviumnetworks.com>
> Acked-by: Erik Gabriel Carrillo <erik.g.carrillo at intel.com>
> Acked-by: Jerin Jacob <jerin.jacob at 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


More information about the dev mailing list