diff mbox

[dpdk-dev,v3,8/8] app/test: add ARMv8 crypto tests and test vectors

Message ID 1483551207-18236-9-git-send-email-zbigniew.bodek@caviumnetworks.com (mailing list archive)
State Changes Requested, archived
Delegated to: Pablo de Lara Guarch
Headers show

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel compilation success Compilation OK

Commit Message

zbigniew.bodek@caviumnetworks.com Jan. 4, 2017, 5:33 p.m. UTC
From: Zbigniew Bodek <zbigniew.bodek@caviumnetworks.com>

Introduce unit tests for ARMv8 crypto PMD.
Add test vectors for short cases such as 160 bytes.
These test cases are ARMv8 specific since the code provides
different processing paths for different input data sizes.

User can validate correctness of algorithms' implementation using:
* cryptodev_sw_armv8_autotest
For performance test one can use:
* cryptodev_sw_armv8_perftest

Signed-off-by: Zbigniew Bodek <zbigniew.bodek@caviumnetworks.com>
---
 app/test/test_cryptodev.c                  |  63 ++++
 app/test/test_cryptodev_aes_test_vectors.h | 144 ++++++++-
 app/test/test_cryptodev_blockcipher.c      |   4 +
 app/test/test_cryptodev_blockcipher.h      |   1 +
 app/test/test_cryptodev_perf.c             | 480 +++++++++++++++++++++++++++++
 5 files changed, 684 insertions(+), 8 deletions(-)

Comments

De Lara Guarch, Pablo Jan. 12, 2017, 10:48 a.m. UTC | #1
Hi Bodek,

> -----Original Message-----
> From: zbigniew.bodek@caviumnetworks.com
> [mailto:zbigniew.bodek@caviumnetworks.com]
> Sent: Wednesday, January 04, 2017 5:33 PM
> To: dev@dpdk.org
> Cc: De Lara Guarch, Pablo; Doherty, Declan;
> jerin.jacob@caviumnetworks.com; Zbigniew Bodek
> Subject: [PATCH v3 8/8] app/test: add ARMv8 crypto tests and test vectors
> 
> From: Zbigniew Bodek <zbigniew.bodek@caviumnetworks.com>
> 
> Introduce unit tests for ARMv8 crypto PMD.
> Add test vectors for short cases such as 160 bytes.
> These test cases are ARMv8 specific since the code provides
> different processing paths for different input data sizes.
> 
> User can validate correctness of algorithms' implementation using:
> * cryptodev_sw_armv8_autotest
> For performance test one can use:
> * cryptodev_sw_armv8_perftest
> 
> Signed-off-by: Zbigniew Bodek <zbigniew.bodek@caviumnetworks.com>

Could you rebase this patchset with the dpdk-next-crypto tree?
There is a compilation error due to a missing parameter in a function that has recently changed.

Thanks,
Pablo
zbigniew.bodek@caviumnetworks.com Jan. 12, 2017, 11:50 a.m. UTC | #2
Hello Pablo,

On 12.01.2017 11:48, De Lara Guarch, Pablo wrote:
> Hi Bodek,
>
>> -----Original Message-----
>> From: zbigniew.bodek@caviumnetworks.com
>> [mailto:zbigniew.bodek@caviumnetworks.com]
>> Sent: Wednesday, January 04, 2017 5:33 PM
>> To: dev@dpdk.org
>> Cc: De Lara Guarch, Pablo; Doherty, Declan;
>> jerin.jacob@caviumnetworks.com; Zbigniew Bodek
>> Subject: [PATCH v3 8/8] app/test: add ARMv8 crypto tests and test vectors
>>
>> From: Zbigniew Bodek <zbigniew.bodek@caviumnetworks.com>
>>
>> Introduce unit tests for ARMv8 crypto PMD.
>> Add test vectors for short cases such as 160 bytes.
>> These test cases are ARMv8 specific since the code provides
>> different processing paths for different input data sizes.
>>
>> User can validate correctness of algorithms' implementation using:
>> * cryptodev_sw_armv8_autotest
>> For performance test one can use:
>> * cryptodev_sw_armv8_perftest
>>
>> Signed-off-by: Zbigniew Bodek <zbigniew.bodek@caviumnetworks.com>
>
> Could you rebase this patchset with the dpdk-next-crypto tree?
> There is a compilation error due to a missing parameter in a function that has recently changed.

I see. The rebase is done. Should I send full v4 patchset now?

Kind regards
Zbigniew

>
> Thanks,
> Pablo
>
De Lara Guarch, Pablo Jan. 12, 2017, 12:07 p.m. UTC | #3
> -----Original Message-----
> From: Zbigniew Bodek [mailto:zbigniew.bodek@caviumnetworks.com]
> Sent: Thursday, January 12, 2017 11:51 AM
> To: De Lara Guarch, Pablo; dev@dpdk.org
> Cc: Doherty, Declan; jerin.jacob@caviumnetworks.com
> Subject: Re: [PATCH v3 8/8] app/test: add ARMv8 crypto tests and test
> vectors
> 
> Hello Pablo,
> 
> On 12.01.2017 11:48, De Lara Guarch, Pablo wrote:
> > Hi Bodek,
> >
> >> -----Original Message-----
> >> From: zbigniew.bodek@caviumnetworks.com
> >> [mailto:zbigniew.bodek@caviumnetworks.com]
> >> Sent: Wednesday, January 04, 2017 5:33 PM
> >> To: dev@dpdk.org
> >> Cc: De Lara Guarch, Pablo; Doherty, Declan;
> >> jerin.jacob@caviumnetworks.com; Zbigniew Bodek
> >> Subject: [PATCH v3 8/8] app/test: add ARMv8 crypto tests and test
> vectors
> >>
> >> From: Zbigniew Bodek <zbigniew.bodek@caviumnetworks.com>
> >>
> >> Introduce unit tests for ARMv8 crypto PMD.
> >> Add test vectors for short cases such as 160 bytes.
> >> These test cases are ARMv8 specific since the code provides
> >> different processing paths for different input data sizes.
> >>
> >> User can validate correctness of algorithms' implementation using:
> >> * cryptodev_sw_armv8_autotest
> >> For performance test one can use:
> >> * cryptodev_sw_armv8_perftest
> >>
> >> Signed-off-by: Zbigniew Bodek <zbigniew.bodek@caviumnetworks.com>
> >
> > Could you rebase this patchset with the dpdk-next-crypto tree?
> > There is a compilation error due to a missing parameter in a function that
> has recently changed.
> 
> I see. The rebase is done. Should I send full v4 patchset now?
> 

There are some comments from Jianbo Liu. Take a look at them in case
you have something to change there.

Also, since you are sending a v4 patchset, make the commit name changes too, please.

Thanks,
Pablo

> Kind regards
> Zbigniew
> 
> >
> > Thanks,
> > Pablo
> >
Hemant Agrawal Jan. 13, 2017, 9:28 a.m. UTC | #4
On 1/4/2017 11:03 PM, zbigniew.bodek@caviumnetworks.com wrote:
> From: Zbigniew Bodek <zbigniew.bodek@caviumnetworks.com>
>
> Introduce unit tests for ARMv8 crypto PMD.
> Add test vectors for short cases such as 160 bytes.
> These test cases are ARMv8 specific since the code provides
> different processing paths for different input data sizes.
>
> User can validate correctness of algorithms' implementation using:
> * cryptodev_sw_armv8_autotest
> For performance test one can use:
> * cryptodev_sw_armv8_perftest
>
> Signed-off-by: Zbigniew Bodek <zbigniew.bodek@caviumnetworks.com>
> ---
>  app/test/test_cryptodev.c                  |  63 ++++
>  app/test/test_cryptodev_aes_test_vectors.h | 144 ++++++++-
>  app/test/test_cryptodev_blockcipher.c      |   4 +
>  app/test/test_cryptodev_blockcipher.h      |   1 +
>  app/test/test_cryptodev_perf.c             | 480 +++++++++++++++++++++++++++++
>  5 files changed, 684 insertions(+), 8 deletions(-)
>
> diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c
> index 872f8b4..a0540d6 100644
> --- a/app/test/test_cryptodev.c
> +++ b/app/test/test_cryptodev.c
............
> @@ -2422,6 +2449,136 @@ struct crypto_data_params aes_cbc_hmac_sha256_output[MAX_PACKET_SIZE_INDEX] = {
>  	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;
> +
> +	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);
> +		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) {
> +			start_cycles = rte_rdtsc_precise();
> +			burst_sent = rte_cryptodev_enqueue_burst(
> +				ts_params->dev_id,
> +				0, &c_ops[num_sent],
> +				((num_to_submit - num_sent) < burst_size) ?
> +				num_to_submit - num_sent : burst_size);
> +			end_cycles = rte_rdtsc_precise();
> +			if (burst_sent == 0)
> +				retries++;
> +			num_sent += burst_sent;
> +			total_cycles += (end_cycles - start_cycles);
> +
> +			/* Wait until requests have been sent. */
> +			rte_delay_ms(1);
> +
you may remove this delay.

> +			start_cycles = rte_rdtsc_precise();
> +			burst_received = rte_cryptodev_dequeue_burst(
> +					ts_params->dev_id, 0, proc_ops,
> +					burst_size);
> +			end_cycles = rte_rdtsc_precise();
> +			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_precise();
> +			burst_received = rte_cryptodev_dequeue_burst(
> +				ts_params->dev_id, 0, proc_ops, burst_size);
> +			end_cycles = rte_rdtsc_precise();
> +
> +			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) {
> @@ -2683,6 +2840,56 @@ static uint32_t get_auth_digest_length(enum rte_crypto_auth_algorithm 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)
> +{
> +	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
>
> @@ -3356,6 +3563,138 @@ static uint32_t get_auth_digest_length(enum rte_crypto_auth_algorithm algo)
>  	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_precise();
> +
> +	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);
> +
> +			/* 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_precise();
> +
> +	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);
> @@ -3664,6 +4003,125 @@ static uint32_t get_auth_digest_length(enum rte_crypto_auth_algorithm algo)
>  }
>
>  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,
> +							&params_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(&params_set[i]);
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static int
>  test_perf_aes_cbc_vary_burst_size(void)
>  {
>  	return test_perf_crypto_qp_vary_burst_size(testsuite_params.dev_id);
> @@ -4214,6 +4672,19 @@ static int test_continual_perf_AES_GCM(void)
>  	}
>  };
>
> +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)
>  {
> @@ -4270,6 +4741,14 @@ static int test_continual_perf_AES_GCM(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);
> @@ -4279,3 +4758,4 @@ static int test_continual_perf_AES_GCM(void)
>  		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);
>
diff mbox

Patch

diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c
index 872f8b4..a0540d6 100644
--- a/app/test/test_cryptodev.c
+++ b/app/test/test_cryptodev.c
@@ -348,6 +348,27 @@  struct crypto_unittest_params {
 		}
 	}
 
+	/* 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 "
@@ -1545,6 +1566,22 @@  struct crypto_unittest_params {
 	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,
@@ -6504,6 +6541,23 @@  struct test_crypto_vector {
 	}
 };
 
+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*/)
 {
@@ -6567,6 +6621,14 @@  struct test_crypto_vector {
 	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);
@@ -6575,3 +6637,4 @@  struct test_crypto_vector {
 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 1c68f93..5683406 100644
--- a/app/test/test_cryptodev_aes_test_vectors.h
+++ b/app/test/test_cryptodev_aes_test_vectors.h
@@ -825,6 +825,98 @@ 
 	}
 };
 
+/** 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",
@@ -878,37 +970,69 @@ 
 		.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 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,
 		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
@@ -954,7 +1078,8 @@ 
 		.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
 	},
 	{
@@ -963,7 +1088,8 @@ 
 		.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
 	},
 	{
@@ -1006,7 +1132,8 @@ 
 		.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 =
@@ -1015,7 +1142,8 @@ 
 		.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 37b10cf..6963241 100644
--- a/app/test/test_cryptodev_blockcipher.c
+++ b/app/test/test_cryptodev_blockcipher.c
@@ -82,6 +82,7 @@ 
 	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:
@@ -508,6 +509,9 @@ 
 	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 04ff1ee..bd362c7 100644
--- a/app/test/test_cryptodev_blockcipher.h
+++ b/app/test/test_cryptodev_blockcipher.h
@@ -49,6 +49,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 59a6891..827cf4d 100644
--- a/app/test/test_cryptodev_perf.c
+++ b/app/test/test_cryptodev_perf.c
@@ -157,6 +157,12 @@  struct crypto_unittest_params {
 		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,27 @@  static const char *auth_algo_name(enum rte_crypto_auth_algorithm auth_algo)
 		}
 	}
 
+	/* 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 "
@@ -2422,6 +2449,136 @@  struct crypto_data_params aes_cbc_hmac_sha256_output[MAX_PACKET_SIZE_INDEX] = {
 	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;
+
+	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);
+		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) {
+			start_cycles = rte_rdtsc_precise();
+			burst_sent = rte_cryptodev_enqueue_burst(
+				ts_params->dev_id,
+				0, &c_ops[num_sent],
+				((num_to_submit - num_sent) < burst_size) ?
+				num_to_submit - num_sent : burst_size);
+			end_cycles = rte_rdtsc_precise();
+			if (burst_sent == 0)
+				retries++;
+			num_sent += burst_sent;
+			total_cycles += (end_cycles - start_cycles);
+
+			/* Wait until requests have been sent. */
+			rte_delay_ms(1);
+
+			start_cycles = rte_rdtsc_precise();
+			burst_received = rte_cryptodev_dequeue_burst(
+					ts_params->dev_id, 0, proc_ops,
+					burst_size);
+			end_cycles = rte_rdtsc_precise();
+			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_precise();
+			burst_received = rte_cryptodev_dequeue_burst(
+				ts_params->dev_id, 0, proc_ops, burst_size);
+			end_cycles = rte_rdtsc_precise();
+
+			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) {
@@ -2683,6 +2840,56 @@  static uint32_t get_auth_digest_length(enum rte_crypto_auth_algorithm 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)
+{
+	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
 
@@ -3356,6 +3563,138 @@  static uint32_t get_auth_digest_length(enum rte_crypto_auth_algorithm algo)
 	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_precise();
+
+	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);
+
+			/* 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_precise();
+
+	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);
@@ -3664,6 +4003,125 @@  static uint32_t get_auth_digest_length(enum rte_crypto_auth_algorithm algo)
 }
 
 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,
+							&params_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(&params_set[i]);
+		}
+	}
+
+	return 0;
+}
+
+static int
 test_perf_aes_cbc_vary_burst_size(void)
 {
 	return test_perf_crypto_qp_vary_burst_size(testsuite_params.dev_id);
@@ -4214,6 +4672,19 @@  static int test_continual_perf_AES_GCM(void)
 	}
 };
 
+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)
 {
@@ -4270,6 +4741,14 @@  static int test_continual_perf_AES_GCM(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);
@@ -4279,3 +4758,4 @@  static int test_continual_perf_AES_GCM(void)
 		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);