X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=app%2Ftest-crypto-perf%2Fmain.c;h=390380898eb3d57009f77baf4bbeb0ef964471fa;hb=c823434174da3d6c632de2540ee70f105fe65fcc;hp=019d83598728803432a43ab01b848a5670d0c29c;hpb=7629b31f840b8e4da78404077e38ad1efe497e5e;p=dpdk.git diff --git a/app/test-crypto-perf/main.c b/app/test-crypto-perf/main.c index 019d835987..390380898e 100644 --- a/app/test-crypto-perf/main.c +++ b/app/test-crypto-perf/main.c @@ -9,7 +9,7 @@ #include #include #include -#ifdef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER +#ifdef RTE_CRYPTO_SCHEDULER #include #endif @@ -21,8 +21,10 @@ #include "cperf_test_verify.h" #include "cperf_test_pmd_cyclecount.h" -#define NUM_SESSIONS 2048 -#define SESS_MEMPOOL_CACHE_SIZE 64 +static struct { + struct rte_mempool *sess_mp; + struct rte_mempool *priv_mp; +} session_pool_socket[RTE_MAX_NUMA_NODES]; const char *cperf_test_type_strs[] = { [CPERF_TEST_TYPE_THROUGHPUT] = "throughput", @@ -36,7 +38,10 @@ const char *cperf_op_type_strs[] = { [CPERF_AUTH_ONLY] = "auth-only", [CPERF_CIPHER_THEN_AUTH] = "cipher-then-auth", [CPERF_AUTH_THEN_CIPHER] = "auth-then-cipher", - [CPERF_AEAD] = "aead" + [CPERF_AEAD] = "aead", + [CPERF_PDCP] = "pdcp", + [CPERF_DOCSIS] = "docsis", + [CPERF_ASYM_MODEX] = "modex" }; const struct cperf_test cperf_testmap[] = { @@ -63,10 +68,105 @@ const struct cperf_test cperf_testmap[] = { }; static int -cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs, - struct rte_mempool *session_pool_socket[]) +create_asym_op_pool_socket(uint8_t dev_id, int32_t socket_id, + uint32_t nb_sessions) +{ + char mp_name[RTE_MEMPOOL_NAMESIZE]; + struct rte_mempool *mpool = NULL; + unsigned int session_size = + RTE_MAX(rte_cryptodev_asym_get_private_session_size(dev_id), + rte_cryptodev_asym_get_header_session_size()); + + if (session_pool_socket[socket_id].priv_mp == NULL) { + snprintf(mp_name, RTE_MEMPOOL_NAMESIZE, "perf_asym_priv_pool%u", + socket_id); + + mpool = rte_mempool_create(mp_name, nb_sessions, session_size, + 0, 0, NULL, NULL, NULL, NULL, + socket_id, 0); + if (mpool == NULL) { + printf("Cannot create pool \"%s\" on socket %d\n", + mp_name, socket_id); + return -ENOMEM; + } + printf("Allocated pool \"%s\" on socket %d\n", mp_name, + socket_id); + session_pool_socket[socket_id].priv_mp = mpool; + } + + if (session_pool_socket[socket_id].sess_mp == NULL) { + + snprintf(mp_name, RTE_MEMPOOL_NAMESIZE, "perf_asym_sess_pool%u", + socket_id); + mpool = rte_mempool_create(mp_name, nb_sessions, + session_size, 0, 0, NULL, NULL, NULL, + NULL, socket_id, 0); + if (mpool == NULL) { + printf("Cannot create pool \"%s\" on socket %d\n", + mp_name, socket_id); + return -ENOMEM; + } + session_pool_socket[socket_id].sess_mp = mpool; + } + return 0; +} + +static int +fill_session_pool_socket(int32_t socket_id, uint32_t session_priv_size, + uint32_t nb_sessions) +{ + char mp_name[RTE_MEMPOOL_NAMESIZE]; + struct rte_mempool *sess_mp; + + if (session_pool_socket[socket_id].priv_mp == NULL) { + snprintf(mp_name, RTE_MEMPOOL_NAMESIZE, + "priv_sess_mp_%u", socket_id); + + sess_mp = rte_mempool_create(mp_name, + nb_sessions, + session_priv_size, + 0, 0, NULL, NULL, NULL, + NULL, socket_id, + 0); + + if (sess_mp == NULL) { + printf("Cannot create pool \"%s\" on socket %d\n", + mp_name, socket_id); + return -ENOMEM; + } + + printf("Allocated pool \"%s\" on socket %d\n", + mp_name, socket_id); + session_pool_socket[socket_id].priv_mp = sess_mp; + } + + if (session_pool_socket[socket_id].sess_mp == NULL) { + + snprintf(mp_name, RTE_MEMPOOL_NAMESIZE, + "sess_mp_%u", socket_id); + + sess_mp = rte_cryptodev_sym_session_pool_create(mp_name, + nb_sessions, 0, 0, 0, socket_id); + + if (sess_mp == NULL) { + printf("Cannot create pool \"%s\" on socket %d\n", + mp_name, socket_id); + return -ENOMEM; + } + + printf("Allocated pool \"%s\" on socket %d\n", + mp_name, socket_id); + session_pool_socket[socket_id].sess_mp = sess_mp; + } + + return 0; +} + +static int +cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs) { uint8_t enabled_cdev_count = 0, nb_lcores, cdev_id; + uint32_t sessions_needed = 0; unsigned int i, j; int ret; @@ -80,22 +180,35 @@ cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs, nb_lcores = rte_lcore_count() - 1; - if (enabled_cdev_count > nb_lcores) { - printf("Number of capable crypto devices (%d) " - "has to be less or equal to number of slave " - "cores (%d)\n", enabled_cdev_count, nb_lcores); + if (nb_lcores < 1) { + RTE_LOG(ERR, USER1, + "Number of enabled cores need to be higher than 1\n"); return -EINVAL; } + /* + * Use less number of devices, + * if there are more available than cores. + */ + if (enabled_cdev_count > nb_lcores) + enabled_cdev_count = nb_lcores; + /* Create a mempool shared by all the devices */ uint32_t max_sess_size = 0, sess_size; for (cdev_id = 0; cdev_id < rte_cryptodev_count(); cdev_id++) { - sess_size = rte_cryptodev_get_private_session_size(cdev_id); + sess_size = rte_cryptodev_sym_get_private_session_size(cdev_id); if (sess_size > max_sess_size) max_sess_size = sess_size; } - +#ifdef RTE_LIB_SECURITY + for (cdev_id = 0; cdev_id < rte_cryptodev_count(); cdev_id++) { + sess_size = rte_security_session_get_size( + rte_cryptodev_get_sec_ctx(cdev_id)); + if (sess_size > max_sess_size) + max_sess_size = sess_size; + } +#endif /* * Calculate number of needed queue pairs, based on the amount * of available number of logical cores and crypto devices. @@ -109,7 +222,7 @@ cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs, for (i = 0; i < enabled_cdev_count && i < RTE_CRYPTO_MAX_DEVS; i++) { cdev_id = enabled_cdevs[i]; -#ifdef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER +#ifdef RTE_CRYPTO_SCHEDULER /* * If multi-core scheduler is used, limit the number * of queue pairs to 1, as there is no way to know @@ -124,8 +237,20 @@ cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs, struct rte_cryptodev_info cdev_info; uint8_t socket_id = rte_cryptodev_socket_id(cdev_id); + /* range check the socket_id - negative values become big + * positive ones due to use of unsigned value + */ + if (socket_id >= RTE_MAX_NUMA_NODES) + socket_id = 0; rte_cryptodev_info_get(cdev_id, &cdev_info); + + if (opts->op_type == CPERF_ASYM_MODEX) { + if ((cdev_info.feature_flags & + RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO) == 0) + continue; + } + if (opts->nb_qps > cdev_info.max_nb_queue_pairs) { printf("Number of needed queue pairs is higher " "than the maximum number of queue pairs " @@ -136,36 +261,95 @@ cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs, } struct rte_cryptodev_config conf = { .nb_queue_pairs = opts->nb_qps, - .socket_id = socket_id + .socket_id = socket_id, }; + switch (opts->op_type) { + case CPERF_ASYM_MODEX: + conf.ff_disable |= (RTE_CRYPTODEV_FF_SECURITY | + RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO); + break; + case CPERF_CIPHER_ONLY: + case CPERF_AUTH_ONLY: + case CPERF_CIPHER_THEN_AUTH: + case CPERF_AUTH_THEN_CIPHER: + case CPERF_AEAD: + conf.ff_disable |= RTE_CRYPTODEV_FF_SECURITY; + /* Fall through */ + case CPERF_PDCP: + case CPERF_DOCSIS: + /* Fall through */ + default: + + conf.ff_disable |= RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO; + } + struct rte_cryptodev_qp_conf qp_conf = { .nb_descriptors = opts->nb_descriptors }; - if (session_pool_socket[socket_id] == NULL) { - char mp_name[RTE_MEMPOOL_NAMESIZE]; - struct rte_mempool *sess_mp; - - snprintf(mp_name, RTE_MEMPOOL_NAMESIZE, - "sess_mp_%u", socket_id); - - sess_mp = rte_mempool_create(mp_name, - NUM_SESSIONS, - max_sess_size, - SESS_MEMPOOL_CACHE_SIZE, - 0, NULL, NULL, NULL, - NULL, socket_id, - 0); - - if (sess_mp == NULL) { - printf("Cannot create session pool on socket %d\n", - socket_id); - return -ENOMEM; - } + /** + * Device info specifies the min headroom and tailroom + * requirement for the crypto PMD. This need to be honoured + * by the application, while creating mbuf. + */ + if (opts->headroom_sz < cdev_info.min_mbuf_headroom_req) { + /* Update headroom */ + opts->headroom_sz = cdev_info.min_mbuf_headroom_req; + } + if (opts->tailroom_sz < cdev_info.min_mbuf_tailroom_req) { + /* Update tailroom */ + opts->tailroom_sz = cdev_info.min_mbuf_tailroom_req; + } + + /* Update segment size to include headroom & tailroom */ + opts->segment_sz += (opts->headroom_sz + opts->tailroom_sz); + + uint32_t dev_max_nb_sess = cdev_info.sym.max_nb_sessions; + /* + * Two sessions objects are required for each session + * (one for the header, one for the private data) + */ + if (!strcmp((const char *)opts->device_type, + "crypto_scheduler")) { +#ifdef RTE_CRYPTO_SCHEDULER + uint32_t nb_slaves = + rte_cryptodev_scheduler_workers_get(cdev_id, + NULL); + + sessions_needed = enabled_cdev_count * + opts->nb_qps * nb_slaves; +#endif + } else + sessions_needed = enabled_cdev_count * opts->nb_qps; - printf("Allocated session pool on socket %d\n", socket_id); - session_pool_socket[socket_id] = sess_mp; + /* + * A single session is required per queue pair + * in each device + */ + if (dev_max_nb_sess != 0 && dev_max_nb_sess < opts->nb_qps) { + RTE_LOG(ERR, USER1, + "Device does not support at least " + "%u sessions\n", opts->nb_qps); + return -ENOTSUP; + } + + if (opts->op_type == CPERF_ASYM_MODEX) + ret = create_asym_op_pool_socket(cdev_id, socket_id, + sessions_needed); + else + ret = fill_session_pool_socket(socket_id, max_sess_size, + sessions_needed); + if (ret < 0) + return ret; + + qp_conf.mp_session = session_pool_socket[socket_id].sess_mp; + qp_conf.mp_session_private = + session_pool_socket[socket_id].priv_mp; + + if (opts->op_type == CPERF_ASYM_MODEX) { + qp_conf.mp_session = NULL; + qp_conf.mp_session_private = NULL; } ret = rte_cryptodev_configure(cdev_id, &conf); @@ -176,8 +360,7 @@ cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs, for (j = 0; j < opts->nb_qps; j++) { ret = rte_cryptodev_queue_pair_setup(cdev_id, j, - &qp_conf, socket_id, - session_pool_socket[socket_id]); + &qp_conf, socket_id); if (ret < 0) { printf("Failed to setup queue pair %u on " "cryptodev %u", j, cdev_id); @@ -202,6 +385,9 @@ cperf_verify_devices_capabilities(struct cperf_options *opts, { struct rte_cryptodev_sym_capability_idx cap_idx; const struct rte_cryptodev_symmetric_capability *capability; + struct rte_cryptodev_asym_capability_idx asym_cap_idx; + const struct rte_cryptodev_asymmetric_xform_capability *asym_capability; + uint8_t i, cdev_id; int ret; @@ -210,6 +396,20 @@ cperf_verify_devices_capabilities(struct cperf_options *opts, cdev_id = enabled_cdevs[i]; + if (opts->op_type == CPERF_ASYM_MODEX) { + asym_cap_idx.type = RTE_CRYPTO_ASYM_XFORM_MODEX; + asym_capability = rte_cryptodev_asym_capability_get( + cdev_id, &asym_cap_idx); + if (asym_capability == NULL) + return -1; + + ret = rte_cryptodev_asym_xform_capability_check_modlen( + asym_capability, sizeof(perf_mod_p)); + if (ret != 0) + return ret; + + } + if (opts->op_type == CPERF_AUTH_ONLY || opts->op_type == CPERF_CIPHER_THEN_AUTH || opts->op_type == CPERF_AUTH_THEN_CIPHER) { @@ -283,7 +483,7 @@ cperf_check_test_vector(struct cperf_options *opts, if (opts->cipher_algo == RTE_CRYPTO_CIPHER_NULL) { if (test_vec->plaintext.data == NULL) return -1; - } else if (opts->cipher_algo != RTE_CRYPTO_CIPHER_NULL) { + } else { if (test_vec->plaintext.data == NULL) return -1; if (test_vec->plaintext.length < opts->max_buffer_size) @@ -292,7 +492,9 @@ cperf_check_test_vector(struct cperf_options *opts, return -1; if (test_vec->ciphertext.length < opts->max_buffer_size) return -1; - if (test_vec->cipher_iv.data == NULL) + /* Cipher IV is only required for some algorithms */ + if (opts->cipher_iv_sz && + test_vec->cipher_iv.data == NULL) return -1; if (test_vec->cipher_iv.length != opts->cipher_iv_sz) return -1; @@ -307,7 +509,9 @@ cperf_check_test_vector(struct cperf_options *opts, return -1; if (test_vec->plaintext.length < opts->max_buffer_size) return -1; - if (test_vec->auth_key.data == NULL) + /* Auth key is only required for some algorithms */ + if (opts->auth_key_sz && + test_vec->auth_key.data == NULL) return -1; if (test_vec->auth_key.length != opts->auth_key_sz) return -1; @@ -329,7 +533,7 @@ cperf_check_test_vector(struct cperf_options *opts, return -1; if (test_vec->plaintext.length < opts->max_buffer_size) return -1; - } else if (opts->cipher_algo != RTE_CRYPTO_CIPHER_NULL) { + } else { if (test_vec->plaintext.data == NULL) return -1; if (test_vec->plaintext.length < opts->max_buffer_size) @@ -371,6 +575,10 @@ cperf_check_test_vector(struct cperf_options *opts, return -1; if (test_vec->ciphertext.length < opts->max_buffer_size) return -1; + if (test_vec->aead_key.data == NULL) + return -1; + if (test_vec->aead_key.length != opts->aead_key_sz) + return -1; if (test_vec->aead_iv.data == NULL) return -1; if (test_vec->aead_iv.length != opts->aead_iv_sz) @@ -393,10 +601,7 @@ main(int argc, char **argv) struct cperf_options opts = {0}; struct cperf_test_vector *t_vec = NULL; struct cperf_op_fns op_fns; - void *ctx[RTE_MAX_LCORE] = { }; - struct rte_mempool *session_pool_socket[RTE_MAX_NUMA_NODES] = { 0 }; - int nb_cryptodevs = 0; uint16_t total_nb_qps = 0; uint8_t cdev_id, i; @@ -418,19 +623,18 @@ main(int argc, char **argv) ret = cperf_options_parse(&opts, argc, argv); if (ret) { - RTE_LOG(ERR, USER1, "Parsing on or more user options failed\n"); + RTE_LOG(ERR, USER1, "Parsing one or more user options failed\n"); goto err; } ret = cperf_options_check(&opts); if (ret) { RTE_LOG(ERR, USER1, - "Checking on or more user options failed\n"); + "Checking one or more user options failed\n"); goto err; } - nb_cryptodevs = cperf_initialize_cryptodev(&opts, enabled_cdevs, - session_pool_socket); + nb_cryptodevs = cperf_initialize_cryptodev(&opts, enabled_cdevs); if (!opts.silent) cperf_options_dump(&opts); @@ -481,14 +685,15 @@ main(int argc, char **argv) goto err; } - if (!opts.silent) + if (!opts.silent && opts.test != CPERF_TEST_TYPE_THROUGHPUT && + opts.test != CPERF_TEST_TYPE_LATENCY) show_test_vector(t_vec); total_nb_qps = nb_cryptodevs * opts.nb_qps; i = 0; uint8_t qp_id = 0, cdev_index = 0; - RTE_LCORE_FOREACH_SLAVE(lcore_id) { + RTE_LCORE_FOREACH_WORKER(lcore_id) { if (i == total_nb_qps) break; @@ -498,7 +703,9 @@ main(int argc, char **argv) uint8_t socket_id = rte_cryptodev_socket_id(cdev_id); ctx[i] = cperf_testmap[opts.test].constructor( - session_pool_socket[socket_id], cdev_id, qp_id, + session_pool_socket[socket_id].sess_mp, + session_pool_socket[socket_id].priv_mp, + cdev_id, qp_id, &opts, t_vec, &op_fns); if (ctx[i] == NULL) { RTE_LOG(ERR, USER1, "Test run constructor failed\n"); @@ -550,7 +757,7 @@ main(int argc, char **argv) distribution_total[buffer_size_count - 1]; i = 0; - RTE_LCORE_FOREACH_SLAVE(lcore_id) { + RTE_LCORE_FOREACH_WORKER(lcore_id) { if (i == total_nb_qps) break; @@ -560,13 +767,16 @@ main(int argc, char **argv) i++; } i = 0; - RTE_LCORE_FOREACH_SLAVE(lcore_id) { + RTE_LCORE_FOREACH_WORKER(lcore_id) { if (i == total_nb_qps) break; - rte_eal_wait_lcore(lcore_id); + ret |= rte_eal_wait_lcore(lcore_id); i++; } + + if (ret != EXIT_SUCCESS) + goto err; } else { /* Get next size from range or list */ @@ -577,7 +787,7 @@ main(int argc, char **argv) while (opts.test_buffer_size <= opts.max_buffer_size) { i = 0; - RTE_LCORE_FOREACH_SLAVE(lcore_id) { + RTE_LCORE_FOREACH_WORKER(lcore_id) { if (i == total_nb_qps) break; @@ -587,14 +797,17 @@ main(int argc, char **argv) i++; } i = 0; - RTE_LCORE_FOREACH_SLAVE(lcore_id) { + RTE_LCORE_FOREACH_WORKER(lcore_id) { if (i == total_nb_qps) break; - rte_eal_wait_lcore(lcore_id); + ret |= rte_eal_wait_lcore(lcore_id); i++; } + if (ret != EXIT_SUCCESS) + goto err; + /* Get next size from range or list */ if (opts.inc_buffer_size != 0) opts.test_buffer_size += opts.inc_buffer_size; @@ -608,7 +821,7 @@ main(int argc, char **argv) } i = 0; - RTE_LCORE_FOREACH_SLAVE(lcore_id) { + RTE_LCORE_FOREACH_WORKER(lcore_id) { if (i == total_nb_qps) break; @@ -618,8 +831,13 @@ main(int argc, char **argv) } for (i = 0; i < nb_cryptodevs && - i < RTE_CRYPTO_MAX_DEVS; i++) + i < RTE_CRYPTO_MAX_DEVS; i++) { rte_cryptodev_stop(enabled_cdevs[i]); + ret = rte_cryptodev_close(enabled_cdevs[i]); + if (ret) + RTE_LOG(ERR, USER1, + "Crypto device close error %d\n", ret); + } free_test_vector(t_vec, &opts); @@ -628,7 +846,7 @@ main(int argc, char **argv) err: i = 0; - RTE_LCORE_FOREACH_SLAVE(lcore_id) { + RTE_LCORE_FOREACH_WORKER(lcore_id) { if (i == total_nb_qps) break; @@ -638,8 +856,14 @@ err: } for (i = 0; i < nb_cryptodevs && - i < RTE_CRYPTO_MAX_DEVS; i++) + i < RTE_CRYPTO_MAX_DEVS; i++) { rte_cryptodev_stop(enabled_cdevs[i]); + ret = rte_cryptodev_close(enabled_cdevs[i]); + if (ret) + RTE_LOG(ERR, USER1, + "Crypto device close error %d\n", ret); + + } rte_free(opts.imix_buffer_sizes); free_test_vector(t_vec, &opts);