This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "".
The branch, master has been updated via a5609cc551f4bc71fb69746f3d6cafaf64b87fbf (commit) from 03aafc317489232bab7e9048f9bd96a24e6f598d (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- commit a5609cc551f4bc71fb69746f3d6cafaf64b87fbf Author: Matias Elo matias.elo@nokia.com Date: Mon Jan 23 16:35:35 2017 +0200
test: perf: add new packet function microbenchmark application
The application calls each packet function TEST_REPEAT_COUNT times and calculates the average cycle count per call.
Main options: -b: Burst size for *_multi operations -i: Benchmark index to run indefinitely
The application prints benchmark results as a table, which can be copied as is to a spreadsheet application.
Signed-off-by: Matias Elo matias.elo@nokia.com Reviewed-and-tested-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/test/common_plat/performance/.gitignore b/test/common_plat/performance/.gitignore index 1527d25..eeacf2f 100644 --- a/test/common_plat/performance/.gitignore +++ b/test/common_plat/performance/.gitignore @@ -1,6 +1,7 @@ *.log *.trs odp_atomic +odp_bench_packet odp_crypto odp_l2fwd odp_pktio_perf diff --git a/test/common_plat/performance/Makefile.am b/test/common_plat/performance/Makefile.am index f184609..bcbf9cd 100644 --- a/test/common_plat/performance/Makefile.am +++ b/test/common_plat/performance/Makefile.am @@ -2,7 +2,9 @@ include $(top_srcdir)/test/Makefile.inc
TESTS_ENVIRONMENT += TEST_DIR=${builddir}
-EXECUTABLES = odp_crypto$(EXEEXT) odp_pktio_perf$(EXEEXT) +EXECUTABLES = odp_bench_packet$(EXEEXT) \ + odp_crypto$(EXEEXT) \ + odp_pktio_perf$(EXEEXT)
COMPILE_ONLY = odp_l2fwd$(EXEEXT) \ odp_sched_latency$(EXEEXT) \ @@ -20,6 +22,8 @@ endif
bin_PROGRAMS = $(EXECUTABLES) $(COMPILE_ONLY)
+odp_bench_packet_LDFLAGS = $(AM_LDFLAGS) -static +odp_bench_packet_CFLAGS = $(AM_CFLAGS) -I${top_srcdir}/test odp_crypto_LDFLAGS = $(AM_LDFLAGS) -static odp_crypto_CFLAGS = $(AM_CFLAGS) -I${top_srcdir}/test odp_sched_latency_LDFLAGS = $(AM_LDFLAGS) -static @@ -30,6 +34,7 @@ odp_scheduling_CFLAGS = $(AM_CFLAGS) -I${top_srcdir}/test noinst_HEADERS = \ $(top_srcdir)/test/test_debug.h
+dist_odp_bench_packet_SOURCES = odp_bench_packet.c dist_odp_crypto_SOURCES = odp_crypto.c dist_odp_sched_latency_SOURCES = odp_sched_latency.c dist_odp_scheduling_SOURCES = odp_scheduling.c diff --git a/test/common_plat/performance/odp_bench_packet.c b/test/common_plat/performance/odp_bench_packet.c new file mode 100644 index 0000000..1aa9d81 --- /dev/null +++ b/test/common_plat/performance/odp_bench_packet.c @@ -0,0 +1,1611 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * @example odp_bench_packet.c Microbenchmarks for packet functions + */ + +#include <stdlib.h> +#include <getopt.h> +#include <unistd.h> +#include <errno.h> +#include <inttypes.h> +#include <signal.h> + +#include <test_debug.h> + +#include <odp_api.h> +#include <odp/helper/threads.h> +#include <odp/helper/eth.h> +#include <odp/helper/ip.h> +#include <odp/helper/udp.h> + +/** Minimum number of packet data bytes in the first segment */ +#define PKT_POOL_SEG_LEN 128 + +/** Packet user area size in bytes */ +#define PKT_POOL_UAREA_SIZE 8 + +/** Minimum test packet size */ +#define TEST_MIN_PKT_SIZE 64 + +/** Maximum test packet size */ +#define TEST_MAX_PKT_SIZE 2048 + +/** Number of test runs per individual benchmark */ +#define TEST_REPEAT_COUNT 1000 + +/** Number of times to run tests for each packet size */ +#define TEST_SIZE_RUN_COUNT 10 + +/** Maximum burst size for *_multi operations */ +#define TEST_MAX_BURST 64 + +/** Offset of the contiguous area */ +#define TEST_ALIGN_OFFSET 16 + +/** Length of the contiguous area */ +#define TEST_ALIGN_LEN 32 + +/** Minimum byte alignment of contiguous area */ +#define TEST_ALIGN 32 + +/** Test packet offsets */ +#define TEST_L2_OFFSET 0 +#define TEST_L3_OFFSET (TEST_MIN_PKT_SIZE / 4) +#define TEST_L4_OFFSET (TEST_MIN_PKT_SIZE / 2) + +/** Default burst size for *_multi operations */ +#define TEST_DEF_BURST 8 + +/** Get rid of path in filename - only for unix-type paths using '/' */ +#define NO_PATH(file_name) (strrchr((file_name), '/') ? \ + strrchr((file_name), '/') + 1 : (file_name)) + +#define BENCH_INFO(run, init, term, name) \ + {#run, run, init, term, name} + +ODP_STATIC_ASSERT((TEST_ALIGN_OFFSET + TEST_ALIGN_LEN) <= TEST_MIN_PKT_SIZE, + "Invalid_alignment"); + +/** Warm up round packet size */ +#define WARM_UP TEST_MIN_PKT_SIZE + +/** Test packet sizes */ +const uint32_t test_packet_len[] = {WARM_UP, TEST_MIN_PKT_SIZE, 128, 256, 512, + 1024, 1518, TEST_MAX_PKT_SIZE}; + +/** + * Parsed command line arguments + */ +typedef struct { + int bench_idx; /** Benchmark index to run indefinitely */ + int burst_size; /** Burst size for *_multi operations */ +} appl_args_t; + +/** + * Initialize benchmark resources + */ +typedef void (*bench_init_fn_t)(void); + +/** + * Run benchmark + * + * @retval >0 on success + * */ +typedef int (*bench_run_fn_t)(void); + +/** + * Release benchmark resources + */ +typedef void (*bench_term_fn_t)(void); + +/** + * Benchmark data + */ +typedef struct { + const char *name; + bench_run_fn_t run; + bench_init_fn_t init; + bench_term_fn_t term; + const char *desc; +} bench_info_t; + +/** + * Grouping of all global data + */ +typedef struct { + /** Application (parsed) arguments */ + appl_args_t appl; + /** Packet pool */ + odp_pool_t pool; + /** Benchmark functions */ + bench_info_t *bench; + /** Number of benchmark functions */ + int num_bench; + struct { + /** Test packet length */ + uint32_t len; + /** Minimum test packet headroom */ + uint32_t headroom; + /** Minimum test packet tailroom */ + uint32_t tailroom; + /** Minimum test packet segment length */ + uint32_t seg_len; + } pkt; + /** Array for storing test packets */ + odp_packet_t pkt_tbl[TEST_REPEAT_COUNT * TEST_MAX_BURST]; + /** Array for storing test packets */ + odp_packet_t pkt2_tbl[TEST_REPEAT_COUNT]; + /** Array for storing test event */ + odp_event_t event_tbl[TEST_REPEAT_COUNT]; + /** Array for storing test pointers */ + void *ptr_tbl[TEST_REPEAT_COUNT]; + /** Array for storing test segments */ + odp_packet_seg_t seg_tbl[TEST_REPEAT_COUNT]; + /** Array for storing test outputs */ + uint32_t output_tbl[TEST_REPEAT_COUNT]; + /** Array for storing test pool handles */ + odp_pool_t pool_tbl[TEST_REPEAT_COUNT]; + /** Array for storing test pktio handles */ + odp_pktio_t pktio_tbl[TEST_REPEAT_COUNT]; + /** Array for storing test timestamps */ + odp_time_t ts_tbl[TEST_REPEAT_COUNT]; + /** Array for storing test data */ + uint8_t data_tbl[TEST_REPEAT_COUNT][TEST_MAX_PKT_SIZE]; + /** Benchmark run failed */ + uint8_t bench_failed; +} args_t; + +/** Global pointer to args */ +static args_t *gbl_args; +/** Global barrier to synchronize main and worker */ +static odp_barrier_t barrier; +/** Break worker loop if set to 1 */ +static int exit_thread; + +static void sig_handler(int signo ODP_UNUSED) +{ + exit_thread = 1; +} + +/** + * Run given benchmark indefinitely + */ +static void run_indef(args_t *args, int idx) +{ + const char *desc; + + desc = args->bench[idx].desc != NULL ? + args->bench[idx].desc : args->bench[idx].name; + + printf("Running %s() indefinitely\n", desc); + + while (!exit_thread) { + int ret; + + if (args->bench[idx].init != NULL) + args->bench[idx].init(); + + ret = args->bench[idx].run(); + + if (args->bench[idx].term != NULL) + args->bench[idx].term(); + + if (!ret) + LOG_ABORT("Benchmark %s failed\n", desc); + } +} + +/** + * Master function for running the microbenchmarks + */ +static int run_benchmarks(void *arg) +{ + int i, j, k; + args_t *args = arg; + int num_sizes = sizeof(test_packet_len) / sizeof(test_packet_len[0]); + double results[gbl_args->num_bench][num_sizes]; + + memset(results, 0, sizeof(results)); + + printf("\nRunning benchmarks (cycles per call)\n" + "------------------------------------\n"); + + for (i = 0; i < num_sizes; i++) { + uint64_t tot_cycles = 0; + + printf("\nPacket length: %6d bytes\n" + "---------------------------\n", test_packet_len[i]); + + gbl_args->pkt.len = test_packet_len[i]; + + for (j = 0, k = 1; j < gbl_args->num_bench; k++) { + int ret; + uint64_t c1, c2; + const char *desc; + + if (args->appl.bench_idx && + (j + 1) != args->appl.bench_idx) { + j++; + continue; + } else if (args->appl.bench_idx && + (j + 1) == args->appl.bench_idx) { + run_indef(args, j); + return 0; + } + + desc = args->bench[j].desc != NULL ? + args->bench[j].desc : + args->bench[j].name; + + if (args->bench[j].init != NULL) + args->bench[j].init(); + + c1 = odp_cpu_cycles(); + ret = args->bench[j].run(); + c2 = odp_cpu_cycles(); + + if (args->bench[j].term != NULL) + args->bench[j].term(); + + if (!ret) { + LOG_ERR("Benchmark %s failed\n", desc); + args->bench_failed = 1; + return -1; + } + + tot_cycles += odp_cpu_cycles_diff(c2, c1); + + if (k >= TEST_SIZE_RUN_COUNT) { + double cycles; + + /** Each benchmark runs internally + * TEST_REPEAT_COUNT times. */ + cycles = ((double)tot_cycles) / + (TEST_SIZE_RUN_COUNT * + TEST_REPEAT_COUNT); + results[j][i] = cycles; + + printf("%-30s: %8.1f\n", desc, cycles); + + j++; + k = 0; + tot_cycles = 0; + } + } + } + printf("\n%-30s", "Benchmark / packet_size [B]"); + for (i = 0; i < num_sizes; i++) { + if (i == 0) + printf(" WARM UP "); + else + printf("%8.1d ", test_packet_len[i]); + } + printf("\n---------------------------------"); + for (i = 0; i < num_sizes; i++) + printf("----------"); + + for (i = 0; i < gbl_args->num_bench; i++) { + printf("\n[%02d] %-30s", i + 1, args->bench[i].desc != NULL ? + args->bench[i].desc : args->bench[i].name); + + for (j = 0; j < num_sizes; j++) + printf("%8.1f ", results[i][j]); + } + printf("\n\n"); + return 0; +} + +static void allocate_test_packets(uint32_t len, odp_packet_t pkt[], int num) +{ + int pkts = 0; + + while (pkts < num) { + int ret; + + ret = odp_packet_alloc_multi(gbl_args->pool, len, &pkt[pkts], + num - pkts); + if (ret < 0) + LOG_ABORT("Allocating test packets failed\n"); + + pkts += ret; + } +} + +static void alloc_packets_half(void) +{ + allocate_test_packets(gbl_args->pkt.len / 2, gbl_args->pkt_tbl, + TEST_REPEAT_COUNT); +} + +static void alloc_packets_multi(void) +{ + allocate_test_packets(gbl_args->pkt.len, gbl_args->pkt_tbl, + TEST_REPEAT_COUNT * gbl_args->appl.burst_size); +} + +static void alloc_concat_packets(void) +{ + allocate_test_packets(gbl_args->pkt.len / 2, gbl_args->pkt_tbl, + TEST_REPEAT_COUNT); + allocate_test_packets(gbl_args->pkt.len / 2, gbl_args->pkt2_tbl, + TEST_REPEAT_COUNT); +} + +static void alloc_packets_twice(void) +{ + allocate_test_packets(gbl_args->pkt.len, gbl_args->pkt_tbl, + TEST_REPEAT_COUNT); + allocate_test_packets(gbl_args->pkt.len, gbl_args->pkt2_tbl, + TEST_REPEAT_COUNT); +} + +static void create_packets(void) +{ + int i; + uint32_t headroom, tailroom, seg_len; + uint32_t min_headroom = 0; + uint32_t min_tailroom = 0; + uint32_t min_seg_len = 0; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + odp_packet_seg_t *seg_tbl = gbl_args->seg_tbl; + + allocate_test_packets(gbl_args->pkt.len, gbl_args->pkt_tbl, + TEST_REPEAT_COUNT); + + for (i = 0; i < TEST_REPEAT_COUNT; i++) { + headroom = odp_packet_headroom(pkt_tbl[i]); + tailroom = odp_packet_tailroom(pkt_tbl[i]); + seg_len = odp_packet_seg_len(pkt_tbl[i]); + + seg_tbl[i] = odp_packet_first_seg(pkt_tbl[i]); + + if (i == 0) { + min_headroom = headroom; + min_tailroom = tailroom; + min_seg_len = seg_len; + } else { + if (headroom < min_headroom) + min_headroom = headroom; + if (tailroom < min_tailroom) + min_tailroom = tailroom; + if (seg_len < min_seg_len) + min_seg_len = seg_len; + } + + if (odp_packet_l2_offset_set(pkt_tbl[i], TEST_L2_OFFSET) || + odp_packet_l3_offset_set(pkt_tbl[i], TEST_L3_OFFSET) || + odp_packet_l4_offset_set(pkt_tbl[i], TEST_L4_OFFSET)) + LOG_ABORT("Setting test packet offsets failed\n"); + + odp_packet_flow_hash_set(pkt_tbl[i], i); + odp_packet_ts_set(pkt_tbl[i], odp_time_local()); + } + gbl_args->pkt.headroom = min_headroom; + gbl_args->pkt.tailroom = min_tailroom; + gbl_args->pkt.seg_len = min_seg_len; +} + +static void create_events(void) +{ + int i; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + + create_packets(); + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + gbl_args->event_tbl[i] = odp_packet_to_event(pkt_tbl[i]); +} + +static void free_packets(void) +{ + odp_packet_free_multi(gbl_args->pkt_tbl, TEST_REPEAT_COUNT); +} + +static void free_packets_multi(void) +{ + odp_packet_free_multi(gbl_args->pkt_tbl, + TEST_REPEAT_COUNT * gbl_args->appl.burst_size); +} + +static void free_packets_twice(void) +{ + odp_packet_free_multi(gbl_args->pkt_tbl, TEST_REPEAT_COUNT); + odp_packet_free_multi(gbl_args->pkt2_tbl, TEST_REPEAT_COUNT); +} + +static int bench_empty(void) +{ + int i; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + gbl_args->output_tbl[i] = i; + + return i; +} + +static int bench_packet_alloc(void) +{ + int i; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) { + odp_packet_t pkt; + + pkt = odp_packet_alloc(gbl_args->pool, gbl_args->pkt.len); + + gbl_args->pkt_tbl[i] = pkt; + } + + return i; +} + +static int bench_packet_alloc_multi(void) +{ + int i; + int pkts = 0; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + pkts += odp_packet_alloc_multi(gbl_args->pool, + gbl_args->pkt.len, + &gbl_args->pkt_tbl[pkts], + gbl_args->appl.burst_size); + return pkts; +} + +static int bench_packet_free(void) +{ + int i; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + odp_packet_free(gbl_args->pkt_tbl[i]); + + return i; +} + +static int bench_packet_free_multi(void) +{ + int i; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) { + int pkt_idx = i * gbl_args->appl.burst_size; + + odp_packet_free_multi(&gbl_args->pkt_tbl[pkt_idx], + gbl_args->appl.burst_size); + } + return i; +} + +static int bench_packet_alloc_free(void) +{ + int i; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) { + odp_packet_t pkt; + + pkt = odp_packet_alloc(gbl_args->pool, gbl_args->pkt.len); + + odp_packet_free(pkt); + } + return i; +} + +static int bench_packet_alloc_free_multi(void) +{ + int i; + int pkts; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) { + pkts = odp_packet_alloc_multi(gbl_args->pool, gbl_args->pkt.len, + gbl_args->pkt_tbl, + gbl_args->appl.burst_size); + odp_packet_free_multi(gbl_args->pkt_tbl, pkts); + } + return i; +} + +static int bench_packet_reset(void) +{ + int i; + int ret = 0; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_reset(gbl_args->pkt_tbl[i], + gbl_args->pkt.len); + return !ret; +} + +static int bench_packet_from_event(void) +{ + int i; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + pkt_tbl[i] = odp_packet_from_event(gbl_args->event_tbl[i]); + + return i; +} + +static int bench_packet_to_event(void) +{ + int i; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + gbl_args->event_tbl[i] = odp_packet_to_event(pkt_tbl[i]); + + return i; +} + +static int bench_packet_head(void) +{ + int i; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + gbl_args->ptr_tbl[i] = odp_packet_head(gbl_args->pkt_tbl[i]); + + return i; +} + +static int bench_packet_buf_len(void) +{ + int i; + uint32_t ret = 0; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_buf_len(gbl_args->pkt_tbl[i]); + + return ret; +} + +static int bench_packet_data(void) +{ + int i; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + gbl_args->ptr_tbl[i] = odp_packet_data(gbl_args->pkt_tbl[i]); + + return i; +} + +static int bench_packet_seg_len(void) +{ + int i; + uint32_t ret = 0; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_seg_len(gbl_args->pkt_tbl[i]); + + return ret; +} + +static int bench_packet_len(void) +{ + int i; + uint32_t ret = 0; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_len(gbl_args->pkt_tbl[i]); + + return ret; +} + +static int bench_packet_headroom(void) +{ + int i; + uint32_t ret = 0; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_headroom(gbl_args->pkt_tbl[i]); + + return ret; +} + +static int bench_packet_tailroom(void) +{ + int i; + uint32_t ret = 0; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_tailroom(gbl_args->pkt_tbl[i]); + + return ret; +} + +static int bench_packet_tail(void) +{ + int i; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + gbl_args->ptr_tbl[i] = odp_packet_tail(gbl_args->pkt_tbl[i]); + + return i; +} + +static int bench_packet_offset(void) +{ + int i; + uint32_t offset = gbl_args->pkt.len / 2; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + gbl_args->ptr_tbl[i] = odp_packet_offset(gbl_args->pkt_tbl[i], + offset, NULL, NULL); + return i; +} + +static int bench_packet_prefetch(void) +{ + int i; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + odp_packet_prefetch(gbl_args->pkt_tbl[i], 0, gbl_args->pkt.len); + + return i; +} + +static int bench_packet_push_head(void) +{ + int i; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + uint32_t hroom = gbl_args->pkt.headroom; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + gbl_args->ptr_tbl[i] = odp_packet_push_head(pkt_tbl[i], hroom); + + return i; +} + +static int bench_packet_pull_head(void) +{ + int i; + uint32_t len = gbl_args->pkt.seg_len - 1; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + gbl_args->ptr_tbl[i] = odp_packet_pull_head(pkt_tbl[i], len); + + return i; +} + +static int bench_packet_push_tail(void) +{ + int i; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + uint32_t troom = gbl_args->pkt.tailroom; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + gbl_args->ptr_tbl[i] = odp_packet_push_tail(pkt_tbl[i], troom); + + return i; +} + +static int bench_packet_pull_tail(void) +{ + int i; + uint32_t len = gbl_args->pkt.seg_len - 1; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + gbl_args->ptr_tbl[i] = odp_packet_pull_tail(pkt_tbl[i], len); + + return i; +} + +static int bench_packet_extend_head(void) +{ + int i; + int ret = 0; + uint32_t len = gbl_args->pkt.len / 2; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + void **ptr_tbl = gbl_args->ptr_tbl; + uint32_t *data_tbl = gbl_args->output_tbl; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_extend_head(&pkt_tbl[i], len, ptr_tbl[i], + &data_tbl[i]); + return ret >= 0; +} + +static int bench_packet_trunc_head(void) +{ + int i; + int ret = 0; + uint32_t len = gbl_args->pkt.len / 2; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + void **ptr_tbl = gbl_args->ptr_tbl; + uint32_t *data_tbl = gbl_args->output_tbl; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_trunc_head(&pkt_tbl[i], len, ptr_tbl[i], + &data_tbl[i]); + return ret >= 0; +} + +static int bench_packet_extend_tail(void) +{ + int i; + int ret = 0; + uint32_t len = gbl_args->pkt.len / 2; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + void **ptr_tbl = gbl_args->ptr_tbl; + uint32_t *data_tbl = gbl_args->output_tbl; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_extend_tail(&pkt_tbl[i], len, ptr_tbl[i], + &data_tbl[i]); + return ret >= 0; +} + +static int bench_packet_trunc_tail(void) +{ + int i; + int ret = 0; + uint32_t len = gbl_args->pkt.len / 2; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + void **ptr_tbl = gbl_args->ptr_tbl; + uint32_t *data_tbl = gbl_args->output_tbl; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_trunc_tail(&pkt_tbl[i], len, ptr_tbl[i], + &data_tbl[i]); + return ret >= 0; +} + +static int bench_packet_add_data(void) +{ + int i; + int ret = 0; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + uint32_t len = gbl_args->pkt.len / 2; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_add_data(&pkt_tbl[i], 0, len); + + return ret >= 0; +} + +static int bench_packet_rem_data(void) +{ + int i; + int ret = 0; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + uint32_t len = gbl_args->pkt.len / 2; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_rem_data(&pkt_tbl[i], 0, len); + + return ret >= 0; +} + +static int bench_packet_align(void) +{ + int i; + int ret = 0; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_align(&pkt_tbl[i], TEST_ALIGN_OFFSET, + TEST_ALIGN_LEN, TEST_ALIGN); + return ret >= 0; +} + +static int bench_packet_is_segmented(void) +{ + int i; + uint32_t ret = 0; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_is_segmented(gbl_args->pkt_tbl[i]); + + return (ret == 0) ? 1 : ret; +} + +static int bench_packet_num_segs(void) +{ + int i; + uint32_t ret = 0; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_num_segs(gbl_args->pkt_tbl[i]); + + return ret; +} + +static int bench_packet_first_seg(void) +{ + int i; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + gbl_args->seg_tbl[i] = odp_packet_first_seg(pkt_tbl[i]); + + return i; +} + +static int bench_packet_last_seg(void) +{ + int i; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + gbl_args->seg_tbl[i] = odp_packet_last_seg(pkt_tbl[i]); + + return i; +} + +static int bench_packet_next_seg(void) +{ + int i; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + odp_packet_seg_t *seg_tbl = gbl_args->seg_tbl; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + gbl_args->seg_tbl[i] = odp_packet_next_seg(pkt_tbl[i], + seg_tbl[i]); + return i; +} + +static int bench_packet_seg_data(void) +{ + int i; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + odp_packet_seg_t *seg_tbl = gbl_args->seg_tbl; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + gbl_args->ptr_tbl[i] = odp_packet_seg_data(pkt_tbl[i], + seg_tbl[i]); + return i; +} + +static int bench_packet_seg_data_len(void) +{ + int i; + uint32_t ret = 0; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + odp_packet_seg_t *seg_tbl = gbl_args->seg_tbl; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_seg_data_len(pkt_tbl[i], seg_tbl[i]); + + return ret; +} + +static int bench_packet_concat(void) +{ + int i; + int ret = 0; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + odp_packet_t *frag_tbl = gbl_args->pkt2_tbl; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_concat(&pkt_tbl[i], frag_tbl[i]); + + return ret >= 0; +} + +static int bench_packet_split(void) +{ + int i; + int ret = 0; + uint32_t head_len; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + odp_packet_t *frag_tbl = gbl_args->pkt2_tbl; + + head_len = odp_packet_len(pkt_tbl[0]) / 2; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_split(&pkt_tbl[i], head_len, &frag_tbl[i]); + + return ret >= 0; +} + +static int bench_packet_copy(void) +{ + int i; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + odp_packet_t *cpy_tbl = gbl_args->pkt2_tbl; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + cpy_tbl[i] = odp_packet_copy(pkt_tbl[i], gbl_args->pool); + + return i; +} + +static int bench_packet_copy_part(void) +{ + int i; + uint32_t len = gbl_args->pkt.len / 2; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + odp_packet_t *cpy_tbl = gbl_args->pkt2_tbl; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + cpy_tbl[i] = odp_packet_copy_part(pkt_tbl[i], 0, len, + gbl_args->pool); + return i; +} + +static int bench_packet_copy_to_mem(void) +{ + int i; + uint32_t ret = 0; + uint32_t len = gbl_args->pkt.len; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_copy_to_mem(pkt_tbl[i], 0, len, + gbl_args->data_tbl[i]); + return !ret; +} + +static int bench_packet_copy_from_mem(void) +{ + int i; + uint32_t ret = 0; + uint32_t len = gbl_args->pkt.len; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_copy_from_mem(pkt_tbl[i], 0, len, + gbl_args->data_tbl[i]); + return !ret; +} + +static int bench_packet_copy_from_pkt(void) +{ + int i; + uint32_t ret = 0; + uint32_t len = gbl_args->pkt.len; + odp_packet_t *dst_tbl = gbl_args->pkt_tbl; + odp_packet_t *src_tbl = gbl_args->pkt2_tbl; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_copy_from_pkt(dst_tbl[i], 0, src_tbl[i], 0, + len); + return !ret; +} + +static int bench_packet_copy_data(void) +{ + int i; + uint32_t ret = 0; + uint32_t len = gbl_args->pkt.len / 2; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_copy_data(pkt_tbl[i], 0, len, len); + + return !ret; +} + +static int bench_packet_move_data(void) +{ + int i; + uint32_t ret = 0; + uint32_t len = gbl_args->pkt.len / 2; + uint32_t offset = len / 2; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_move_data(pkt_tbl[i], offset, len, len); + + return !ret; +} + +static int bench_packet_pool(void) +{ + int i; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + gbl_args->pool_tbl[i] = odp_packet_pool(gbl_args->pkt_tbl[i]); + + return i; +} + +static int bench_packet_input(void) +{ + int i; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + gbl_args->pktio_tbl[i] = odp_packet_input(gbl_args->pkt_tbl[i]); + + return i; +} + +static int bench_packet_input_index(void) +{ + int i; + int ret = 0; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_input_index(gbl_args->pkt_tbl[i]); + + return (ret == 0) ? 1 : ret; +} + +static int bench_packet_user_ptr(void) +{ + int i; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + gbl_args->ptr_tbl[i] = odp_packet_user_ptr(pkt_tbl[i]); + + return i; +} + +static int bench_packet_user_ptr_set(void) +{ + int i; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + odp_packet_user_ptr_set(gbl_args->pkt_tbl[i], + gbl_args->ptr_tbl[i]); + + return i; +} + +static int bench_packet_user_area(void) +{ + int i; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + gbl_args->ptr_tbl[i] = odp_packet_user_area(pkt_tbl[i]); + + return i; +} + +static int bench_packet_user_area_size(void) +{ + int i; + uint32_t ret = 0; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_user_area_size(gbl_args->pkt_tbl[i]); + + return ret; +} + +static int bench_packet_l2_ptr(void) +{ + int i; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + gbl_args->ptr_tbl[i] = odp_packet_l2_ptr(gbl_args->pkt_tbl[i], + NULL); + return i; +} + +static int bench_packet_l2_offset(void) +{ + int i; + int ret = 0; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_l2_offset(gbl_args->pkt_tbl[i]); + + return ret >= 0; +} + +static int bench_packet_l2_offset_set(void) +{ + int i; + uint32_t ret = 0; + uint32_t offset = gbl_args->pkt.len / 2; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_l2_offset_set(gbl_args->pkt_tbl[i], offset); + + return !ret; +} + +static int bench_packet_l3_ptr(void) +{ + int i; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + gbl_args->ptr_tbl[i] = odp_packet_l3_ptr(gbl_args->pkt_tbl[i], + NULL); + return i; +} + +static int bench_packet_l3_offset(void) +{ + int i; + int ret = 0; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_l3_offset(gbl_args->pkt_tbl[i]); + + return ret >= 0; +} + +static int bench_packet_l3_offset_set(void) +{ + int i; + uint32_t ret = 0; + uint32_t offset = gbl_args->pkt.len / 2; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_l3_offset_set(gbl_args->pkt_tbl[i], offset); + + return !ret; +} + +static int bench_packet_l4_ptr(void) +{ + int i; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + gbl_args->ptr_tbl[i] = odp_packet_l4_ptr(gbl_args->pkt_tbl[i], + NULL); + return i; +} + +static int bench_packet_l4_offset(void) +{ + int i; + int ret = 0; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_l4_offset(gbl_args->pkt_tbl[i]); + + return ret >= 0; +} + +static int bench_packet_l4_offset_set(void) +{ + int i; + uint32_t ret = 0; + uint32_t offset = gbl_args->pkt.len / 2; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_l4_offset_set(gbl_args->pkt_tbl[i], offset); + + return !ret; +} + +static int bench_packet_flow_hash(void) +{ + int i; + uint32_t ret = 0; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_flow_hash(gbl_args->pkt_tbl[i]); + + return ret; +} + +static int bench_packet_flow_hash_set(void) +{ + int i; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + odp_packet_flow_hash_set(gbl_args->pkt_tbl[i], i); + + return i; +} + +static int bench_packet_ts(void) +{ + int i; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + gbl_args->ts_tbl[i] = odp_packet_ts(gbl_args->pkt_tbl[i]); + + return i; +} + +static int bench_packet_ts_set(void) +{ + int i; + odp_time_t ts = odp_time_local(); + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + odp_packet_ts_set(gbl_args->pkt_tbl[i], ts); + + return i; +} + +/** + * Prinf usage information + */ +static void usage(char *progname) +{ + printf("\n" + "OpenDataPlane Packet function microbenchmark.\n" + "\n" + "Usage: %s OPTIONS\n" + " E.g. %s\n" + "\n" + "Optional OPTIONS:\n" + " -b, --burst Test packet burst size.\n" + " -i, --index Benchmark index to run indefinitely.\n" + " -h, --help Display help and exit.\n\n" + "\n", NO_PATH(progname), NO_PATH(progname)); +} + +/** + * Parse and store the command line arguments + * + * @param argc argument count + * @param argv[] argument vector + * @param appl_args Store application arguments here + */ +static void parse_args(int argc, char *argv[], appl_args_t *appl_args) +{ + int opt; + int long_index; + static const struct option longopts[] = { + {"burst", required_argument, NULL, 'b'}, + {"help", no_argument, NULL, 'h'}, + {"index", required_argument, NULL, 'i'}, + {NULL, 0, NULL, 0} + }; + + static const char *shortopts = "b:i:h"; + + /* Let helper collect its own arguments (e.g. --odph_proc) */ + odph_parse_options(argc, argv, shortopts, longopts); + + opterr = 0; /* Do not issue errors on helper options */ + + appl_args->bench_idx = 0; /* Run all benchmarks */ + appl_args->burst_size = TEST_DEF_BURST; + + while (1) { + opt = getopt_long(argc, argv, shortopts, longopts, &long_index); + + if (opt == -1) + break; /* No more options */ + + switch (opt) { + case 'b': + appl_args->burst_size = atoi(optarg); + break; + case 'h': + usage(argv[0]); + exit(EXIT_SUCCESS); + break; + case 'i': + appl_args->bench_idx = atoi(optarg); + break; + default: + break; + } + } + + if (appl_args->burst_size < 1 || + appl_args->burst_size > TEST_MAX_BURST) { + printf("Invalid burst size (max %d)\n", TEST_MAX_BURST); + exit(EXIT_FAILURE); + } + + optind = 1; /* Reset 'extern optind' from the getopt lib */ +} + +/** + * Print system and application info + */ +static void print_info(char *progname, appl_args_t *appl_args ODP_UNUSED) +{ + printf("\n" + "ODP system info\n" + "---------------\n" + "ODP API version: %s\n" + "ODP impl name: %s\n" + "CPU model: %s\n" + "CPU freq (hz): %" PRIu64 "\n" + "Cache line size: %i\n" + "CPU count: %i\n" + "\n", + odp_version_api_str(), odp_version_impl_name(), + odp_cpu_model_str(), odp_cpu_hz_max(), + odp_sys_cache_line_size(), odp_cpu_count()); + + printf("Running ODP appl: "%s"\n" + "-----------------\n", progname); + fflush(NULL); +} + +/** + * Test functions + */ +bench_info_t test_suite[] = { + BENCH_INFO(bench_empty, NULL, NULL, NULL), + BENCH_INFO(bench_packet_alloc, NULL, free_packets, NULL), + BENCH_INFO(bench_packet_alloc_multi, NULL, free_packets_multi, + NULL), + BENCH_INFO(bench_packet_free, create_packets, NULL, NULL), + BENCH_INFO(bench_packet_free_multi, alloc_packets_multi, NULL, + NULL), + BENCH_INFO(bench_packet_alloc_free, NULL, NULL, NULL), + BENCH_INFO(bench_packet_alloc_free_multi, NULL, NULL, NULL), + BENCH_INFO(bench_packet_reset, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_from_event, create_events, free_packets, + NULL), + BENCH_INFO(bench_packet_to_event, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_head, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_buf_len, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_data, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_seg_len, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_len, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_headroom, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_tailroom, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_tail, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_offset, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_prefetch, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_push_head, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_pull_head, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_push_tail, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_pull_tail, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_extend_head, alloc_packets_half, + free_packets, NULL), + BENCH_INFO(bench_packet_trunc_head, create_packets, + free_packets, NULL), + BENCH_INFO(bench_packet_extend_tail, alloc_packets_half, + free_packets, NULL), + BENCH_INFO(bench_packet_trunc_tail, create_packets, + free_packets, NULL), + BENCH_INFO(bench_packet_add_data, alloc_packets_half, + free_packets, NULL), + BENCH_INFO(bench_packet_rem_data, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_align, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_is_segmented, create_packets, + free_packets, NULL), + BENCH_INFO(bench_packet_num_segs, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_first_seg, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_last_seg, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_next_seg, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_seg_data, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_seg_data_len, create_packets, + free_packets, NULL), + BENCH_INFO(bench_packet_concat, alloc_concat_packets, + free_packets, NULL), + BENCH_INFO(bench_packet_split, create_packets, + free_packets_twice, NULL), + BENCH_INFO(bench_packet_copy, create_packets, + free_packets_twice, NULL), + BENCH_INFO(bench_packet_copy_part, create_packets, + free_packets_twice, NULL), + BENCH_INFO(bench_packet_copy_to_mem, create_packets, + free_packets, NULL), + BENCH_INFO(bench_packet_copy_from_mem, create_packets, + free_packets, NULL), + BENCH_INFO(bench_packet_copy_from_pkt, alloc_packets_twice, + free_packets_twice, NULL), + BENCH_INFO(bench_packet_copy_data, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_move_data, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_pool, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_input, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_input_index, create_packets, + free_packets, NULL), + BENCH_INFO(bench_packet_user_ptr, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_user_ptr_set, create_packets, + free_packets, NULL), + BENCH_INFO(bench_packet_user_area, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_user_area_size, create_packets, + free_packets, NULL), + BENCH_INFO(bench_packet_l2_ptr, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_l2_offset, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_l2_offset_set, create_packets, + free_packets, NULL), + BENCH_INFO(bench_packet_l3_ptr, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_l3_offset, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_l3_offset_set, create_packets, + free_packets, NULL), + BENCH_INFO(bench_packet_l4_ptr, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_l4_offset, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_l4_offset_set, create_packets, + free_packets, NULL), + BENCH_INFO(bench_packet_flow_hash, create_packets, free_packets, + NULL), + BENCH_INFO(bench_packet_flow_hash_set, create_packets, + free_packets, NULL), + BENCH_INFO(bench_packet_ts, create_packets, free_packets, NULL), + BENCH_INFO(bench_packet_ts_set, create_packets, free_packets, + NULL), +}; + +/** + * ODP packet microbenchmark application + */ +int main(int argc, char *argv[]) +{ + odph_odpthread_t worker_thread; + int cpu; + odp_shm_t shm; + odp_cpumask_t cpumask; + char cpumaskstr[ODP_CPUMASK_STR_SIZE]; + odp_pool_capability_t capa; + odp_pool_param_t params; + odp_instance_t instance; + uint32_t pkt_num; + uint8_t ret; + + /* Init ODP before calling anything else */ + if (odp_init_global(&instance, NULL, NULL)) { + LOG_ERR("Error: ODP global init failed.\n"); + exit(EXIT_FAILURE); + } + + /* Init this thread */ + if (odp_init_local(instance, ODP_THREAD_CONTROL)) { + LOG_ERR("Error: ODP local init failed.\n"); + exit(EXIT_FAILURE); + } + + /* Reserve memory for args from shared mem */ + shm = odp_shm_reserve("shm_args", sizeof(args_t), + ODP_CACHE_LINE_SIZE, 0); + + if (shm == ODP_SHM_INVALID) { + LOG_ERR("Error: shared mem reserve failed.\n"); + exit(EXIT_FAILURE); + } + + gbl_args = odp_shm_addr(shm); + + if (gbl_args == NULL) { + LOG_ERR("Error: shared mem alloc failed.\n"); + exit(EXIT_FAILURE); + } + + memset(gbl_args, 0, sizeof(args_t)); + + gbl_args->bench = test_suite; + gbl_args->num_bench = sizeof(test_suite) / sizeof(test_suite[0]); + + /* Parse and store the application arguments */ + parse_args(argc, argv, &gbl_args->appl); + + /* Print both system and application information */ + print_info(NO_PATH(argv[0]), &gbl_args->appl); + + /* Get default worker cpumask */ + if (odp_cpumask_default_worker(&cpumask, 1) != 1) { + LOG_ERR("Error: unable to allocate worker thread.\n"); + exit(EXIT_FAILURE); + } + + (void)odp_cpumask_to_str(&cpumask, cpumaskstr, sizeof(cpumaskstr)); + + /* Check pool capability */ + if (odp_pool_capability(&capa)) { + LOG_ERR("Error: unable to query pool capability.\n"); + exit(EXIT_FAILURE); + } + + /* At least 2 x TEST_REPEAT_COUNT packets required */ + pkt_num = (gbl_args->appl.burst_size > 2) ? + gbl_args->appl.burst_size * TEST_REPEAT_COUNT : + 2 * TEST_REPEAT_COUNT; + + if (capa.pkt.max_num && capa.pkt.max_num < pkt_num) { + LOG_ERR("Error: packet pool size not supported.\n"); + printf("MAX: %" PRIu32 "\n", capa.pkt.max_num); + exit(EXIT_FAILURE); + } else if (capa.pkt.max_len && capa.pkt.max_len < TEST_MAX_PKT_SIZE) { + LOG_ERR("Error: packet length not supported.\n"); + exit(EXIT_FAILURE); + } else if (capa.pkt.max_seg_len && + capa.pkt.max_seg_len < PKT_POOL_SEG_LEN) { + LOG_ERR("Error: segment length not supported.\n"); + exit(EXIT_FAILURE); + } else if (capa.pkt.max_uarea_size && + capa.pkt.max_uarea_size < PKT_POOL_UAREA_SIZE) { + LOG_ERR("Error: user area size not supported.\n"); + exit(EXIT_FAILURE); + } + + /* Create packet pool */ + odp_pool_param_init(¶ms); + params.pkt.seg_len = PKT_POOL_SEG_LEN; + params.pkt.len = TEST_MAX_PKT_SIZE; + params.pkt.num = pkt_num; + params.pkt.uarea_size = PKT_POOL_UAREA_SIZE; + params.type = ODP_POOL_PACKET; + + gbl_args->pool = odp_pool_create("packet pool", ¶ms); + + if (gbl_args->pool == ODP_POOL_INVALID) { + LOG_ERR("Error: packet pool create failed.\n"); + exit(EXIT_FAILURE); + } + + printf("CPU: %i\n", odp_cpumask_first(&cpumask)); + printf("CPU mask: %s\n", cpumaskstr); + printf("Burst size: %d\n", gbl_args->appl.burst_size); + printf("Bench repeat: %d\n", TEST_REPEAT_COUNT); + + odp_pool_print(gbl_args->pool); + + memset(&worker_thread, 0, sizeof(odph_odpthread_t)); + + odp_barrier_init(&barrier, 1 + 1); + + signal(SIGINT, sig_handler); + + /* Create worker threads */ + cpu = odp_cpumask_first(&cpumask); + + odp_cpumask_t thd_mask; + odph_odpthread_params_t thr_params; + + memset(&thr_params, 0, sizeof(thr_params)); + thr_params.start = run_benchmarks; + thr_params.arg = gbl_args; + thr_params.thr_type = ODP_THREAD_WORKER; + thr_params.instance = instance; + + odp_cpumask_zero(&thd_mask); + odp_cpumask_set(&thd_mask, cpu); + odph_odpthreads_create(&worker_thread, &thd_mask, + &thr_params); + + odph_odpthreads_join(&worker_thread); + + ret = gbl_args->bench_failed; + + if (odp_pool_destroy(gbl_args->pool)) { + LOG_ERR("Error: pool destroy\n"); + exit(EXIT_FAILURE); + } + + if (odp_shm_free(shm)) { + LOG_ERR("Error: shm free\n"); + exit(EXIT_FAILURE); + } + + if (odp_term_local()) { + LOG_ERR("Error: term local\n"); + exit(EXIT_FAILURE); + } + + if (odp_term_global(instance)) { + LOG_ERR("Error: term global\n"); + exit(EXIT_FAILURE); + } + + return ret; +}
-----------------------------------------------------------------------
Summary of changes: test/common_plat/performance/.gitignore | 1 + test/common_plat/performance/Makefile.am | 7 +- test/common_plat/performance/odp_bench_packet.c | 1611 +++++++++++++++++++++++ 3 files changed, 1618 insertions(+), 1 deletion(-) create mode 100644 test/common_plat/performance/odp_bench_packet.c
hooks/post-receive