From: <pbhagavatula@marvell.com>
To: <jerinj@marvell.com>, <pravin.pathak@intel.com>,
<hemant.agrawal@nxp.com>, <sachin.saxena@nxp.com>,
<mattias.ronnblom@ericsson.com>, <liangma@liangbit.com>,
<peter.mccarthy@intel.com>, <harry.van.haaren@intel.com>,
<erik.g.carrillo@intel.com>, <abhinandan.gujjar@intel.com>,
<amitprakashs@marvell.com>, <s.v.naga.harish.k@intel.com>,
<anatoly.burakov@intel.com>
Cc: <dev@dpdk.org>, Pavan Nikhilesh <pbhagavatula@marvell.com>
Subject: [PATCH 3/3] app/eventdev: add vector adapter performance test
Date: Thu, 10 Apr 2025 23:30:41 +0530 [thread overview]
Message-ID: <20250410180056.10368-4-pbhagavatula@marvell.com> (raw)
In-Reply-To: <20250410180056.10368-1-pbhagavatula@marvell.com>
From: Pavan Nikhilesh <pbhagavatula@marvell.com>
Add performance test for event vector adapter.
Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
---
app/test-eventdev/evt_common.h | 9 +-
app/test-eventdev/evt_options.c | 14 ++
app/test-eventdev/evt_options.h | 1 +
app/test-eventdev/test_perf_atq.c | 61 +++++-
app/test-eventdev/test_perf_common.c | 281 ++++++++++++++++++-------
app/test-eventdev/test_perf_common.h | 13 +-
app/test-eventdev/test_perf_queue.c | 66 +++++-
doc/guides/rel_notes/release_25_07.rst | 5 +
doc/guides/tools/testeventdev.rst | 6 +
9 files changed, 362 insertions(+), 94 deletions(-)
diff --git a/app/test-eventdev/evt_common.h b/app/test-eventdev/evt_common.h
index 74f9d187f3..ec824f2454 100644
--- a/app/test-eventdev/evt_common.h
+++ b/app/test-eventdev/evt_common.h
@@ -39,11 +39,12 @@
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_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_EVENT_CRYPTO_ADPTR, /* Producer type Crypto Adapter. */
- EVT_PROD_TYPE_EVENT_DMA_ADPTR, /* Producer type DMA Adapter. */
+ EVT_PROD_TYPE_EVENT_CRYPTO_ADPTR, /* Producer type Crypto Adapter. */
+ EVT_PROD_TYPE_EVENT_DMA_ADPTR, /* Producer type DMA Adapter. */
+ EVT_PROD_TYPE_EVENT_VECTOR_ADPTR, /* Producer type Vector adapter. */
EVT_PROD_TYPE_MAX,
};
diff --git a/app/test-eventdev/evt_options.c b/app/test-eventdev/evt_options.c
index 323d1e724d..0e70c971eb 100644
--- a/app/test-eventdev/evt_options.c
+++ b/app/test-eventdev/evt_options.c
@@ -186,6 +186,13 @@ evt_parse_dma_adptr_mode(struct evt_options *opt, const char *arg)
return ret;
}
+static int
+evt_parse_vector_prod_type(struct evt_options *opt,
+ const char *arg __rte_unused)
+{
+ opt->prod_type = EVT_PROD_TYPE_EVENT_VECTOR_ADPTR;
+ return 0;
+}
static int
evt_parse_crypto_prod_type(struct evt_options *opt,
@@ -494,6 +501,7 @@ usage(char *program)
"\t in ns.\n"
"\t--prod_type_timerdev_burst : use timer device as producer\n"
"\t burst mode.\n"
+ "\t--prod_type_vector : use vector adapter as producer.\n"
"\t--nb_timers : number of timers to arm.\n"
"\t--nb_timer_adptrs : number of timer adapters to use.\n"
"\t--timer_tick_nsec : timer tick interval in ns.\n"
@@ -591,6 +599,7 @@ static struct option lgopts[] = {
{ EVT_PROD_CRYPTODEV, 0, 0, 0 },
{ EVT_PROD_TIMERDEV, 0, 0, 0 },
{ EVT_PROD_TIMERDEV_BURST, 0, 0, 0 },
+ { EVT_PROD_VECTOR, 0, 0, 0 },
{ EVT_DMA_ADPTR_MODE, 1, 0, 0 },
{ EVT_CRYPTO_ADPTR_MODE, 1, 0, 0 },
{ EVT_CRYPTO_OP_TYPE, 1, 0, 0 },
@@ -642,6 +651,7 @@ evt_opts_parse_long(int opt_idx, struct evt_options *opt)
{ EVT_PROD_DMADEV, evt_parse_dma_prod_type},
{ EVT_PROD_TIMERDEV, evt_parse_timer_prod_type},
{ EVT_PROD_TIMERDEV_BURST, evt_parse_timer_prod_type_burst},
+ { EVT_PROD_VECTOR, evt_parse_vector_prod_type },
{ EVT_DMA_ADPTR_MODE, evt_parse_dma_adptr_mode},
{ EVT_CRYPTO_ADPTR_MODE, evt_parse_crypto_adptr_mode},
{ EVT_CRYPTO_OP_TYPE, evt_parse_crypto_op_type},
@@ -721,4 +731,8 @@ evt_options_dump(struct evt_options *opt)
evt_dump_end;
evt_dump_nb_flows(opt);
evt_dump_worker_dequeue_depth(opt);
+ if (opt->ena_vector || opt->prod_type == EVT_PROD_TYPE_EVENT_VECTOR_ADPTR) {
+ evt_dump("vector_sz", "%d", opt->vector_size);
+ evt_dump("vector_tmo_ns", "%"PRIu64, opt->vector_tmo_nsec);
+ }
}
diff --git a/app/test-eventdev/evt_options.h b/app/test-eventdev/evt_options.h
index 18a893b704..4bf712bd19 100644
--- a/app/test-eventdev/evt_options.h
+++ b/app/test-eventdev/evt_options.h
@@ -38,6 +38,7 @@
#define EVT_PROD_DMADEV ("prod_type_dmadev")
#define EVT_PROD_TIMERDEV ("prod_type_timerdev")
#define EVT_PROD_TIMERDEV_BURST ("prod_type_timerdev_burst")
+#define EVT_PROD_VECTOR ("prod_type_vector")
#define EVT_DMA_ADPTR_MODE ("dma_adptr_mode")
#define EVT_CRYPTO_ADPTR_MODE ("crypto_adptr_mode")
#define EVT_CRYPTO_OP_TYPE ("crypto_op_type")
diff --git a/app/test-eventdev/test_perf_atq.c b/app/test-eventdev/test_perf_atq.c
index 30c34edabd..b07b010af1 100644
--- a/app/test-eventdev/test_perf_atq.c
+++ b/app/test-eventdev/test_perf_atq.c
@@ -145,7 +145,7 @@ perf_atq_worker_burst(void *arg, const int enable_fwd_latency)
}
static int
-perf_atq_worker_vector(void *arg, const int enable_fwd_latency)
+perf_atq_worker_crypto_vector(void *arg, const int enable_fwd_latency)
{
uint16_t enq = 0, deq = 0;
struct rte_event ev;
@@ -161,10 +161,8 @@ perf_atq_worker_vector(void *arg, const int enable_fwd_latency)
if (!deq)
continue;
- if (ev.event_type == RTE_EVENT_TYPE_CRYPTODEV_VECTOR) {
- if (perf_handle_crypto_vector_ev(&ev, &pe, enable_fwd_latency))
- continue;
- }
+ if (perf_handle_crypto_vector_ev(&ev, &pe, enable_fwd_latency))
+ continue;
stage = ev.sub_event_type % nb_stages;
/* First q in pipeline, mark timestamp to compute fwd latency */
@@ -173,8 +171,8 @@ perf_atq_worker_vector(void *arg, const int enable_fwd_latency)
/* Last stage in pipeline */
if (unlikely(stage == laststage)) {
- perf_process_vector_last_stage(pool, t->ca_op_pool, &ev, w,
- enable_fwd_latency);
+ perf_process_crypto_vector_last_stage(pool, t->ca_op_pool, &ev, w,
+ enable_fwd_latency);
} else {
atq_fwd_event_vector(&ev, sched_type_list, nb_stages);
do {
@@ -188,6 +186,53 @@ perf_atq_worker_vector(void *arg, const int enable_fwd_latency)
return 0;
}
+static int
+perf_atq_worker_vector(void *arg, const int enable_fwd_latency)
+{
+ uint16_t enq = 0, deq = 0;
+ struct rte_event ev;
+ PERF_WORKER_INIT;
+
+ RTE_SET_USED(sz);
+ RTE_SET_USED(pe);
+ RTE_SET_USED(cnt);
+ RTE_SET_USED(prod_type);
+ RTE_SET_USED(prod_timer_type);
+
+ while (t->done == false) {
+ deq = rte_event_dequeue_burst(dev, port, &ev, 1, 0);
+ if (!deq)
+ continue;
+
+ if (ev.event_type != RTE_EVENT_TYPE_CPU_VECTOR) {
+ w->processed_pkts++;
+ continue;
+ }
+
+ stage = ev.sub_event_type % nb_stages;
+ if (enable_fwd_latency && stage == 0)
+ /* first stage in pipeline, mark ts to compute fwd latency */
+ ev.vec->u64s[0] = rte_get_timer_cycles();
+
+ /* Last stage in pipeline */
+ if (unlikely(stage == laststage)) {
+ w->processed_vecs++;
+ if (enable_fwd_latency)
+ w->latency += rte_get_timer_cycles() - ev.vec->u64s[0];
+
+ rte_mempool_put(pool, ev.event_ptr);
+ } else {
+ atq_fwd_event_vector(&ev, sched_type_list, nb_stages);
+ do {
+ enq = rte_event_enqueue_burst(dev, port, &ev, 1);
+ } while (!enq && !t->done);
+ }
+ }
+ perf_worker_cleanup(pool, dev, port, &ev, enq, deq);
+
+ return 0;
+}
+
static int
worker_wrapper(void *arg)
{
@@ -199,6 +244,8 @@ worker_wrapper(void *arg)
/* allow compiler to optimize */
if (opt->ena_vector && opt->prod_type == EVT_PROD_TYPE_EVENT_CRYPTO_ADPTR)
+ return perf_atq_worker_crypto_vector(arg, fwd_latency);
+ else if (opt->prod_type == EVT_PROD_TYPE_EVENT_VECTOR_ADPTR)
return perf_atq_worker_vector(arg, fwd_latency);
else if (!burst && !fwd_latency)
return perf_atq_worker(arg, 0);
diff --git a/app/test-eventdev/test_perf_common.c b/app/test-eventdev/test_perf_common.c
index 627f07caa1..4709de8b07 100644
--- a/app/test-eventdev/test_perf_common.c
+++ b/app/test-eventdev/test_perf_common.c
@@ -102,16 +102,20 @@ perf_test_result(struct evt_test *test, struct evt_options *opt)
int i;
uint64_t total = 0;
struct test_perf *t = evt_test_priv(test);
+ uint8_t is_vec;
printf("Packet distribution across worker cores :\n");
+ is_vec = (opt->prod_type == EVT_PROD_TYPE_EVENT_VECTOR_ADPTR);
for (i = 0; i < t->nb_workers; i++)
- total += t->worker[i].processed_pkts;
+ total += is_vec ? t->worker[i].processed_vecs : t->worker[i].processed_pkts;
for (i = 0; i < t->nb_workers; i++)
- printf("Worker %d packets: "CLGRN"%"PRIx64" "CLNRM"percentage:"
- CLGRN" %3.2f"CLNRM"\n", i,
- t->worker[i].processed_pkts,
- (((double)t->worker[i].processed_pkts)/total)
- * 100);
+ printf("Worker %d packets: " CLGRN "%" PRIx64 " " CLNRM "percentage:" CLGRN
+ " %3.2f" CLNRM "\n",
+ i, is_vec ? t->worker[i].processed_vecs : t->worker[i].processed_pkts,
+ (((double)(is_vec ? t->worker[i].processed_vecs :
+ t->worker[i].processed_pkts)) /
+ total) *
+ 100);
return t->result;
}
@@ -887,6 +891,31 @@ perf_event_crypto_producer_burst(void *arg)
return 0;
}
+static int
+perf_event_vector_producer(struct prod_data *p)
+{
+ struct rte_event_vector_adapter *adptr = p->va.vector_adptr;
+ struct evt_options *opt = p->t->opt;
+ const struct test_perf *t = p->t;
+ uint64_t objs[BURST_SIZE];
+ uint16_t enq;
+
+ if (opt->verbose_level > 1)
+ printf("%s(): lcore %d vector adapter %p\n", __func__, rte_lcore_id(), adptr);
+
+ while (t->done == false) {
+ enq = rte_event_vector_adapter_enqueue(adptr, objs, BURST_SIZE, 0);
+ while (enq < BURST_SIZE) {
+ enq += rte_event_vector_adapter_enqueue(adptr, objs + enq, BURST_SIZE - enq,
+ 0);
+ if (t->done)
+ break;
+ rte_pause();
+ }
+ }
+ return 0;
+}
+
static int
perf_producer_wrapper(void *arg)
{
@@ -930,6 +959,8 @@ perf_producer_wrapper(void *arg)
return perf_event_crypto_producer(arg);
} else if (t->opt->prod_type == EVT_PROD_TYPE_EVENT_DMA_ADPTR)
return perf_event_dma_producer(arg);
+ else if (t->opt->prod_type == EVT_PROD_TYPE_EVENT_VECTOR_ADPTR)
+ return perf_event_vector_producer(p);
return 0;
}
@@ -947,115 +978,103 @@ processed_pkts(struct test_perf *t)
}
static inline uint64_t
-total_latency(struct test_perf *t)
+processed_vecs(struct test_perf *t)
{
uint8_t i;
uint64_t total = 0;
for (i = 0; i < t->nb_workers; i++)
- total += t->worker[i].latency;
+ total += t->worker[i].processed_vecs;
return total;
}
-
-int
-perf_launch_lcores(struct evt_test *test, struct evt_options *opt,
- int (*worker)(void *))
+static inline uint64_t
+total_latency(struct test_perf *t)
{
- int ret, lcore_id;
- struct test_perf *t = evt_test_priv(test);
-
- int port_idx = 0;
- /* launch workers */
- RTE_LCORE_FOREACH_WORKER(lcore_id) {
- if (!(opt->wlcores[lcore_id]))
- continue;
-
- ret = rte_eal_remote_launch(worker,
- &t->worker[port_idx], lcore_id);
- if (ret) {
- evt_err("failed to launch worker %d", lcore_id);
- return ret;
- }
- port_idx++;
- }
-
- /* launch producers */
- RTE_LCORE_FOREACH_WORKER(lcore_id) {
- if (!(opt->plcores[lcore_id]))
- continue;
+ uint8_t i;
+ uint64_t total = 0;
- ret = rte_eal_remote_launch(perf_producer_wrapper,
- &t->prod[port_idx], lcore_id);
- if (ret) {
- evt_err("failed to launch perf_producer %d", lcore_id);
- return ret;
- }
- port_idx++;
- }
+ for (i = 0; i < t->nb_workers; i++)
+ total += t->worker[i].latency;
- const uint64_t total_pkts = t->outstand_pkts;
+ return total;
+}
- uint64_t dead_lock_cycles = rte_get_timer_cycles();
- int64_t dead_lock_remaining = total_pkts;
+static void
+check_work_status(struct test_perf *t, struct evt_options *opt)
+{
const uint64_t dead_lock_sample = rte_get_timer_hz() * 5;
-
+ const uint64_t freq_mhz = rte_get_timer_hz() / 1000000;
+ uint64_t dead_lock_cycles = rte_get_timer_cycles();
+ const uint64_t perf_sample = rte_get_timer_hz();
uint64_t perf_cycles = rte_get_timer_cycles();
+ const uint64_t total_pkts = t->outstand_pkts;
+ int64_t dead_lock_remaining = total_pkts;
int64_t perf_remaining = total_pkts;
- const uint64_t perf_sample = rte_get_timer_hz();
-
- static float total_mpps;
static uint64_t samples;
+ static float total_mpps;
+ int64_t remaining;
+ uint8_t is_vec;
- const uint64_t freq_mhz = rte_get_timer_hz() / 1000000;
- int64_t remaining = t->outstand_pkts - processed_pkts(t);
+ is_vec = (t->opt->prod_type == EVT_PROD_TYPE_EVENT_VECTOR_ADPTR);
+ remaining = t->outstand_pkts - (is_vec ? processed_vecs(t) : processed_pkts(t));
while (t->done == false) {
const uint64_t new_cycles = rte_get_timer_cycles();
if ((new_cycles - perf_cycles) > perf_sample) {
const uint64_t latency = total_latency(t);
- const uint64_t pkts = processed_pkts(t);
+ const uint64_t pkts = is_vec ? processed_vecs(t) : processed_pkts(t);
+ uint64_t fallback_pkts = processed_pkts(t);
remaining = t->outstand_pkts - pkts;
- float mpps = (float)(perf_remaining-remaining)/1000000;
+ float mpps = (float)(perf_remaining - remaining) / 1E6;
perf_remaining = remaining;
perf_cycles = new_cycles;
total_mpps += mpps;
++samples;
+
if (opt->fwd_latency && pkts > 0) {
- printf(CLGRN"\r%.3f mpps avg %.3f mpps [avg fwd latency %.3f us] "CLNRM,
- mpps, total_mpps/samples,
- (float)(latency/pkts)/freq_mhz);
+ if (is_vec) {
+ printf(CLGRN
+ "\r%.3f mvps avg %.3f mvps [avg fwd latency %.3f us] "
+ "fallback mpps %.3f" CLNRM,
+ mpps, total_mpps / samples,
+ (float)(latency / pkts) / freq_mhz,
+ fallback_pkts / 1E6);
+ } else {
+ printf(CLGRN
+ "\r%.3f mpps avg %.3f mpps [avg fwd latency %.3f us] "
+ CLNRM,
+ mpps, total_mpps / samples,
+ (float)(latency / pkts) / freq_mhz);
+ }
} else {
- printf(CLGRN"\r%.3f mpps avg %.3f mpps"CLNRM,
- mpps, total_mpps/samples);
+ if (is_vec) {
+ printf(CLGRN
+ "\r%.3f mvps avg %.3f mvps fallback mpps %.3f" CLNRM,
+ mpps, total_mpps / samples, fallback_pkts / 1E6);
+ } else {
+ printf(CLGRN "\r%.3f mpps avg %.3f mpps" CLNRM, mpps,
+ total_mpps / samples);
+ }
}
fflush(stdout);
if (remaining <= 0) {
t->result = EVT_TEST_SUCCESS;
- if (opt->prod_type == EVT_PROD_TYPE_SYNT ||
- opt->prod_type ==
- EVT_PROD_TYPE_EVENT_TIMER_ADPTR ||
- opt->prod_type ==
- EVT_PROD_TYPE_EVENT_CRYPTO_ADPTR ||
- opt->prod_type ==
- EVT_PROD_TYPE_EVENT_DMA_ADPTR) {
+ if (opt->prod_type != EVT_PROD_TYPE_ETH_RX_ADPTR) {
t->done = true;
break;
}
}
}
-
if (new_cycles - dead_lock_cycles > dead_lock_sample &&
- (opt->prod_type == EVT_PROD_TYPE_SYNT ||
- opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR ||
- opt->prod_type == EVT_PROD_TYPE_EVENT_CRYPTO_ADPTR ||
- opt->prod_type == EVT_PROD_TYPE_EVENT_DMA_ADPTR)) {
- remaining = t->outstand_pkts - processed_pkts(t);
+ (opt->prod_type != EVT_PROD_TYPE_ETH_RX_ADPTR)) {
+ remaining =
+ t->outstand_pkts - (is_vec ? processed_vecs(t) : processed_pkts(t));
if (dead_lock_remaining == remaining) {
rte_event_dev_dump(opt->dev_id, stdout);
evt_err("No schedules for seconds, deadlock");
@@ -1067,6 +1086,45 @@ perf_launch_lcores(struct evt_test *test, struct evt_options *opt,
}
}
printf("\n");
+}
+
+int
+perf_launch_lcores(struct evt_test *test, struct evt_options *opt, int (*worker)(void *))
+{
+ int ret, lcore_id;
+ struct test_perf *t = evt_test_priv(test);
+
+ int port_idx = 0;
+ /* launch workers */
+ RTE_LCORE_FOREACH_WORKER(lcore_id)
+ {
+ if (!(opt->wlcores[lcore_id]))
+ continue;
+
+ ret = rte_eal_remote_launch(worker, &t->worker[port_idx], lcore_id);
+ if (ret) {
+ evt_err("failed to launch worker %d", lcore_id);
+ return ret;
+ }
+ port_idx++;
+ }
+
+ /* launch producers */
+ RTE_LCORE_FOREACH_WORKER(lcore_id)
+ {
+ if (!(opt->plcores[lcore_id]))
+ continue;
+
+ ret = rte_eal_remote_launch(perf_producer_wrapper, &t->prod[port_idx], lcore_id);
+ if (ret) {
+ evt_err("failed to launch perf_producer %d", lcore_id);
+ return ret;
+ }
+ port_idx++;
+ }
+
+ check_work_status(t, opt);
+
return 0;
}
@@ -1564,6 +1622,70 @@ perf_event_dev_port_setup(struct evt_test *test, struct evt_options *opt,
prod++;
}
+ } else if (opt->prod_type == EVT_PROD_TYPE_EVENT_VECTOR_ADPTR) {
+ struct rte_event_vector_adapter_conf conf;
+ struct rte_event_vector_adapter_info info;
+
+ ret = rte_event_vector_adapter_info_get(opt->dev_id, &info);
+
+ if (opt->vector_size < info.min_vector_sz ||
+ opt->vector_size > info.max_vector_sz) {
+ evt_err("Vector size [%d] not within limits max[%d] min[%d]",
+ opt->vector_size, info.max_vector_sz, info.min_vector_sz);
+ return -EINVAL;
+ }
+
+ if (opt->vector_tmo_nsec > info.max_vector_timeout_ns ||
+ opt->vector_tmo_nsec < info.min_vector_timeout_ns) {
+ evt_err("Vector timeout [%" PRIu64 "] not within limits "
+ "max[%" PRIu64 "] min[%" PRIu64 "]",
+ opt->vector_tmo_nsec, info.max_vector_timeout_ns,
+ info.min_vector_timeout_ns);
+ return -EINVAL;
+ }
+
+ memset(&conf, 0, sizeof(struct rte_event_vector_adapter_conf));
+ conf.event_dev_id = opt->dev_id;
+ conf.vector_sz = opt->vector_size;
+ conf.vector_timeout_ns = opt->vector_tmo_nsec;
+ conf.socket_id = opt->socket_id;
+ conf.vector_mp = t->pool;
+
+ conf.ev.sched_type = opt->sched_type_list[0];
+ conf.ev.event_type = RTE_EVENT_TYPE_VECTOR | RTE_EVENT_TYPE_CPU;
+
+ conf.ev_fallback.event_type = RTE_EVENT_TYPE_CPU;
+
+ prod = 0;
+ for (; port < perf_nb_event_ports(opt); port++) {
+ struct rte_event_vector_adapter *vector_adptr;
+ struct prod_data *p = &t->prod[port];
+ uint32_t service_id;
+
+ p->queue_id = prod * stride;
+ p->t = t;
+
+ conf.ev.queue_id = p->queue_id;
+
+ vector_adptr = rte_event_vector_adapter_create(&conf);
+ if (vector_adptr == NULL) {
+ evt_err("Failed to create vector adapter for port %d", port);
+ return -ENOMEM;
+ }
+ p->va.vector_adptr = vector_adptr;
+ prod++;
+
+ if (rte_event_vector_adapter_service_id_get(vector_adptr, &service_id) ==
+ 0) {
+ ret = evt_service_setup(service_id);
+ if (ret) {
+ evt_err("Failed to setup service core"
+ " for vector adapter\n");
+ return ret;
+ }
+ rte_service_runstate_set(service_id, 1);
+ }
+ }
} else {
prod = 0;
for ( ; port < perf_nb_event_ports(opt); port++) {
@@ -1728,6 +1850,20 @@ perf_eventdev_destroy(struct evt_test *test, struct evt_options *opt)
for (i = 0; i < opt->nb_timer_adptrs; i++)
rte_event_timer_adapter_stop(t->timer_adptr[i]);
}
+
+ if (opt->prod_type == EVT_PROD_TYPE_EVENT_VECTOR_ADPTR) {
+ for (i = 0; i < evt_nr_active_lcores(opt->plcores); i++) {
+ struct prod_data *p = &t->prod[i];
+ uint32_t service_id;
+
+ if (p->va.vector_adptr) {
+ if (rte_event_vector_adapter_service_id_get(p->va.vector_adptr,
+ &service_id) == 0)
+ rte_service_runstate_set(service_id, 0);
+ rte_event_vector_adapter_destroy(p->va.vector_adptr);
+ }
+ }
+ }
rte_event_dev_stop(opt->dev_id);
rte_event_dev_close(opt->dev_id);
}
@@ -2119,6 +2255,9 @@ perf_mempool_setup(struct evt_test *test, struct evt_options *opt)
cache_sz, /* cache size*/
0, NULL, NULL, NULL, /* obj constructor */
NULL, opt->socket_id, 0); /* flags */
+ } else if (opt->prod_type == EVT_PROD_TYPE_EVENT_VECTOR_ADPTR) {
+ t->pool = rte_event_vector_pool_create(test->name, opt->pool_sz, cache_sz,
+ opt->vector_size, opt->socket_id);
} else {
t->pool = rte_pktmbuf_pool_create(test->name, /* mempool name */
opt->pool_sz, /* number of elements*/
diff --git a/app/test-eventdev/test_perf_common.h b/app/test-eventdev/test_perf_common.h
index d7333ad390..99df008cc7 100644
--- a/app/test-eventdev/test_perf_common.h
+++ b/app/test-eventdev/test_perf_common.h
@@ -16,6 +16,7 @@
#include <rte_event_eth_rx_adapter.h>
#include <rte_event_eth_tx_adapter.h>
#include <rte_event_timer_adapter.h>
+#include <rte_event_vector_adapter.h>
#include <rte_eventdev.h>
#include <rte_lcore.h>
#include <rte_malloc.h>
@@ -33,6 +34,7 @@ struct test_perf;
struct __rte_cache_aligned worker_data {
uint64_t processed_pkts;
+ uint64_t processed_vecs;
uint64_t latency;
uint8_t dev_id;
uint8_t port_id;
@@ -50,12 +52,17 @@ struct dma_adptr_data {
uint16_t vchan_id;
};
+struct vector_adptr_data {
+ struct rte_event_vector_adapter *vector_adptr;
+};
+
struct __rte_cache_aligned prod_data {
uint8_t dev_id;
uint8_t port_id;
uint8_t queue_id;
struct crypto_adptr_data ca;
struct dma_adptr_data da;
+ struct vector_adptr_data va;
struct test_perf *t;
};
@@ -320,9 +327,9 @@ perf_process_last_stage_latency(struct rte_mempool *const pool, enum evt_prod_ty
}
static __rte_always_inline void
-perf_process_vector_last_stage(struct rte_mempool *const pool,
- struct rte_mempool *const ca_pool, struct rte_event *const ev,
- struct worker_data *const w, const bool enable_fwd_latency)
+perf_process_crypto_vector_last_stage(struct rte_mempool *const pool,
+ struct rte_mempool *const ca_pool, struct rte_event *const ev,
+ struct worker_data *const w, const bool enable_fwd_latency)
{
struct rte_event_vector *vec = ev->vec;
struct rte_crypto_op *cop;
diff --git a/app/test-eventdev/test_perf_queue.c b/app/test-eventdev/test_perf_queue.c
index 58715a2537..36fe94e190 100644
--- a/app/test-eventdev/test_perf_queue.c
+++ b/app/test-eventdev/test_perf_queue.c
@@ -147,7 +147,7 @@ perf_queue_worker_burst(void *arg, const int enable_fwd_latency)
}
static int
-perf_queue_worker_vector(void *arg, const int enable_fwd_latency)
+perf_queue_worker_crypto_vector(void *arg, const int enable_fwd_latency)
{
uint16_t enq = 0, deq = 0;
struct rte_event ev;
@@ -163,10 +163,8 @@ perf_queue_worker_vector(void *arg, const int enable_fwd_latency)
if (!deq)
continue;
- if (ev.event_type == RTE_EVENT_TYPE_CRYPTODEV_VECTOR) {
- if (perf_handle_crypto_vector_ev(&ev, &pe, enable_fwd_latency))
- continue;
- }
+ if (perf_handle_crypto_vector_ev(&ev, &pe, enable_fwd_latency))
+ continue;
stage = ev.queue_id % nb_stages;
/* First q in pipeline, mark timestamp to compute fwd latency */
@@ -175,8 +173,8 @@ perf_queue_worker_vector(void *arg, const int enable_fwd_latency)
/* Last stage in pipeline */
if (unlikely(stage == laststage)) {
- perf_process_vector_last_stage(pool, t->ca_op_pool, &ev, w,
- enable_fwd_latency);
+ perf_process_crypto_vector_last_stage(pool, t->ca_op_pool, &ev, w,
+ enable_fwd_latency);
} else {
fwd_event_vector(&ev, sched_type_list, nb_stages);
do {
@@ -190,6 +188,52 @@ perf_queue_worker_vector(void *arg, const int enable_fwd_latency)
return 0;
}
+static int
+perf_queue_worker_vector(void *arg, const int enable_fwd_latency)
+{
+ uint16_t enq = 0, deq = 0;
+ struct rte_event ev;
+ PERF_WORKER_INIT;
+
+ RTE_SET_USED(pe);
+ RTE_SET_USED(sz);
+ RTE_SET_USED(cnt);
+ RTE_SET_USED(prod_type);
+ RTE_SET_USED(prod_timer_type);
+
+ while (t->done == false) {
+ deq = rte_event_dequeue_burst(dev, port, &ev, 1, 0);
+ if (!deq)
+ continue;
+
+ if (ev.event_type != RTE_EVENT_TYPE_CPU_VECTOR) {
+ w->processed_pkts++;
+ continue;
+ }
+
+ stage = ev.sub_event_type % nb_stages;
+ if (enable_fwd_latency && stage == 0)
+ /* first stage in pipeline, mark ts to compute fwd latency */
+ ev.vec->u64s[0] = rte_get_timer_cycles();
+
+ /* Last stage in pipeline */
+ if (unlikely(stage == laststage)) {
+ w->processed_vecs++;
+ if (enable_fwd_latency)
+ w->latency += rte_get_timer_cycles() - ev.vec->u64s[0];
+ rte_mempool_put(pool, ev.event_ptr);
+ } else {
+ fwd_event_vector(&ev, sched_type_list, nb_stages);
+ do {
+ enq = rte_event_enqueue_burst(dev, port, &ev, 1);
+ } while (!enq && !t->done);
+ }
+ }
+ perf_worker_cleanup(pool, dev, port, &ev, enq, deq);
+
+ return 0;
+}
+
static int
worker_wrapper(void *arg)
{
@@ -201,6 +245,8 @@ worker_wrapper(void *arg)
/* allow compiler to optimize */
if (opt->ena_vector && opt->prod_type == EVT_PROD_TYPE_EVENT_CRYPTO_ADPTR)
+ return perf_queue_worker_crypto_vector(arg, fwd_latency);
+ else if (opt->prod_type == EVT_PROD_TYPE_EVENT_VECTOR_ADPTR)
return perf_queue_worker_vector(arg, fwd_latency);
else if (!burst && !fwd_latency)
return perf_queue_worker(arg, 0);
@@ -234,8 +280,10 @@ perf_queue_eventdev_setup(struct evt_test *test, struct evt_options *opt)
nb_ports = evt_nr_active_lcores(opt->wlcores);
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);
+ opt->prod_type == EVT_PROD_TYPE_EVENT_TIMER_ADPTR ||
+ opt->prod_type == EVT_PROD_TYPE_EVENT_VECTOR_ADPTR ?
+ 0 :
+ evt_nr_active_lcores(opt->plcores);
nb_queues = perf_queue_nb_event_queues(opt);
diff --git a/doc/guides/rel_notes/release_25_07.rst b/doc/guides/rel_notes/release_25_07.rst
index e6e84eeec6..a17ab13a00 100644
--- a/doc/guides/rel_notes/release_25_07.rst
+++ b/doc/guides/rel_notes/release_25_07.rst
@@ -61,6 +61,11 @@ New Features
model by introducing APIs that allow applications to offload creation of
event vectors.
+* **Added vector adapter producer mode in eventdev test.**
+
+ Added vector adapter producer mode to measure performance of event vector
+ adapter.
+
Removed Items
-------------
diff --git a/doc/guides/tools/testeventdev.rst b/doc/guides/tools/testeventdev.rst
index 58f373b867..c4e1047fbb 100644
--- a/doc/guides/tools/testeventdev.rst
+++ b/doc/guides/tools/testeventdev.rst
@@ -130,6 +130,10 @@ The following are the application command-line options:
Use DMA device as producer.
+* ``--prod_type_vector``
+
+ Use event vector adapter as producer.
+
* ``--timer_tick_nsec``
Used to dictate number of nano seconds between bucket traversal of the
@@ -635,6 +639,7 @@ Supported application command line options are following::
--prod_type_timerdev
--prod_type_cryptodev
--prod_type_dmadev
+ --prod_type_vector
--prod_enq_burst_sz
--timer_tick_nsec
--max_tmo_nsec
@@ -756,6 +761,7 @@ Supported application command line options are following::
--prod_type_timerdev
--prod_type_cryptodev
--prod_type_dmadev
+ --prod_type_vector
--timer_tick_nsec
--max_tmo_nsec
--expiry_nsec
--
2.43.0
next prev parent reply other threads:[~2025-04-10 18:01 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-26 13:14 [RFC 0/2] introduce event vector adapter pbhagavatula
2025-03-26 13:14 ` [RFC 1/2] eventdev: " pbhagavatula
2025-04-10 18:00 ` [PATCH 0/3] " pbhagavatula
2025-04-10 18:00 ` [PATCH 1/3] eventdev: " pbhagavatula
2025-04-10 18:00 ` [PATCH 2/3] eventdev: add default software " pbhagavatula
2025-04-10 18:00 ` pbhagavatula [this message]
2025-03-26 13:14 ` [RFC 2/2] " pbhagavatula
2025-03-26 14:18 ` Stephen Hemminger
2025-03-26 17:25 ` [EXTERNAL] " Pavan Nikhilesh Bhagavatula
2025-03-26 20:25 ` Stephen Hemminger
2025-03-26 14:22 ` Stephen Hemminger
2025-03-26 17:06 ` [RFC 0/2] introduce event " Pavan Nikhilesh Bhagavatula
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250410180056.10368-4-pbhagavatula@marvell.com \
--to=pbhagavatula@marvell.com \
--cc=abhinandan.gujjar@intel.com \
--cc=amitprakashs@marvell.com \
--cc=anatoly.burakov@intel.com \
--cc=dev@dpdk.org \
--cc=erik.g.carrillo@intel.com \
--cc=harry.van.haaren@intel.com \
--cc=hemant.agrawal@nxp.com \
--cc=jerinj@marvell.com \
--cc=liangma@liangbit.com \
--cc=mattias.ronnblom@ericsson.com \
--cc=peter.mccarthy@intel.com \
--cc=pravin.pathak@intel.com \
--cc=s.v.naga.harish.k@intel.com \
--cc=sachin.saxena@nxp.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).