[dpdk-dev,v5,1/4] app/eventdev: add event timer adapter as a producer
Checks
Commit Message
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
-----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.
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
> 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.
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.
>
@@ -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);
@@ -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);
@@ -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);
@@ -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;
@@ -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;\
@@ -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);