diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c index e8d1eae9e5..0f0cf4d68c 100644 --- a/app/test/test_cryptodev.c +++ b/app/test/test_cryptodev.c @@ -348,6 +348,28 @@ testsuite_setup(void) } } + /* Create 2 ARMv8 devices if required */ + if (gbl_cryptodev_type == RTE_CRYPTODEV_ARMV8_PMD) { +#ifndef RTE_LIBRTE_PMD_ARMV8_CRYPTO + RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_ARMV8_CRYPTO must be" + " enabled in config file to run this testsuite.\n"); + return TEST_FAILED; +#endif + nb_devs = rte_cryptodev_count_devtype( + RTE_CRYPTODEV_ARMV8_PMD); + if (nb_devs < 2) { + for (i = nb_devs; i < 2; i++) { + ret = rte_eal_vdev_init( + RTE_STR(CRYPTODEV_NAME_ARMV8_PMD), + NULL); + + TEST_ASSERT(ret == 0, "Failed to create " + "instance %u of pmd : %s", i, + RTE_STR(CRYPTODEV_NAME_ARMV8_PMD)); + } + } + } + #ifndef RTE_LIBRTE_PMD_QAT if (gbl_cryptodev_type == RTE_CRYPTODEV_QAT_SYM_PMD) { RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_QAT must be enabled " @@ -1593,6 +1615,22 @@ test_authonly_openssl_all(void) return TEST_SUCCESS; } +static int +test_AES_chain_armv8_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_ARMV8_PMD, + BLKCIPHER_AES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + /* ***** SNOW 3G Tests ***** */ static int create_wireless_algo_hash_session(uint8_t dev_id, @@ -7847,6 +7885,23 @@ static struct unit_test_suite cryptodev_null_testsuite = { } }; +static struct unit_test_suite cryptodev_armv8_testsuite = { + .suite_name = "Crypto Device ARMv8 Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_armv8_all), + + /** Negative tests */ + TEST_CASE_ST(ut_setup, ut_teardown, + auth_decryption_AES128CBC_HMAC_SHA1_fail_data_corrupt), + TEST_CASE_ST(ut_setup, ut_teardown, + auth_decryption_AES128CBC_HMAC_SHA1_fail_tag_corrupt), + + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + static int test_cryptodev_qat(void /*argv __rte_unused, int argc __rte_unused*/) { @@ -7910,6 +7965,14 @@ test_cryptodev_sw_zuc(void /*argv __rte_unused, int argc __rte_unused*/) return unit_test_suite_runner(&cryptodev_sw_zuc_testsuite); } +static int +test_cryptodev_armv8(void) +{ + gbl_cryptodev_type = RTE_CRYPTODEV_ARMV8_PMD; + + return unit_test_suite_runner(&cryptodev_armv8_testsuite); +} + REGISTER_TEST_COMMAND(cryptodev_qat_autotest, test_cryptodev_qat); REGISTER_TEST_COMMAND(cryptodev_aesni_mb_autotest, test_cryptodev_aesni_mb); REGISTER_TEST_COMMAND(cryptodev_openssl_autotest, test_cryptodev_openssl); @@ -7918,3 +7981,4 @@ REGISTER_TEST_COMMAND(cryptodev_null_autotest, test_cryptodev_null); REGISTER_TEST_COMMAND(cryptodev_sw_snow3g_autotest, test_cryptodev_sw_snow3g); REGISTER_TEST_COMMAND(cryptodev_sw_kasumi_autotest, test_cryptodev_sw_kasumi); REGISTER_TEST_COMMAND(cryptodev_sw_zuc_autotest, test_cryptodev_sw_zuc); +REGISTER_TEST_COMMAND(cryptodev_sw_armv8_autotest, test_cryptodev_armv8); diff --git a/app/test/test_cryptodev_aes_test_vectors.h b/app/test/test_cryptodev_aes_test_vectors.h index e566548ff9..f0f37ed9cc 100644 --- a/app/test/test_cryptodev_aes_test_vectors.h +++ b/app/test/test_cryptodev_aes_test_vectors.h @@ -825,6 +825,98 @@ static const struct blockcipher_test_data aes_test_data_11 = { } }; +/** AES-128-CBC SHA256 HMAC test vector (160 bytes) */ +static const struct blockcipher_test_data aes_test_data_12 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 160 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 160 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC, + .auth_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, + 0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60 + }, + .len = 32 + }, + .digest = { + .data = { + 0x92, 0xEC, 0x65, 0x9A, 0x52, 0xCC, 0x50, 0xA5, + 0xEE, 0x0E, 0xDF, 0x1E, 0xA4, 0xC9, 0xC1, 0x04, + 0xD5, 0xDC, 0x78, 0x90, 0xF4, 0xE3, 0x35, 0x62, + 0xAD, 0x95, 0x45, 0x28, 0x5C, 0xF8, 0x8C, 0x0B + }, + .len = 32, + .truncated_len = 16 + } +}; + +/** AES-128-CBC SHA1 HMAC test vector (160 bytes) */ +static const struct blockcipher_test_data aes_test_data_13 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 160 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 160 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x4F, 0x16, 0xEA, 0xF7, 0x4A, 0x88, 0xD3, 0xE0, + 0x0E, 0x12, 0x8B, 0xE7, 0x05, 0xD0, 0x86, 0x48, + 0x22, 0x43, 0x30, 0xA7 + }, + .len = 20, + .truncated_len = 12 + } +}; + static const struct blockcipher_test_case aes_chain_test_cases[] = { { .test_descr = "AES-128-CTR HMAC-SHA1 Encryption Digest", @@ -888,10 +980,18 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest", .test_data = &aes_test_data_4, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 | + BLOCKCIPHER_TEST_TARGET_PMD_MB | BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest " + "(short buffers)", + .test_data = &aes_test_data_13, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 + }, { .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest " "Scatter Gather", @@ -902,34 +1002,57 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, { .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " "Verify", .test_data = &aes_test_data_4, .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 | + BLOCKCIPHER_TEST_TARGET_PMD_MB | BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " + "Verify (short buffers)", + .test_data = &aes_test_data_13, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 + }, { .test_descr = "AES-128-CBC HMAC-SHA256 Encryption Digest", .test_data = &aes_test_data_5, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 | + BLOCKCIPHER_TEST_TARGET_PMD_MB | BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, + { + .test_descr = "AES-128-CBC HMAC-SHA256 Encryption Digest " + "(short buffers)", + .test_data = &aes_test_data_12, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 + }, { .test_descr = "AES-128-CBC HMAC-SHA256 Decryption Digest " "Verify", .test_data = &aes_test_data_5, .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 | + BLOCKCIPHER_TEST_TARGET_PMD_MB | BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, + { + .test_descr = "AES-128-CBC HMAC-SHA256 Decryption Digest " + "Verify (short buffers)", + .test_data = &aes_test_data_12, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 + }, { .test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest", .test_data = &aes_test_data_6, @@ -998,7 +1121,8 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_4, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT | + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL }, { @@ -1007,7 +1131,8 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_4, .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT | + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL }, { @@ -1050,7 +1175,8 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_4, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 | + BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL }, { .test_descr = @@ -1059,7 +1185,8 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_4, .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 | + BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL }, }; diff --git a/app/test/test_cryptodev_blockcipher.c b/app/test/test_cryptodev_blockcipher.c index 01aef3bec5..a48540cc9b 100644 --- a/app/test/test_cryptodev_blockcipher.c +++ b/app/test/test_cryptodev_blockcipher.c @@ -102,6 +102,7 @@ test_blockcipher_one_case(const struct blockcipher_test_case *t, switch (cryptodev_type) { case RTE_CRYPTODEV_QAT_SYM_PMD: case RTE_CRYPTODEV_OPENSSL_PMD: + case RTE_CRYPTODEV_ARMV8_PMD: /* Fall through */ digest_len = tdata->digest.len; break; case RTE_CRYPTODEV_AESNI_MB_PMD: @@ -645,6 +646,9 @@ test_blockcipher_all_tests(struct rte_mempool *mbuf_pool, case RTE_CRYPTODEV_OPENSSL_PMD: target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL; break; + case RTE_CRYPTODEV_ARMV8_PMD: + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8; + break; default: TEST_ASSERT(0, "Unrecognized cryptodev type"); break; diff --git a/app/test/test_cryptodev_blockcipher.h b/app/test/test_cryptodev_blockcipher.h index 7256f6b125..91e98585af 100644 --- a/app/test/test_cryptodev_blockcipher.h +++ b/app/test/test_cryptodev_blockcipher.h @@ -50,6 +50,7 @@ #define BLOCKCIPHER_TEST_TARGET_PMD_MB 0x0001 /* Multi-buffer flag */ #define BLOCKCIPHER_TEST_TARGET_PMD_QAT 0x0002 /* QAT flag */ #define BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL 0x0004 /* SW OPENSSL flag */ +#define BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 0x0008 /* ARMv8 flag */ #define BLOCKCIPHER_TEST_OP_CIPHER (BLOCKCIPHER_TEST_OP_ENCRYPT | \ BLOCKCIPHER_TEST_OP_DECRYPT) diff --git a/app/test/test_cryptodev_perf.c b/app/test/test_cryptodev_perf.c index 9b26fc1bb6..7f1adf874d 100644 --- a/app/test/test_cryptodev_perf.c +++ b/app/test/test_cryptodev_perf.c @@ -157,6 +157,12 @@ test_perf_create_openssl_session(uint8_t dev_id, enum chain_mode chain, enum rte_crypto_cipher_algorithm cipher_algo, unsigned int cipher_key_len, enum rte_crypto_auth_algorithm auth_algo); +static struct rte_cryptodev_sym_session * +test_perf_create_armv8_session(uint8_t dev_id, enum chain_mode chain, + enum rte_crypto_cipher_algorithm cipher_algo, + unsigned int cipher_key_len, + enum rte_crypto_auth_algorithm auth_algo); + static struct rte_mbuf * test_perf_create_pktmbuf(struct rte_mempool *mpool, unsigned buf_sz); static inline struct rte_crypto_op * @@ -397,6 +403,28 @@ testsuite_setup(void) } } + /* Create 2 ARMv8 devices if required */ + if (gbl_cryptodev_perftest_devtype == RTE_CRYPTODEV_ARMV8_PMD) { +#ifndef RTE_LIBRTE_PMD_ARMV8_CRYPTO + RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_ARMV8_CRYPTO must be" + " enabled in config file to run this testsuite.\n"); + return TEST_FAILED; +#endif + nb_devs = rte_cryptodev_count_devtype( + RTE_CRYPTODEV_ARMV8_PMD); + if (nb_devs < 2) { + for (i = nb_devs; i < 2; i++) { + ret = rte_eal_vdev_init( + RTE_STR(CRYPTODEV_NAME_ARMV8_PMD), + NULL); + + TEST_ASSERT(ret == 0, "Failed to create " + "instance %u of pmd : %s", i, + RTE_STR(CRYPTODEV_NAME_ARMV8_PMD)); + } + } + } + #ifndef RTE_LIBRTE_PMD_QAT if (gbl_cryptodev_perftest_devtype == RTE_CRYPTODEV_QAT_SYM_PMD) { RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_QAT must be enabled " @@ -2425,6 +2453,139 @@ test_perf_openssl_optimise_cyclecount(struct perf_test_params *pparams) return TEST_SUCCESS; } +static int +test_perf_armv8_optimise_cyclecount(struct perf_test_params *pparams) +{ + uint32_t num_to_submit = pparams->total_operations; + struct rte_crypto_op *c_ops[num_to_submit]; + struct rte_crypto_op *proc_ops[num_to_submit]; + uint64_t failed_polls, retries, start_cycles, end_cycles, + total_cycles = 0; + uint32_t burst_sent = 0, burst_received = 0; + uint32_t i, burst_size, num_sent, num_ops_received; + uint32_t nb_ops; + + struct crypto_testsuite_params *ts_params = &testsuite_params; + + static struct rte_cryptodev_sym_session *sess; + + unsigned int digest_length = get_auth_digest_length(pparams->auth_algo); + + if (rte_cryptodev_count() == 0) { + printf("\nNo crypto devices found. Is PMD build configured?\n"); + return TEST_FAILED; + } + + /* Create Crypto session*/ + sess = test_perf_create_armv8_session(ts_params->dev_id, + pparams->chain, pparams->cipher_algo, + pparams->cipher_key_length, pparams->auth_algo); + TEST_ASSERT_NOT_NULL(sess, "Session creation failed"); + + /* Generate Crypto op data structure(s)*/ + for (i = 0; i < num_to_submit ; i++) { + struct rte_mbuf *m = test_perf_create_pktmbuf( + ts_params->mbuf_mp, + pparams->buf_size); + TEST_ASSERT_NOT_NULL(m, "Failed to allocate tx_buf"); + + struct rte_crypto_op *op = + rte_crypto_op_alloc(ts_params->op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC); + TEST_ASSERT_NOT_NULL(op, "Failed to allocate op"); + + op = test_perf_set_crypto_op_aes(op, m, sess, pparams->buf_size, + digest_length, pparams->chain); + TEST_ASSERT_NOT_NULL(op, "Failed to attach op to session"); + + c_ops[i] = op; + } + + printf("\nOn %s dev%u qp%u, %s, cipher algo:%s, cipher key length:%u, " + "auth_algo:%s, Packet Size %u bytes", + pmd_name(gbl_cryptodev_perftest_devtype), + ts_params->dev_id, 0, + chain_mode_name(pparams->chain), + cipher_algo_name(pparams->cipher_algo), + pparams->cipher_key_length, + auth_algo_name(pparams->auth_algo), + pparams->buf_size); + printf("\nOps Tx\tOps Rx\tOps/burst "); + printf("Retries " + "EmptyPolls\tIACycles/CyOp\tIACycles/Burst\tIACycles/Byte"); + + for (i = 2; i <= 128 ; i *= 2) { + num_sent = 0; + num_ops_received = 0; + retries = 0; + failed_polls = 0; + burst_size = i; + total_cycles = 0; + while (num_sent < num_to_submit) { + if ((num_to_submit - num_sent) < burst_size) + nb_ops = num_to_submit - num_sent; + else + nb_ops = burst_size; + + start_cycles = rte_rdtsc(); + burst_sent = rte_cryptodev_enqueue_burst( + ts_params->dev_id, + 0, &c_ops[num_sent], + nb_ops); + end_cycles = rte_rdtsc(); + + if (burst_sent == 0) + retries++; + num_sent += burst_sent; + total_cycles += (end_cycles - start_cycles); + + start_cycles = rte_rdtsc(); + burst_received = rte_cryptodev_dequeue_burst( + ts_params->dev_id, 0, proc_ops, + burst_size); + end_cycles = rte_rdtsc(); + if (burst_received < burst_sent) + failed_polls++; + num_ops_received += burst_received; + + total_cycles += end_cycles - start_cycles; + } + + while (num_ops_received != num_to_submit) { + /* Sending 0 length burst to flush sw crypto device */ + rte_cryptodev_enqueue_burst( + ts_params->dev_id, 0, NULL, 0); + + start_cycles = rte_rdtsc(); + burst_received = rte_cryptodev_dequeue_burst( + ts_params->dev_id, 0, proc_ops, burst_size); + end_cycles = rte_rdtsc(); + + total_cycles += end_cycles - start_cycles; + if (burst_received == 0) + failed_polls++; + num_ops_received += burst_received; + } + + printf("\n%u\t%u\t%u", num_sent, num_ops_received, burst_size); + printf("\t\t%"PRIu64, retries); + printf("\t%"PRIu64, failed_polls); + printf("\t\t%"PRIu64, total_cycles/num_ops_received); + printf("\t\t%"PRIu64, + (total_cycles/num_ops_received)*burst_size); + printf("\t\t%"PRIu64, + total_cycles/(num_ops_received*pparams->buf_size)); + } + printf("\n"); + + for (i = 0; i < num_to_submit ; i++) { + rte_pktmbuf_free(c_ops[i]->sym->m_src); + rte_crypto_op_free(c_ops[i]); + } + + return TEST_SUCCESS; +} + static uint32_t get_auth_key_max_length(enum rte_crypto_auth_algorithm algo) { switch (algo) { @@ -2690,6 +2851,56 @@ test_perf_create_openssl_session(uint8_t dev_id, enum chain_mode chain, } } +static struct rte_cryptodev_sym_session * +test_perf_create_armv8_session(uint8_t dev_id, enum chain_mode chain, + enum rte_crypto_cipher_algorithm cipher_algo, + unsigned int cipher_key_len, + enum rte_crypto_auth_algorithm auth_algo) +{ + struct rte_crypto_sym_xform cipher_xform = { 0 }; + struct rte_crypto_sym_xform auth_xform = { 0 }; + + /* Setup Cipher Parameters */ + cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; + cipher_xform.cipher.algo = cipher_algo; + + switch (cipher_algo) { + case RTE_CRYPTO_CIPHER_AES_CBC: + cipher_xform.cipher.key.data = aes_cbc_128_key; + break; + default: + return NULL; + } + + cipher_xform.cipher.key.length = cipher_key_len; + + /* Setup Auth Parameters */ + auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; + auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; + auth_xform.auth.algo = auth_algo; + + auth_xform.auth.digest_length = get_auth_digest_length(auth_algo); + + switch (chain) { + case CIPHER_HASH: + cipher_xform.next = &auth_xform; + auth_xform.next = NULL; + /* Encrypt and hash the result */ + cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; + /* Create Crypto session*/ + return rte_cryptodev_sym_session_create(dev_id, &cipher_xform); + case HASH_CIPHER: + auth_xform.next = &cipher_xform; + cipher_xform.next = NULL; + /* Hash encrypted message and decrypt */ + cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT; + /* Create Crypto session*/ + return rte_cryptodev_sym_session_create(dev_id, &auth_xform); + default: + return NULL; + } +} + #define AES_BLOCK_SIZE 16 #define AES_CIPHER_IV_LENGTH 16 @@ -3380,6 +3591,139 @@ test_perf_openssl(uint8_t dev_id, uint16_t queue_id, return TEST_SUCCESS; } +static int +test_perf_armv8(uint8_t dev_id, uint16_t queue_id, + struct perf_test_params *pparams) +{ + uint16_t i, k, l, m; + uint16_t j = 0; + uint16_t ops_unused = 0; + uint16_t burst_size; + uint16_t ops_needed; + + uint64_t burst_enqueued = 0, total_enqueued = 0, burst_dequeued = 0; + uint64_t processed = 0, failed_polls = 0, retries = 0; + uint64_t tsc_start = 0, tsc_end = 0; + + unsigned int digest_length = get_auth_digest_length(pparams->auth_algo); + + struct rte_crypto_op *ops[pparams->burst_size]; + struct rte_crypto_op *proc_ops[pparams->burst_size]; + + struct rte_mbuf *mbufs[pparams->burst_size * NUM_MBUF_SETS]; + + struct crypto_testsuite_params *ts_params = &testsuite_params; + + static struct rte_cryptodev_sym_session *sess; + + if (rte_cryptodev_count() == 0) { + printf("\nNo crypto devices found. Is PMD build configured?\n"); + return TEST_FAILED; + } + + /* Create Crypto session*/ + sess = test_perf_create_armv8_session(ts_params->dev_id, + pparams->chain, pparams->cipher_algo, + pparams->cipher_key_length, pparams->auth_algo); + TEST_ASSERT_NOT_NULL(sess, "Session creation failed"); + + /* Generate a burst of crypto operations */ + for (i = 0; i < (pparams->burst_size * NUM_MBUF_SETS); i++) { + mbufs[i] = test_perf_create_pktmbuf( + ts_params->mbuf_mp, + pparams->buf_size); + + if (mbufs[i] == NULL) { + printf("\nFailed to get mbuf - freeing the rest.\n"); + for (k = 0; k < i; k++) + rte_pktmbuf_free(mbufs[k]); + return -1; + } + } + + tsc_start = rte_rdtsc(); + + while (total_enqueued < pparams->total_operations) { + if ((total_enqueued + pparams->burst_size) <= + pparams->total_operations) + burst_size = pparams->burst_size; + else + burst_size = pparams->total_operations - total_enqueued; + + ops_needed = burst_size - ops_unused; + + if (ops_needed != rte_crypto_op_bulk_alloc(ts_params->op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC, ops, ops_needed)){ + printf("\nFailed to alloc enough ops, finish dequeuing " + "and free ops below."); + } else { + for (i = 0; i < ops_needed; i++) + ops[i] = test_perf_set_crypto_op_aes(ops[i], + mbufs[i + (pparams->burst_size * + (j % NUM_MBUF_SETS))], sess, + pparams->buf_size, digest_length, + pparams->chain); + + /* enqueue burst */ + burst_enqueued = rte_cryptodev_enqueue_burst(dev_id, + queue_id, ops, burst_size); + + if (burst_enqueued < burst_size) + retries++; + + ops_unused = burst_size - burst_enqueued; + total_enqueued += burst_enqueued; + } + + /* dequeue burst */ + burst_dequeued = rte_cryptodev_dequeue_burst(dev_id, queue_id, + proc_ops, pparams->burst_size); + if (burst_dequeued == 0) + failed_polls++; + else { + processed += burst_dequeued; + + for (l = 0; l < burst_dequeued; l++) + rte_crypto_op_free(proc_ops[l]); + } + j++; + } + + /* Dequeue any operations still in the crypto device */ + while (processed < pparams->total_operations) { + /* Sending 0 length burst to flush sw crypto device */ + rte_cryptodev_enqueue_burst(dev_id, queue_id, NULL, 0); + + /* dequeue burst */ + burst_dequeued = rte_cryptodev_dequeue_burst(dev_id, queue_id, + proc_ops, pparams->burst_size); + if (burst_dequeued == 0) + failed_polls++; + else { + processed += burst_dequeued; + + for (m = 0; m < burst_dequeued; m++) + rte_crypto_op_free(proc_ops[m]); + } + } + + tsc_end = rte_rdtsc(); + + double ops_s = ((double)processed / (tsc_end - tsc_start)) + * rte_get_tsc_hz(); + double throughput = (ops_s * pparams->buf_size * NUM_MBUF_SETS) + / 1000000000; + + printf("\t%u\t%6.2f\t%10.2f\t%8"PRIu64"\t%8"PRIu64, pparams->buf_size, + ops_s / 1000000, throughput, retries, failed_polls); + + for (i = 0; i < pparams->burst_size * NUM_MBUF_SETS; i++) + rte_pktmbuf_free(mbufs[i]); + + printf("\n"); + return TEST_SUCCESS; +} + /* perf_test_aes_sha("avx2", HASH_CIPHER, 16, CBC, SHA1); @@ -3692,6 +4036,125 @@ test_perf_openssl_vary_burst_size(void) return 0; } +static int +test_perf_armv8_vary_pkt_size(void) +{ + unsigned int total_operations = 100000; + unsigned int burst_size = { 64 }; + unsigned int buf_lengths[] = { 64, 128, 256, 512, 768, 1024, 1280, 1536, + 1792, 2048 }; + uint8_t i, j; + + struct perf_test_params params_set[] = { + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = HASH_CIPHER, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC + }, + { + .chain = HASH_CIPHER, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC + }, + }; + + for (i = 0; i < RTE_DIM(params_set); i++) { + params_set[i].total_operations = total_operations; + params_set[i].burst_size = burst_size; + printf("\n%s. cipher algo: %s auth algo: %s cipher key size=%u." + " burst_size: %d ops\n", + chain_mode_name(params_set[i].chain), + cipher_algo_name(params_set[i].cipher_algo), + auth_algo_name(params_set[i].auth_algo), + params_set[i].cipher_key_length, + burst_size); + printf("\nBuffer Size(B)\tOPS(M)\tThroughput(Gbps)\tRetries\t" + "EmptyPolls\n"); + for (j = 0; j < RTE_DIM(buf_lengths); j++) { + params_set[i].buf_size = buf_lengths[j]; + test_perf_armv8(testsuite_params.dev_id, 0, + ¶ms_set[i]); + } + } + + return 0; +} + +static int +test_perf_armv8_vary_burst_size(void) +{ + unsigned int total_operations = 4096; + uint16_t buf_lengths[] = { 64 }; + uint8_t i, j; + + struct perf_test_params params_set[] = { + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = HASH_CIPHER, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC + }, + { + .chain = HASH_CIPHER, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC + }, + }; + + printf("\n\nStart %s.", __func__); + printf("\nThis Test measures the average IA cycle cost using a " + "constant request(packet) size. "); + printf("Cycle cost is only valid when indicators show device is " + "not busy, i.e. Retries and EmptyPolls = 0"); + + for (i = 0; i < RTE_DIM(params_set); i++) { + printf("\n"); + params_set[i].total_operations = total_operations; + + for (j = 0; j < RTE_DIM(buf_lengths); j++) { + params_set[i].buf_size = buf_lengths[j]; + test_perf_armv8_optimise_cyclecount(¶ms_set[i]); + } + } + + return 0; +} + static int test_perf_aes_cbc_vary_burst_size(void) { @@ -4244,6 +4707,19 @@ static struct unit_test_suite cryptodev_openssl_testsuite = { } }; +static struct unit_test_suite cryptodev_armv8_testsuite = { + .suite_name = "Crypto Device ARMv8 Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, + test_perf_armv8_vary_pkt_size), + TEST_CASE_ST(ut_setup, ut_teardown, + test_perf_armv8_vary_burst_size), + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + static int perftest_aesni_gcm_cryptodev(void) { @@ -4300,6 +4776,14 @@ perftest_qat_continual_cryptodev(void) return unit_test_suite_runner(&cryptodev_qat_continual_testsuite); } +static int +perftest_sw_armv8_cryptodev(void /*argv __rte_unused, int argc __rte_unused*/) +{ + gbl_cryptodev_perftest_devtype = RTE_CRYPTODEV_ARMV8_PMD; + + return unit_test_suite_runner(&cryptodev_armv8_testsuite); +} + REGISTER_TEST_COMMAND(cryptodev_aesni_mb_perftest, perftest_aesni_mb_cryptodev); REGISTER_TEST_COMMAND(cryptodev_qat_perftest, perftest_qat_cryptodev); REGISTER_TEST_COMMAND(cryptodev_sw_snow3g_perftest, perftest_sw_snow3g_cryptodev); @@ -4309,3 +4793,5 @@ REGISTER_TEST_COMMAND(cryptodev_openssl_perftest, perftest_openssl_cryptodev); REGISTER_TEST_COMMAND(cryptodev_qat_continual_perftest, perftest_qat_continual_cryptodev); +REGISTER_TEST_COMMAND(cryptodev_sw_armv8_perftest, + perftest_sw_armv8_cryptodev);