aboutsummaryrefslogtreecommitdiff
path: root/test/performance/odp_sched_perf.c
diff options
context:
space:
mode:
authorMatias Elo <matias.elo@nokia.com>2024-02-29 10:17:50 +0200
committerMatias Elo <matias.elo@nokia.com>2024-02-29 10:17:50 +0200
commit16e67fed112cd472a9fd1be20b75903cb6bf219c (patch)
treed4d7794d3e9f0ad47f33a97b0df943c98a818168 /test/performance/odp_sched_perf.c
parentc00ef7d6bce1e483c4cf1bb3cdf6cd629530d795 (diff)
parent7abbd0d823091bfc52ec0345fb8fc67f68cc8c80 (diff)
Merge ODP v1.44.0.0
Merge ODP linux-generic v1.44.0.0 into linux-dpdk. Signed-off-by: Matias Elo <matias.elo@nokia.com>
Diffstat (limited to 'test/performance/odp_sched_perf.c')
-rw-r--r--test/performance/odp_sched_perf.c131
1 files changed, 114 insertions, 17 deletions
diff --git a/test/performance/odp_sched_perf.c b/test/performance/odp_sched_perf.c
index f89705576..47f703338 100644
--- a/test/performance/odp_sched_perf.c
+++ b/test/performance/odp_sched_perf.c
@@ -1,10 +1,23 @@
/* Copyright (c) 2018, Linaro Limited
- * Copyright (c) 2020-2022, Nokia
+ * Copyright (c) 2020-2024, Nokia
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+/**
+ * @example odp_sched_perf.c
+ *
+ * Performance test application for scheduling
+ *
+ * @cond _ODP_HIDE_FROM_DOXYGEN_
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE /* Needed for sigaction */
+#endif
+
+#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
@@ -52,6 +65,9 @@ typedef struct test_options_t {
uint32_t ctx_size;
uint32_t ctx_rd_words;
uint32_t ctx_rw_words;
+ uint32_t uarea_rd;
+ uint32_t uarea_rw;
+ uint32_t uarea_size;
uint64_t wait_ns;
int verbose;
@@ -88,6 +104,7 @@ typedef struct test_global_t {
test_stat_t stat[ODP_THREAD_COUNT_MAX];
thread_arg_t thread_arg[ODP_THREAD_COUNT_MAX];
odp_atomic_u32_t num_worker;
+ odp_atomic_u32_t exit_threads;
} test_global_t;
@@ -96,6 +113,23 @@ typedef struct {
odp_atomic_u64_t count;
} queue_context_t;
+static test_global_t *test_globals;
+
+static void sig_handler(int signum ODP_UNUSED)
+{
+ odp_atomic_store_u32(&test_globals->exit_threads, 1);
+}
+
+static int setup_sig_handler(void)
+{
+ struct sigaction action = { .sa_handler = sig_handler };
+
+ if (sigemptyset(&action.sa_mask) || sigaction(SIGINT, &action, NULL))
+ return -1;
+
+ return 0;
+}
+
static void print_usage(void)
{
printf("\n"
@@ -111,7 +145,8 @@ static void print_usage(void)
" the queues are default (or lowest) priority. Default: 0.\n"
" -d, --num_dummy Number of empty queues. Default: 0.\n"
" -e, --num_event Number of events per queue. Default: 100.\n"
- " -s, --num_sched Number of events to schedule per thread. Default: 100 000.\n"
+ " -s, --num_sched Number of events to schedule per thread. If zero, the application runs\n"
+ " until SIGINT is received. Default: 100 000.\n"
" -g, --num_group Number of schedule groups. Round robins threads and queues into groups.\n"
" -1: SCHED_GROUP_WORKER\n"
" 0: SCHED_GROUP_ALL (default)\n"
@@ -127,6 +162,8 @@ static void print_usage(void)
" -l, --ctx_rw_words Number of queue context words (uint64_t) to modify on every event. Default: 0.\n"
" -n, --rd_words Number of event data words (uint64_t) to read before enqueueing it. Default: 0.\n"
" -m, --rw_words Number of event data words (uint64_t) to modify before enqueueing it. Default: 0.\n"
+ " -u, --uarea_rd Number of user area words (uint64_t) to read on every event. Default: 0.\n"
+ " -U, --uarea_rw Number of user area words (uint64_t) to modify on every event. Default: 0.\n"
" -p, --pool_type Pool type. 0: buffer, 1: packet. Default: 0.\n"
" -v, --verbose Verbose output.\n"
" -h, --help This help\n"
@@ -159,13 +196,15 @@ static int parse_options(int argc, char *argv[], test_options_t *test_options)
{"ctx_rw_words", required_argument, NULL, 'l'},
{"rd_words", required_argument, NULL, 'n'},
{"rw_words", required_argument, NULL, 'm'},
+ {"uarea_rd", required_argument, NULL, 'u'},
+ {"uarea_rw", required_argument, NULL, 'U'},
{"pool_type", required_argument, NULL, 'p'},
{"verbose", no_argument, NULL, 'v'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}
};
- static const char *shortopts = "+c:q:L:H:d:e:s:g:j:b:t:f:a:w:k:l:n:m:p:vh";
+ static const char *shortopts = "+c:q:L:H:d:e:s:g:j:b:t:f:a:w:k:l:n:m:p:u:U:vh";
test_options->num_cpu = 1;
test_options->num_queue = 1;
@@ -184,6 +223,8 @@ static int parse_options(int argc, char *argv[], test_options_t *test_options)
test_options->ctx_rw_words = 0;
test_options->rd_words = 0;
test_options->rw_words = 0;
+ test_options->uarea_rd = 0;
+ test_options->uarea_rw = 0;
test_options->wait_ns = 0;
test_options->verbose = 0;
@@ -245,6 +286,12 @@ static int parse_options(int argc, char *argv[], test_options_t *test_options)
case 'm':
test_options->rw_words = atoi(optarg);
break;
+ case 'u':
+ test_options->uarea_rd = atoi(optarg);
+ break;
+ case 'U':
+ test_options->uarea_rw = atoi(optarg);
+ break;
case 'p':
pool_type = atoi(optarg);
break;
@@ -337,6 +384,7 @@ static int parse_options(int argc, char *argv[], test_options_t *test_options)
ctx_size = ROUNDUP(ctx_size, ODP_CACHE_LINE_SIZE);
test_options->ctx_size = ctx_size;
+ test_options->uarea_size = 8 * (test_options->uarea_rd + test_options->uarea_rw);
return ret;
}
@@ -377,7 +425,7 @@ static int create_pool(test_global_t *global)
odp_pool_capability_t pool_capa;
odp_pool_param_t pool_param;
odp_pool_t pool;
- uint32_t max_num, max_size;
+ uint32_t max_num, max_size, max_uarea;
test_options_t *test_options = &global->test_options;
uint32_t num_cpu = test_options->num_cpu;
uint32_t num_queue = test_options->num_queue;
@@ -395,6 +443,7 @@ static int create_pool(test_global_t *global)
uint32_t event_size = 16;
int touch_data = test_options->touch_data;
uint32_t ctx_size = test_options->ctx_size;
+ uint32_t uarea_size = test_options->uarea_size;
if (touch_data) {
event_size = test_options->rd_words + test_options->rw_words;
@@ -426,22 +475,22 @@ static int create_pool(test_global_t *global)
printf(" max burst size %u\n", max_burst);
printf(" total events %u\n", tot_event);
printf(" event size %u bytes", event_size);
- if (touch_data) {
- printf(" (rd: %u, rw: %u)\n",
- 8 * test_options->rd_words,
- 8 * test_options->rw_words);
- } else {
- printf("\n");
- }
+ if (touch_data)
+ printf(" (rd: %u, rw: %u)", 8 * test_options->rd_words, 8 * test_options->rw_words);
+ printf("\n");
printf(" context size %u bytes", ctx_size);
if (test_options->ctx_rd_words || test_options->ctx_rw_words) {
- printf(" (rd: %u, rw: %u)\n",
+ printf(" (rd: %u, rw: %u)",
8 * test_options->ctx_rd_words,
8 * test_options->ctx_rw_words);
- } else {
- printf("\n");
}
+ printf("\n");
+
+ printf(" user area size %u bytes", uarea_size);
+ if (uarea_size)
+ printf(" (rd: %u, rw: %u)", 8 * test_options->uarea_rd, 8 * test_options->uarea_rw);
+ printf("\n");
if (odp_pool_capability(&pool_capa)) {
ODPH_ERR("Error: pool capa failed\n");
@@ -452,11 +501,12 @@ static int create_pool(test_global_t *global)
printf(" pool type buffer\n");
max_num = pool_capa.buf.max_num;
max_size = pool_capa.buf.max_size;
-
+ max_uarea = pool_capa.buf.max_uarea_size;
} else {
printf(" pool type packet\n");
max_num = pool_capa.pkt.max_num;
max_size = pool_capa.pkt.max_seg_len;
+ max_uarea = pool_capa.pkt.max_uarea_size;
}
if (max_num && tot_event > max_num) {
@@ -469,18 +519,25 @@ static int create_pool(test_global_t *global)
return -1;
}
+ if (uarea_size > max_uarea) {
+ ODPH_ERR("Error: max supported user area size %u\n", max_uarea);
+ return -1;
+ }
+
odp_pool_param_init(&pool_param);
if (test_options->pool_type == ODP_POOL_BUFFER) {
pool_param.type = ODP_POOL_BUFFER;
pool_param.buf.num = tot_event;
pool_param.buf.size = event_size;
pool_param.buf.align = 8;
+ pool_param.buf.uarea_size = uarea_size;
} else {
pool_param.type = ODP_POOL_PACKET;
pool_param.pkt.num = tot_event;
pool_param.pkt.len = event_size;
pool_param.pkt.seg_len = event_size;
pool_param.pkt.align = 8;
+ pool_param.pkt.uarea_size = uarea_size;
}
pool = odp_pool_create("sched perf", &pool_param);
@@ -853,6 +910,28 @@ static int destroy_groups(test_global_t *global)
return 0;
}
+static uint64_t rw_uarea(odp_event_t ev[], int num, uint32_t rd_words, uint32_t rw_words)
+{
+ uint64_t *data;
+ int i;
+ uint32_t j;
+ uint64_t sum = 0;
+
+ for (i = 0; i < num; i++) {
+ data = odp_event_user_area(ev[i]);
+
+ for (j = 0; j < rd_words; j++)
+ sum += data[j];
+
+ for (; j < rd_words + rw_words; j++) {
+ sum += data[j];
+ data[j] += 1;
+ }
+ }
+
+ return sum;
+}
+
static inline uint64_t rw_ctx_data(void *ctx, uint32_t offset,
uint32_t rd_words, uint32_t rw_words)
{
@@ -921,12 +1000,17 @@ static int test_sched(void *arg)
uint32_t ctx_size = test_options->ctx_size;
uint32_t ctx_rd_words = test_options->ctx_rd_words;
uint32_t ctx_rw_words = test_options->ctx_rw_words;
+ const uint32_t uarea_size = test_options->uarea_size;
+ const uint32_t uarea_rd = test_options->uarea_rd;
+ const uint32_t uarea_rw = test_options->uarea_rw;
odp_pool_type_t pool_type = test_options->pool_type;
int touch_ctx = ctx_rd_words || ctx_rw_words;
+ odp_atomic_u32_t *exit_threads = &global->exit_threads;
uint32_t ctx_offset = 0;
uint32_t sched_retries = 0;
uint64_t data_sum = 0;
uint64_t ctx_sum = 0;
+ uint64_t uarea_sum = 0;
uint64_t wait_ns = test_options->wait_ns;
odp_event_t ev[max_burst];
@@ -981,7 +1065,10 @@ static int test_sched(void *arg)
c1 = odp_cpu_cycles();
last_retry_ts = t1;
- for (rounds = 0; events < num_sched; rounds++) {
+ for (rounds = 0; odp_likely(!odp_atomic_load_u32(exit_threads)); rounds++) {
+ if (odp_unlikely(num_sched && events >= num_sched))
+ break;
+
num = odp_schedule_multi(&queue, ODP_SCHED_NO_WAIT,
ev, max_burst);
@@ -990,6 +1077,9 @@ static int test_sched(void *arg)
events += num;
i = 0;
+ if (odp_unlikely(uarea_size))
+ uarea_sum += rw_uarea(ev, num, uarea_rd, uarea_rw);
+
if (odp_unlikely(ctx_size)) {
queue_context_t *ctx = odp_queue_context(queue);
@@ -1077,7 +1167,7 @@ static int test_sched(void *arg)
global->stat[thr].nsec = nsec;
global->stat[thr].cycles = cycles;
global->stat[thr].waits = waits;
- global->stat[thr].dummy_sum = data_sum + ctx_sum;
+ global->stat[thr].dummy_sum = data_sum + ctx_sum + uarea_sum;
global->stat[thr].failed = ret;
if (odp_atomic_fetch_dec_u32(&global->num_worker) == 1) {
@@ -1337,10 +1427,17 @@ int main(int argc, char **argv)
ODPH_ERR("Error: SHM alloc failed\n");
exit(EXIT_FAILURE);
}
+ test_globals = global;
memset(global, 0, sizeof(test_global_t));
global->pool = ODP_POOL_INVALID;
global->ctx_shm = ODP_SHM_INVALID;
+ odp_atomic_init_u32(&global->exit_threads, 0);
+
+ if (setup_sig_handler()) {
+ ODPH_ERR("Error: signal handler setup failed\n");
+ exit(EXIT_FAILURE);
+ }
if (parse_options(argc, argv, &global->test_options))
return -1;