Different implementations may have different overheads for getting the
nanoseconds number. This overhead may accumulate when time is read
repeatedly and impact the overall value.

Alex


On 4 January 2016 at 14:30, Bill Fischofer <[email protected]>
wrote:

>
>
> On Mon, Jan 4, 2016 at 1:34 AM, Alexandru Badicioiu <
> [email protected]> wrote:
>
>> Using time API makes the performance test OS independent but it makes the
>> actual results dependent also on the time API implementation. This could be
>> an issue especially when comparing crypto performances of different
>> platforms.
>>
>
> How is that?  A ns is a ns no matter how it's implemented.
>
>
>>
>> Alex
>>
>> On 30 December 2015 at 16:59, Maxim Uvarov <[email protected]>
>> wrote:
>>
>>> Alex, I think after 1.6 time api will be there and it's better to reuse
>>> for performance test.
>>>
>>> Maxim.
>>>
>>>
>>> On 12/17/2015 12:55, [email protected] wrote:
>>>
>>>> From: Alexandru Badicioiu <alexandru.badicioiu at linaro.org>
>>>>
>>>> Measures the time required to launch and get the result
>>>> of ODP crypto operations in async and sync API mode with
>>>> configurable payload size, crypto algorithms and iteration
>>>> number.
>>>> Both asynchronous scheduled and polled are supported.
>>>> In scheduled mode a separate worker thread is used to
>>>> get the crypto completion events.
>>>> Output packet can be reused as the input of the next
>>>> operation or a new packet can be allocated for each
>>>> operation.
>>>> Based on a previous work :
>>>> https://lists.linaro.org/pipermail/lng-odp/2014-September/003251.html.
>>>>
>>>> Signed-off-by: Alexandru Badicioiu <[email protected]>
>>>> ---
>>>>
>>>> v1
>>>> ---
>>>> - replaced cspeed with crypto
>>>> - removed unused parameter core_count
>>>> v2
>>>> --
>>>> - alphabetical order in Makefile.am
>>>> - replaced pool params memset with init call
>>>> v3
>>>> --
>>>> - rebased to latest master
>>>>
>>>> ---
>>>>   test/performance/Makefile.am  |   5 +-
>>>>   test/performance/odp_crypto.c | 937
>>>> ++++++++++++++++++++++++++++++++++++++++++
>>>>   2 files changed, 941 insertions(+), 1 deletion(-)
>>>>   create mode 100644 test/performance/odp_crypto.c
>>>>
>>>> diff --git a/test/performance/Makefile.am b/test/performance/Makefile.am
>>>> index 721615b..78374cd 100644
>>>> --- a/test/performance/Makefile.am
>>>> +++ b/test/performance/Makefile.am
>>>> @@ -2,7 +2,7 @@ include $(top_srcdir)/test/Makefile.inc
>>>>     TESTS_ENVIRONMENT += TEST_DIR=${builddir}
>>>>   -EXECUTABLES = odp_atomic$(EXEEXT) odp_pktio_perf$(EXEEXT)
>>>> +EXECUTABLES = odp_atomic$(EXEEXT) odp_crypto$(EXEEXT)
>>>> odp_pktio_perf$(EXEEXT)
>>>>     COMPILE_ONLY = odp_l2fwd$(EXEEXT) \
>>>>                odp_scheduling$(EXEEXT)
>>>> @@ -18,6 +18,8 @@ bin_PROGRAMS = $(EXECUTABLES) $(COMPILE_ONLY)
>>>>     odp_atomic_LDFLAGS = $(AM_LDFLAGS) -static
>>>>   odp_atomic_CFLAGS = $(AM_CFLAGS) -I${top_srcdir}/test
>>>> +odp_crypto_LDFLAGS = $(AM_LDFLAGS) -static
>>>> +odp_crypto_CFLAGS = $(AM_CFLAGS) -I${top_srcdir}/test
>>>>   odp_scheduling_LDFLAGS = $(AM_LDFLAGS) -static
>>>>   odp_scheduling_CFLAGS = $(AM_CFLAGS) -I${top_srcdir}/test
>>>>   @@ -25,6 +27,7 @@ noinst_HEADERS = \
>>>>                   $(top_srcdir)/test/test_debug.h
>>>>     dist_odp_atomic_SOURCES = odp_atomic.c
>>>> +dist_odp_crypto_SOURCES = odp_crypto.c
>>>>   dist_odp_scheduling_SOURCES = odp_scheduling.c
>>>>   dist_odp_pktio_perf_SOURCES = odp_pktio_perf.c
>>>>   diff --git a/test/performance/odp_crypto.c
>>>> b/test/performance/odp_crypto.c
>>>> new file mode 100644
>>>> index 0000000..0596b17
>>>> --- /dev/null
>>>> +++ b/test/performance/odp_crypto.c
>>>> @@ -0,0 +1,937 @@
>>>> +/* Copyright (c) 2015, Linaro Limited
>>>> + * All rights reserved.
>>>> + *
>>>> + * SPDX-License-Identifier:    BSD-3-Clause
>>>> + */
>>>> +
>>>> +#ifndef _GNU_SOURCE
>>>> +#define _GNU_SOURCE
>>>> +#endif /* _GNU_SOURCE */
>>>> +
>>>> +#include <stdlib.h>
>>>> +#include <string.h>
>>>> +#include <getopt.h>
>>>> +#include <unistd.h>
>>>> +#include <stdio.h>
>>>> +#include <sys/time.h>
>>>> +#include <sys/resource.h>
>>>> +
>>>> +#include <odp.h>
>>>> +#include <odp/helper/linux.h>
>>>> +
>>>> +#define app_err(fmt, ...) \
>>>> +       fprintf(stderr, "%s:%d:%s(): Error: " fmt, __FILE__, \
>>>> +               __LINE__, __func__, ##__VA_ARGS__)
>>>> +
>>>> +/** @def SHM_PKT_POOL_SIZE
>>>> + * @brief Size of the shared memory block
>>>> + */
>>>> +#define SHM_PKT_POOL_SIZE      (512 * 2048 * 2)
>>>> +
>>>> +/** @def SHM_PKT_POOL_BUF_SIZE
>>>> + * @brief Buffer size of the packet pool buffer
>>>> + */
>>>> +#define SHM_PKT_POOL_BUF_SIZE  (1024 * 32)
>>>> +
>>>> +static uint8_t test_iv[8] = "01234567";
>>>> +
>>>> +static uint8_t test_key16[16] = { 0x01, 0x02, 0x03, 0x04, 0x05,
>>>> +                                 0x06, 0x07, 0x08, 0x09, 0x0a,
>>>> +                                 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
>>>> +                                 0x10,
>>>> +};
>>>> +
>>>> +static uint8_t test_key24[24] = { 0x01, 0x02, 0x03, 0x04, 0x05,
>>>> +                                 0x06, 0x07, 0x08, 0x09, 0x0a,
>>>> +                                 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
>>>> +                                 0x10, 0x11, 0x12, 0x13, 0x14,
>>>> +                                 0x15, 0x16, 0x17, 0x18
>>>> +};
>>>> +
>>>> +/**
>>>> + * Structure that holds template for session create call
>>>> + * for different algorithms supported by test
>>>> + */
>>>> +typedef struct {
>>>> +       const char *name;                     /**< Algorithm name */
>>>> +       odp_crypto_session_params_t session;  /**< Prefilled crypto
>>>> session params */
>>>> +       unsigned int hash_adjust;             /**< Size of hash */
>>>> +} crypto_alg_config_t;
>>>> +
>>>> +/**
>>>> + * Parsed command line crypto arguments. Describes test configuration.
>>>> + */
>>>> +typedef struct {
>>>> +       /**
>>>> +        * If non zero prints content of packets. Enabled by -d or
>>>> +        * --debug option.
>>>> +        */
>>>> +       int debug_packets;
>>>> +
>>>> +       /**
>>>> +        * If non zero Try to run crypto operation in place. Note some
>>>> +        * implementation may not support such mode. Enabled by -n or
>>>> +        * --inplace option.
>>>> +        */
>>>> +       int in_place;
>>>> +
>>>> +       /**
>>>> +        * If non zeor output of previous operation taken as input for
>>>> +        * next encrypt operations. Enabled by -r or --reuse option.
>>>> +        */
>>>> +       int reuse_packet;
>>>> +
>>>> +       /**
>>>> +        * Maximum number of outstanding encryption requests. Note code
>>>> +        * poll for results over queue and if nothing is available it
>>>> can
>>>> +        * submit more encryption requests up to maximum number
>>>> specified by
>>>> +        * this option. Specified through -f or --flight option.
>>>> +        */
>>>> +       int in_flight;
>>>> +
>>>> +       /**
>>>> +        * Number of iteration to repeat crypto operation to get good
>>>> +        * average number. Specified through -i or --terations option.
>>>> +        * Default is 10000.
>>>> +        */
>>>> +       int iteration_count;
>>>> +
>>>> +       /**
>>>> +        * Maximum sessions. Currently is not used.
>>>> +        */
>>>> +       int max_sessions;
>>>> +
>>>> +       /**
>>>> +        * Payload size to test. If 0 set of predefined payload sizes
>>>> +        * is tested. Specified through -p or --payload option.
>>>> +        */
>>>> +       int payload_length;
>>>> +
>>>> +       /**
>>>> +        * Pointer to selected algorithm to test. If NULL all available
>>>> +        * alogorthims are tested. Name of algorithm is passed through
>>>> +        * -a or --algorithm option.
>>>> +        */
>>>> +       crypto_alg_config_t *alg_config;
>>>> +
>>>> +       /**
>>>> +        * Use scheduler to get completion events from crypto operation.
>>>> +        * Specified through -s argument.
>>>> +        * */
>>>> +       int schedule;
>>>> +
>>>> +       /*
>>>> +        * Poll completion queue for crypto completion events.
>>>> +        * Specified through -p argument.
>>>> +        */
>>>> +       int poll;
>>>> +} crypto_args_t;
>>>> +
>>>> +/*
>>>> + * Helper structure that holds averages for test of one algorithm
>>>> + * for given payload size.
>>>> + */
>>>> +typedef struct {
>>>> +       /**
>>>> +        * Elapsed time for one crypto operation.
>>>> +        */
>>>> +       double elapsed;
>>>> +
>>>> +       /**
>>>> +        * CPU time spent pre one crypto operation by whole process
>>>> +        * i.e include current and all other threads in process.
>>>> +        * It is filled with 'getrusage(RUSAGE_SELF, ...)' call.
>>>> +        */
>>>> +       double rusage_self;
>>>> +
>>>> +       /**
>>>> +        * CPU time spent per one crypto operation by current thread
>>>> +        * only. It is filled with 'getrusage(RUSAGE_THREAD, ...)'
>>>> +        * call.
>>>> +        */
>>>> +       double rusage_thread;
>>>> +} crypto_run_result_t;
>>>> +
>>>> +/**
>>>> + * Structure holds one snap to misc times of current process.
>>>> + */
>>>> +typedef struct {
>>>> +       struct timeval tv;       /**< Elapsed time */
>>>> +       struct rusage ru_self;   /**< Rusage value for whole process */
>>>> +       struct rusage ru_thread; /**< Rusage value for current thread */
>>>> +} time_record_t;
>>>> +
>>>> +static void parse_args(int argc, char *argv[], crypto_args_t *cargs);
>>>> +static void usage(char *progname);
>>>> +
>>>> +/**
>>>> + * Set of predefined payloads. Make sure that maximum payload
>>>> + * size is not bigger than SHM_PKT_POOL_BUF_SIZE. May relax when
>>>> + * implementation start support segmented buffers/packets.
>>>> + */
>>>> +static unsigned int payloads[] = {
>>>> +       16,
>>>> +       64,
>>>> +       256,
>>>> +       1024,
>>>> +       8192,
>>>> +       16384
>>>> +};
>>>> +
>>>> +/**
>>>> + * Set of known algorithms to test
>>>> + */
>>>> +static crypto_alg_config_t algs_config[] = {
>>>> +       {
>>>> +               .name = "3des-cbc-null",
>>>> +               .session = {
>>>> +                       .cipher_alg = ODP_CIPHER_ALG_3DES_CBC,
>>>> +                       .cipher_key = {
>>>> +                               .data = test_key24,
>>>> +                               .length = sizeof(test_key24)
>>>> +                       },
>>>> +                       .iv = {
>>>> +                               .data = test_iv,
>>>> +                               .length = 8,
>>>> +                       },
>>>> +                       .auth_alg = ODP_AUTH_ALG_NULL
>>>> +               },
>>>> +       },
>>>> +       {
>>>> +               .name = "3des-cbc-hmac-md5-96",
>>>> +               .session = {
>>>> +                       .cipher_alg = ODP_CIPHER_ALG_3DES_CBC,
>>>> +                       .cipher_key = {
>>>> +                               .data = test_key24,
>>>> +                               .length = sizeof(test_key24)
>>>> +                       },
>>>> +                       .iv = {
>>>> +                               .data = test_iv,
>>>> +                               .length = 8,
>>>> +                       },
>>>> +                       .auth_alg = ODP_AUTH_ALG_MD5_96,
>>>> +                       .auth_key = {
>>>> +                               .data = test_key16,
>>>> +                               .length = sizeof(test_key16)
>>>> +                       }
>>>> +               },
>>>> +               .hash_adjust = 12
>>>> +       },
>>>> +       {
>>>> +               .name = "null-hmac-md5-96",
>>>> +               .session = {
>>>> +                       .cipher_alg = ODP_CIPHER_ALG_NULL,
>>>> +                       .auth_alg = ODP_AUTH_ALG_MD5_96,
>>>> +                       .auth_key = {
>>>> +                               .data = test_key16,
>>>> +                               .length = sizeof(test_key16)
>>>> +                       }
>>>> +               },
>>>> +               .hash_adjust = 12
>>>> +       },
>>>> +};
>>>> +
>>>> +/**
>>>> + * Find corresponding config for given name. Returns NULL
>>>> + * if config for given name is not found.
>>>> + */
>>>> +static crypto_alg_config_t *
>>>> +find_config_by_name(const char *name) {
>>>> +       unsigned int i;
>>>> +       crypto_alg_config_t *ret = NULL;
>>>> +
>>>> +       for (i = 0; i < (sizeof(algs_config) /
>>>> sizeof(crypto_alg_config_t));
>>>> +            i++) {
>>>> +               if (strcmp(algs_config[i].name, name) == 0) {
>>>> +                       ret = algs_config + i;
>>>> +                       break;
>>>> +               }
>>>> +       }
>>>> +       return ret;
>>>> +}
>>>> +
>>>> +/**
>>>> + * Helper function that prints list of algorithms that this
>>>> + * test understands.
>>>> + */
>>>> +static void
>>>> +print_config_names(const char *prefix) {
>>>> +       unsigned int i;
>>>> +
>>>> +       for (i = 0; i < (sizeof(algs_config) /
>>>> sizeof(crypto_alg_config_t));
>>>> +            i++) {
>>>> +               printf("%s %s\n", prefix, algs_config[i].name);
>>>> +       }
>>>> +}
>>>> +
>>>> +/**
>>>> + * Snap current time values and put them into 'rec'.
>>>> + */
>>>> +static void
>>>> +fill_time_record(time_record_t *rec)
>>>> +{
>>>> +       gettimeofday(&rec->tv, NULL);
>>>> +       getrusage(RUSAGE_SELF, &rec->ru_self);
>>>> +       getrusage(RUSAGE_THREAD, &rec->ru_thread);
>>>> +}
>>>> +
>>>> +/**
>>>> + * Calculated CPU time difference for given two rusage structures.
>>>> + * Note it adds user space and system time together.
>>>> + */
>>>> +static unsigned long long
>>>> +get_rusage_diff(struct rusage *start, struct rusage *end)
>>>> +{
>>>> +       unsigned long long rusage_diff;
>>>> +       unsigned long long rusage_start;
>>>> +       unsigned long long rusage_end;
>>>> +
>>>> +       rusage_start = (start->ru_utime.tv_sec * 1000000) +
>>>> +                      (start->ru_utime.tv_usec);
>>>> +       rusage_start += (start->ru_stime.tv_sec * 1000000) +
>>>> +                       (start->ru_stime.tv_usec);
>>>> +
>>>> +       rusage_end = (end->ru_utime.tv_sec * 1000000) +
>>>> +                    (end->ru_utime.tv_usec);
>>>> +       rusage_end += (end->ru_stime.tv_sec * 1000000) +
>>>> +                     (end->ru_stime.tv_usec);
>>>> +
>>>> +       rusage_diff = rusage_end - rusage_start;
>>>> +
>>>> +       return rusage_diff;
>>>> +}
>>>> +
>>>> +/**
>>>> + * Get diff for RUSAGE_SELF (whole process) between two time snap
>>>> + * records.
>>>> + */
>>>> +static unsigned long long
>>>> +get_rusage_self_diff(time_record_t *start, time_record_t *end)
>>>> +{
>>>> +       return get_rusage_diff(&start->ru_self, &end->ru_self);
>>>> +}
>>>> +
>>>> +/**
>>>> + * Get diff for RUSAGE_THREAD (current thread only) between two
>>>> + * time snap records.
>>>> + */
>>>> +static unsigned long long
>>>> +get_rusage_thread_diff(time_record_t *start, time_record_t *end)
>>>> +{
>>>> +       return get_rusage_diff(&start->ru_thread, &end->ru_thread);
>>>> +}
>>>> +
>>>> +/**
>>>> + * Get diff of elapsed time between two time snap records
>>>> + */
>>>> +static unsigned long long
>>>> +get_elapsed_usec(time_record_t *start, time_record_t *end)
>>>> +{
>>>> +       unsigned long long s;
>>>> +       unsigned long long e;
>>>> +
>>>> +       s = (start->tv.tv_sec * 1000000) +
>>>> +           (start->tv.tv_usec);
>>>> +       e = (end->tv.tv_sec * 1000000) +
>>>> +           (end->tv.tv_usec);
>>>> +
>>>> +       return e - s;
>>>> +}
>>>> +
>>>> +#define REPORT_HEADER      "\n%30.30s %15s %15s %15s %15s %15s %15s\n"
>>>> +#define REPORT_LINE        "%30.30s %15d %15d %15.3f %15.3f %15.3f
>>>> %15d\n"
>>>> +
>>>> +/**
>>>> + * Print header line for our report.
>>>> + */
>>>> +static void
>>>> +print_result_header(void)
>>>> +{
>>>> +       printf(REPORT_HEADER,
>>>> +              "algorithm", "avg over #", "payload (bytes)", "elapsed
>>>> (us)",
>>>> +              "rusg self (us)", "rusg thrd (us)", "throughput (Kb)");
>>>> +}
>>>> +
>>>> +/**
>>>> + * Print one line of our report.
>>>> + */
>>>> +static void
>>>> +print_result(crypto_args_t *cargs,
>>>> +            unsigned int payload_length,
>>>> +            crypto_alg_config_t *config,
>>>> +            crypto_run_result_t *result)
>>>> +{
>>>> +       unsigned int throughput;
>>>> +
>>>> +       throughput = (1000000.0 / result->elapsed) * payload_length /
>>>> 1024;
>>>> +       printf(REPORT_LINE,
>>>> +              config->name, cargs->iteration_count, payload_length,
>>>> +              result->elapsed, result->rusage_self,
>>>> result->rusage_thread,
>>>> +              throughput);
>>>> +}
>>>> +
>>>> +/**
>>>> + * Print piece of memory with given size.
>>>> + */
>>>> +static void
>>>> +print_mem(const char *msg,
>>>> +         const unsigned char *ptr,
>>>> +         unsigned int len)
>>>> +{
>>>> +       unsigned i, j;
>>>> +       char c;
>>>> +       char line[81];
>>>> +       char *p;
>>>> +
>>>> +       if (msg)
>>>> +               printf("\n%s (bytes size = %d)", msg, len);
>>>> +
>>>> +       for (i = 0; i < len; i += 16) {
>>>> +               p = line;
>>>> +               sprintf(p, "\n%04x   ", i); p += 8;
>>>> +
>>>> +               for (j = 0; j < 16; j++) {
>>>> +                       if (i + j == len)
>>>> +                               break;
>>>> +
>>>> +                       sprintf(p, " %02x", (ptr)[i + j]); p += 3;
>>>> +               }
>>>> +
>>>> +               for (; j < 16; j++) {
>>>> +                       sprintf(p, "   "); p += 3;
>>>> +               }
>>>> +
>>>> +               sprintf(p, "   "); p += 3;
>>>> +
>>>> +               for (j = 0; j < 16; j++) {
>>>> +                       if (i + j == len)
>>>> +                               break;
>>>> +                       c = (ptr)[i + j];
>>>> +                       *p++ = (' ' <= c && c <= '~') ? c : '.';
>>>> +               }
>>>> +
>>>> +               *p = '\0';
>>>> +               printf("%s", line);
>>>> +       }
>>>> +       printf("\n");
>>>> +}
>>>> +
>>>> +/**
>>>> + * Create ODP crypto session for given config.
>>>> + */
>>>> +static int
>>>> +create_session_from_config(odp_crypto_session_t *session,
>>>> +                          crypto_alg_config_t *config,
>>>> +                          crypto_args_t *cargs)
>>>> +{
>>>> +       odp_crypto_session_params_t params;
>>>> +       odp_crypto_ses_create_err_t ses_create_rc;
>>>> +       odp_pool_t pkt_pool;
>>>> +       odp_queue_t out_queue;
>>>> +
>>>> +       memcpy(&params, &config->session,
>>>> sizeof(odp_crypto_session_params_t));
>>>> +       params.op = ODP_CRYPTO_OP_ENCODE;
>>>> +       params.pref_mode   = ODP_CRYPTO_SYNC;
>>>> +
>>>> +       /* Lookup the packet pool */
>>>> +       pkt_pool = odp_pool_lookup("packet_pool");
>>>> +       if (pkt_pool == ODP_POOL_INVALID) {
>>>> +               app_err("packet_pool pool not found\n");
>>>> +               return -1;
>>>> +       }
>>>> +       params.output_pool = pkt_pool;
>>>> +
>>>> +       if (cargs->schedule || cargs->poll) {
>>>> +               out_queue = odp_queue_lookup("crypto-out");
>>>> +               if (out_queue == ODP_QUEUE_INVALID) {
>>>> +                       app_err("crypto-out queue not found\n");
>>>> +                       return -1;
>>>> +               }
>>>> +               params.compl_queue = out_queue;
>>>> +
>>>> +       } else {
>>>> +               params.compl_queue = ODP_QUEUE_INVALID;
>>>> +       }
>>>> +       if (odp_crypto_session_create(&params, session,
>>>> +                                     &ses_create_rc)) {
>>>> +               app_err("crypto session create failed.\n");
>>>> +               return -1;
>>>> +       }
>>>> +
>>>> +       return 0;
>>>> +}
>>>> +
>>>> +/**
>>>> + * Run measurement iterations for given config and payload size.
>>>> + * Result of run returned in 'result' out parameter.
>>>> + */
>>>> +static int
>>>> +run_measure_one(crypto_args_t *cargs,
>>>> +               crypto_alg_config_t *config,
>>>> +               odp_crypto_session_t *session,
>>>> +               unsigned int payload_length,
>>>> +               crypto_run_result_t *result)
>>>> +{
>>>> +       odp_crypto_op_params_t params;
>>>> +
>>>> +       odp_pool_t pkt_pool;
>>>> +       odp_queue_t out_queue;
>>>> +       odp_packet_t pkt;
>>>> +       int rc = 0;
>>>> +
>>>> +       odp_bool_t posted = 0;
>>>> +
>>>> +       pkt_pool = odp_pool_lookup("packet_pool");
>>>> +       if (pkt_pool == ODP_POOL_INVALID) {
>>>> +               app_err("pkt_pool not found\n");
>>>> +               return -1;
>>>> +       }
>>>> +
>>>> +       out_queue = odp_queue_lookup("crypto-out");
>>>> +       if (cargs->schedule || cargs->poll) {
>>>> +               if (out_queue == ODP_QUEUE_INVALID) {
>>>> +                       app_err("crypto-out queue not found\n");
>>>> +                       return -1;
>>>> +               }
>>>> +       }
>>>> +
>>>> +       pkt = odp_packet_alloc(pkt_pool, payload_length);
>>>> +       if (pkt == ODP_PACKET_INVALID) {
>>>> +               app_err("failed to allocate buffer\n");
>>>> +               return -1;
>>>> +       }
>>>> +
>>>> +       void *mem = odp_packet_data(pkt);
>>>> +
>>>> +       memset(mem, 1, payload_length);
>>>> +
>>>> +       time_record_t start, end;
>>>> +       int packets_sent = 0;
>>>> +       int packets_received = 0;
>>>> +
>>>> +       /* Initialize parameters block */
>>>> +       memset(&params, 0, sizeof(params));
>>>> +       params.session = *session;
>>>> +
>>>> +       params.cipher_range.offset = 0;
>>>> +       params.cipher_range.length = payload_length;
>>>> +
>>>> +       params.auth_range.offset = 0;
>>>> +       params.auth_range.length = payload_length;
>>>> +       params.hash_result_offset = payload_length;
>>>> +
>>>> +       if (cargs->reuse_packet) {
>>>> +               params.pkt = pkt;
>>>> +               params.out_pkt = cargs->in_place ? pkt :
>>>> +                                ODP_PACKET_INVALID;
>>>> +       }
>>>> +
>>>> +       fill_time_record(&start);
>>>> +
>>>> +       while ((packets_sent < cargs->iteration_count) ||
>>>> +              (packets_received <  cargs->iteration_count)) {
>>>> +               void *mem;
>>>> +               odp_crypto_op_result_t result;
>>>> +
>>>> +               if ((packets_sent < cargs->iteration_count) &&
>>>> +                   (packets_sent - packets_received <
>>>> +                    cargs->in_flight)) {
>>>> +                       if (!cargs->reuse_packet) {
>>>> +                               /*
>>>> +                                * For in place test we use just one
>>>> +                                * statically allocated buffer.
>>>> +                                * For now in place test we have to
>>>> +                                * allocate and initialize packet
>>>> +                                * every time.
>>>> +                                * Note we leaked one packet here.
>>>> +                                */
>>>> +                               pkt = odp_packet_alloc(pkt_pool,
>>>> +                                                      payload_length);
>>>> +                               if (pkt == ODP_PACKET_INVALID) {
>>>> +                                       app_err("failed to allocate
>>>> buffer\n");
>>>> +                                       rc = -1;
>>>> +                               } else {
>>>> +                                       void *mem =
>>>> odp_packet_data(pkt);
>>>> +
>>>> +                                       memset(mem, 1, payload_length);
>>>> +                               }
>>>> +                               params.pkt = pkt;
>>>> +                               params.out_pkt = cargs->in_place ? pkt :
>>>> +                                                ODP_PACKET_INVALID;
>>>> +                       }
>>>> +
>>>> +                       if (cargs->debug_packets) {
>>>> +                               mem = odp_packet_data(params.pkt);
>>>> +                               print_mem("Packet before encryption:",
>>>> +                                         mem, payload_length);
>>>> +                       }
>>>> +
>>>> +                       rc = odp_crypto_operation(&params, &posted,
>>>> +                                                 &result);
>>>> +                       if (rc)
>>>> +                               app_err("failed odp_crypto_operation:
>>>> rc = %d\n",
>>>> +                                       rc);
>>>> +                       else
>>>> +                               packets_sent++;
>>>> +               }
>>>> +
>>>> +               if (!posted) {
>>>> +                       packets_received++;
>>>> +                       if (cargs->debug_packets) {
>>>> +                               mem = odp_packet_data(params.out_pkt);
>>>> +                               print_mem("Imediately encrypted
>>>> packet", mem,
>>>> +                                         payload_length +
>>>> +                                         config->hash_adjust);
>>>> +                       }
>>>> +                       if (!cargs->in_place) {
>>>> +                               if (cargs->reuse_packet) {
>>>> +                                       params.pkt = params.out_pkt;
>>>> +                                       params.out_pkt =
>>>> ODP_PACKET_INVALID;
>>>> +                               } else {
>>>> +                                       odp_packet_free(params.out_pkt);
>>>> +                               }
>>>> +                       }
>>>> +               } else {
>>>> +                       odp_event_t ev;
>>>> +                       odp_crypto_compl_t compl;
>>>> +                       odp_crypto_op_result_t result;
>>>> +                       odp_packet_t out_pkt;
>>>> +
>>>> +                       if (cargs->schedule)
>>>> +                               ev = odp_schedule(NULL,
>>>> +                                                 ODP_SCHED_NO_WAIT);
>>>> +                       else
>>>> +                               ev = odp_queue_deq(out_queue);
>>>> +
>>>> +                       while (ev != ODP_EVENT_INVALID) {
>>>> +                               compl = odp_crypto_compl_from_event(ev);
>>>> +                               odp_crypto_compl_result(compl, &result);
>>>> +                               odp_crypto_compl_free(compl);
>>>> +                               out_pkt = result.pkt;
>>>> +
>>>> +                               if (cargs->debug_packets) {
>>>> +                                       mem = odp_packet_data(out_pkt);
>>>> +                                       print_mem("Receieved encrypted
>>>> packet",
>>>> +                                                 mem,
>>>> +                                                 payload_length +
>>>> +                                                 config->hash_adjust);
>>>> +                               }
>>>> +                               if (cargs->reuse_packet) {
>>>> +                                       params.pkt = out_pkt;
>>>> +                                       params.out_pkt =
>>>> ODP_PACKET_INVALID;
>>>> +                               } else {
>>>> +                                       odp_packet_free(out_pkt);
>>>> +                               }
>>>> +                               packets_received++;
>>>> +                               if (cargs->schedule)
>>>> +                                       ev = odp_schedule(NULL,
>>>> +
>>>>  ODP_SCHED_NO_WAIT);
>>>> +                               else
>>>> +                                       ev = odp_queue_deq(out_queue);
>>>> +                       };
>>>> +               }
>>>> +       }
>>>> +
>>>> +       fill_time_record(&end);
>>>> +
>>>> +       {
>>>> +               double count;
>>>> +
>>>> +               count = get_elapsed_usec(&start, &end);
>>>> +               result->elapsed = count /
>>>> +                                 cargs->iteration_count;
>>>> +
>>>> +               count = get_rusage_self_diff(&start, &end);
>>>> +               result->rusage_self = count /
>>>> +                                     cargs->iteration_count;
>>>> +
>>>> +               count = get_rusage_thread_diff(&start, &end);
>>>> +               result->rusage_thread = count /
>>>> +                                       cargs->iteration_count;
>>>> +       }
>>>> +
>>>> +       return rc;
>>>> +}
>>>> +
>>>> +/**
>>>> + * Process one algorithm. Note if paload size is specicified it is
>>>> + * only one run. Or iterate over set of predefined payloads.
>>>> + */
>>>> +static int
>>>> +run_measure_one_config(crypto_args_t *cargs,
>>>> +                      crypto_alg_config_t *config)
>>>> +{
>>>> +       crypto_run_result_t result;
>>>> +       odp_crypto_session_t session;
>>>> +       int rc = 0;
>>>> +
>>>> +       if (create_session_from_config(&session, config, cargs))
>>>> +               rc = -1;
>>>> +
>>>> +       if (!rc) {
>>>> +               if (cargs->payload_length) {
>>>> +                       rc = run_measure_one(cargs, config, &session,
>>>> +                                            cargs->payload_length,
>>>> &result);
>>>> +                       if (!rc) {
>>>> +                               print_result_header();
>>>> +                               print_result(cargs,
>>>> cargs->payload_length,
>>>> +                                            config, &result);
>>>> +                       }
>>>> +               } else {
>>>> +                       unsigned int i;
>>>> +
>>>> +                       print_result_header();
>>>> +                       for (i = 0;
>>>> +                            i < (sizeof(payloads) / sizeof(unsigned
>>>> int));
>>>> +                            i++) {
>>>> +                               rc = run_measure_one(cargs, config,
>>>> &session,
>>>> +                                                    payloads[i],
>>>> &result);
>>>> +                               if (rc)
>>>> +                                       break;
>>>> +                               print_result(cargs, payloads[i],
>>>> +                                            config, &result);
>>>> +                       }
>>>> +               }
>>>> +       }
>>>> +
>>>> +       if (session != ODP_CRYPTO_SESSION_INVALID)
>>>> +               odp_crypto_session_destroy(session);
>>>> +       return rc;
>>>> +}
>>>> +
>>>> +typedef struct thr_arg {
>>>> +       crypto_args_t crypto_args;
>>>> +       crypto_alg_config_t *crypto_alg_config;
>>>> +} thr_arg_t;
>>>> +
>>>> +static void *run_thr_func(void *arg)
>>>> +{
>>>> +       thr_arg_t *thr_args = (thr_arg_t *)arg;
>>>> +
>>>> +       run_measure_one_config(&thr_args->crypto_args,
>>>> +                              thr_args->crypto_alg_config);
>>>> +       return NULL;
>>>> +}
>>>> +
>>>> +int main(int argc, char *argv[])
>>>> +{
>>>> +       crypto_args_t cargs;
>>>> +       odp_pool_t pool;
>>>> +       odp_queue_param_t qparam;
>>>> +       odp_pool_param_t params;
>>>> +       odph_linux_pthread_t thr;
>>>> +       odp_queue_t out_queue = ODP_QUEUE_INVALID;
>>>> +       thr_arg_t thr_arg;
>>>> +       int num_workers = 1;
>>>> +       odp_cpumask_t cpumask;
>>>> +       char cpumaskstr[ODP_CPUMASK_STR_SIZE];
>>>> +
>>>> +       /* Parse and store the application arguments */
>>>> +       parse_args(argc, argv, &cargs);
>>>> +
>>>> +       /* Init ODP before calling anything else */
>>>> +       if (odp_init_global(NULL, NULL)) {
>>>> +               app_err("ODP global init failed.\n");
>>>> +               exit(EXIT_FAILURE);
>>>> +       }
>>>> +
>>>> +       /* Init this thread */
>>>> +       odp_init_local(ODP_THREAD_WORKER);
>>>> +
>>>> +       /* Create packet pool */
>>>> +       odp_pool_param_init(&params);
>>>> +       params.pkt.seg_len = SHM_PKT_POOL_BUF_SIZE;
>>>> +       params.pkt.len     = SHM_PKT_POOL_BUF_SIZE;
>>>> +       params.pkt.num     = SHM_PKT_POOL_SIZE / SHM_PKT_POOL_BUF_SIZE;
>>>> +       params.type        = ODP_POOL_PACKET;
>>>> +       pool = odp_pool_create("packet_pool", &params);
>>>> +
>>>> +       if (pool == ODP_POOL_INVALID) {
>>>> +               app_err("packet pool create failed.\n");
>>>> +               exit(EXIT_FAILURE);
>>>> +       }
>>>> +       odp_pool_print(pool);
>>>> +
>>>> +       if (cargs.schedule) {
>>>> +               qparam.sched.prio  = ODP_SCHED_PRIO_DEFAULT;
>>>> +               qparam.sched.sync  = ODP_SCHED_SYNC_NONE;
>>>> +               qparam.sched.group = ODP_SCHED_GROUP_ALL;
>>>> +               out_queue = odp_queue_create("crypto-out",
>>>> +                                            ODP_QUEUE_TYPE_SCHED,
>>>> &qparam);
>>>> +       } else if (cargs.poll) {
>>>> +               out_queue = odp_queue_create("crypto-out",
>>>> +                                            ODP_QUEUE_TYPE_POLL, NULL);
>>>> +       }
>>>> +       if (cargs.schedule || cargs.poll) {
>>>> +               if (out_queue == ODP_QUEUE_INVALID) {
>>>> +                       app_err("crypto-out queue create failed.\n");
>>>> +                       exit(EXIT_FAILURE);
>>>> +               }
>>>> +       }
>>>> +
>>>> +       if (cargs.schedule) {
>>>> +               printf("Run in async scheduled mode\n");
>>>> +
>>>> +               thr_arg.crypto_args = cargs;
>>>> +               thr_arg.crypto_alg_config = cargs.alg_config;
>>>> +               num_workers = odp_cpumask_default_worker(&cpumask,
>>>> +                                                        num_workers);
>>>> +               (void)odp_cpumask_to_str(&cpumask, cpumaskstr,
>>>> +                                        sizeof(cpumaskstr));
>>>> +               printf("num worker threads:  %i\n",
>>>> +                      num_workers);
>>>> +               printf("first CPU:           %i\n",
>>>> +                      odp_cpumask_first(&cpumask));
>>>> +               printf("cpu mask:            %s\n",
>>>> +                      cpumaskstr);
>>>> +       } else if (cargs.poll) {
>>>> +               printf("Run in async poll mode\n");
>>>> +       } else {
>>>> +               printf("Run in sync mode\n");
>>>> +       }
>>>> +
>>>> +       if (cargs.alg_config) {
>>>> +               if (cargs.schedule) {
>>>> +                       odph_linux_pthread_create(&thr, &cpumask,
>>>> +                                                 run_thr_func,
>>>> +                                                 &thr_arg,
>>>> +                                                 ODP_THREAD_WORKER);
>>>> +                       odph_linux_pthread_join(&thr, num_workers);
>>>> +               } else {
>>>> +                       run_measure_one_config(&cargs,
>>>> cargs.alg_config);
>>>> +               }
>>>> +       } else {
>>>> +               unsigned int i;
>>>> +
>>>> +               for (i = 0;
>>>> +                    i < (sizeof(algs_config) /
>>>> sizeof(crypto_alg_config_t));
>>>> +                    i++) {
>>>> +                       run_measure_one_config(&cargs, algs_config + i);
>>>> +               }
>>>> +       }
>>>> +
>>>> +       return 0;
>>>> +}
>>>> +
>>>> +static void parse_args(int argc, char *argv[], crypto_args_t *cargs)
>>>> +{
>>>> +       int opt;
>>>> +       int long_index;
>>>> +       static struct option longopts[] = {
>>>> +               {"algorithm", optional_argument, NULL, 'a'},
>>>> +               {"debug",  no_argument, NULL, 'd'},
>>>> +               {"flight", optional_argument, NULL, 'f'},
>>>> +               {"help", no_argument, NULL, 'h'},
>>>> +               {"iterations", optional_argument, NULL, 'i'},
>>>> +               {"inplace", no_argument, NULL, 'n'},
>>>> +               {"payload", optional_argument, NULL, 'l'},
>>>> +               {"sessions", optional_argument, NULL, 'm'},
>>>> +               {"reuse", no_argument, NULL, 'r'},
>>>> +               {"poll", no_argument, NULL, 'p'},
>>>> +               {"schedule", no_argument, NULL, 's'},
>>>> +               {NULL, 0, NULL, 0}
>>>> +       };
>>>> +
>>>> +       cargs->in_place = 0;
>>>> +       cargs->in_flight = 1;
>>>> +       cargs->debug_packets = 0;
>>>> +       cargs->iteration_count = 10000;
>>>> +       cargs->payload_length = 0;
>>>> +       cargs->alg_config = NULL;
>>>> +       cargs->reuse_packet = 0;
>>>> +       cargs->schedule = 0;
>>>> +
>>>> +       while (1) {
>>>> +               opt = getopt_long(argc, argv, "+a:c:df:hi:m:nl:spr",
>>>> +                                 longopts, &long_index);
>>>> +
>>>> +               if (opt == -1)
>>>> +                       break;  /* No more options */
>>>> +
>>>> +               switch (opt) {
>>>> +               case 'a':
>>>> +                       cargs->alg_config = find_config_by_name(optarg);
>>>> +                       if (!cargs->alg_config) {
>>>> +                               printf("cannot test crypto '%s'
>>>> configuration\n",
>>>> +                                      optarg);
>>>> +                               usage(argv[0]);
>>>> +                               exit(-1);
>>>> +                       }
>>>> +               case 'd':
>>>> +                       cargs->debug_packets = 1;
>>>> +                       break;
>>>> +               case 'i':
>>>> +                       cargs->iteration_count = atoi(optarg);
>>>> +                       break;
>>>> +               case 'f':
>>>> +                       cargs->in_flight = atoi(optarg);
>>>> +                       break;
>>>> +               case 'h':
>>>> +                       usage(argv[0]);
>>>> +                       exit(EXIT_SUCCESS);
>>>> +                       break;
>>>> +               case 'm':
>>>> +                       cargs->max_sessions = atoi(optarg);
>>>> +                       break;
>>>> +               case 'n':
>>>> +                       cargs->in_place = 1;
>>>> +                       break;
>>>> +               case 'l':
>>>> +                       cargs->payload_length = atoi(optarg);
>>>> +                       break;
>>>> +               case 'r':
>>>> +                       cargs->reuse_packet = 1;
>>>> +                       break;
>>>> +               case 's':
>>>> +                       cargs->schedule = 1;
>>>> +                       break;
>>>> +               case 'p':
>>>> +                       cargs->poll = 1;
>>>> +                       break;
>>>> +               default:
>>>> +                       break;
>>>> +               }
>>>> +       }
>>>> +
>>>> +       optind = 1;             /* reset 'extern optind' from the
>>>> getopt lib */
>>>> +
>>>> +       if ((cargs->in_flight > 1) && cargs->reuse_packet) {
>>>> +               printf("-f (in flight > 1) and -r (reuse packet)
>>>> options are not compatible\n");
>>>> +               usage(argv[0]);
>>>> +               exit(-1);
>>>> +       }
>>>> +       if (cargs->schedule && cargs->poll) {
>>>> +               printf("-s (schedule) and -p (poll) options are not
>>>> compatible\n");
>>>> +               usage(argv[0]);
>>>> +               exit(-1);
>>>> +       }
>>>> +}
>>>> +
>>>> +/**
>>>> + * Prinf usage information
>>>> + */
>>>> +static void usage(char *progname)
>>>> +{
>>>> +       printf("\n"
>>>> +              "Usage: %s OPTIONS\n"
>>>> +              "  E.g. %s -i 100000\n"
>>>> +              "\n"
>>>> +              "OpenDataPlane crypto speed measure.\n"
>>>> +              "Optional OPTIONS\n"
>>>> +              "  -a, --algorithm <name> Specify algorithm name
>>>> (default all)\n"
>>>> +              "                         Supported values are:\n",
>>>> +              progname, progname);
>>>> +
>>>> +       print_config_names("                                  ");
>>>> +       printf("  -d, --debug          Enable dump of processed
>>>> packets.\n"
>>>> +              "  -f, --flight <number> Max number of packet processed
>>>> in parallel (default 1)\n"
>>>> +              "  -i, --iterations <number> Number of iterations.\n"
>>>> +              "  -n, --inplace        Encrypt on place.\n"
>>>> +              "  -l, --payload        Payload length.\n"
>>>> +              "  -r, --reuse          Output encrypted packet is
>>>> passed as input\n"
>>>> +              "                       to next encrypt iteration.\n"
>>>> +              "  -s, --schedule       Use scheduler for completion
>>>> events.\n"
>>>> +              "  -p, --poll           Poll completion queue for
>>>> completion events.\n"
>>>> +              "  -h, --help           Display help and exit.\n"
>>>> +              "\n");
>>>> +}
>>>>
>>>
>>> _______________________________________________
>>> lng-odp mailing list
>>> [email protected]
>>> https://lists.linaro.org/mailman/listinfo/lng-odp
>>>
>>
>>
>> _______________________________________________
>> lng-odp mailing list
>> [email protected]
>> https://lists.linaro.org/mailman/listinfo/lng-odp
>>
>>
>
_______________________________________________
lng-odp mailing list
[email protected]
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to