[v4] test/ipsec: measure libipsec performance

Message ID 20200306070825.19424-1-savinay.dharmappa@intel.com (mailing list archive)
State Accepted, archived
Delegated to: akhil goyal
Headers
Series [v4] test/ipsec: measure libipsec performance |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/iol-intel-Performance success Performance Testing PASS
ci/iol-testing success Testing PASS
ci/iol-mellanox-Performance success Performance Testing PASS
ci/travis-robot success Travis build: passed
ci/Intel-compilation success Compilation OK

Commit Message

Savinay Dharmappa March 6, 2020, 7:08 a.m. UTC
  test app to measures the performance of libipsec
api rte_ipsec_pkt_crypto and rte_ipsec_pkt_process.

Signed-off-by: Savinay Dharmappa <savinay.dharmappa@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
 MAINTAINERS                |   2 +
 app/test/Makefile          |   2 +-
 app/test/meson.build       |   2 +
 app/test/test_ipsec_perf.c | 619 +++++++++++++++++++++++++++++++++++++
 4 files changed, 624 insertions(+), 1 deletion(-)
 create mode 100644 app/test/test_ipsec_perf.c
  

Comments

Akhil Goyal April 19, 2020, 9:43 p.m. UTC | #1
> test app to measures the performance of libipsec
> api rte_ipsec_pkt_crypto and rte_ipsec_pkt_process.
> 
> Signed-off-by: Savinay Dharmappa <savinay.dharmappa@intel.com>
> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> ---
Applied to dpdk-next-crypto

Thanks.
  
Thomas Monjalon April 21, 2020, 2:29 a.m. UTC | #2
06/03/2020 08:08, Savinay Dharmappa:
> test app to measures the performance of libipsec
> api rte_ipsec_pkt_crypto and rte_ipsec_pkt_process.

Please make sentences in commit logs.

> Signed-off-by: Savinay Dharmappa <savinay.dharmappa@intel.com>
> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> ---
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1259,6 +1259,8 @@ F: lib/librte_ipsec/
>  M: Bernard Iremonger <bernard.iremonger@intel.com>
>  F: app/test/test_ipsec.c
>  F: doc/guides/prog_guide/ipsec_lib.rst
> +M: Savinay Dharmappa <savinay.dharmappa@intel.com>
> +F: app/test/test_ipsec_perf.c
>  M: Vladimir Medvedkin <vladimir.medvedkin@intel.com>
>  F: app/test/test_ipsec_sad.c
>  F: app/test-sad/

Repeating what I said on v3:
Having one different maintainer per test file is quite ridiculous.
The maintainers of a lib are expected to maintain the related tests.
  
Thomas Monjalon April 21, 2020, 2:35 a.m. UTC | #3
21/04/2020 04:29, Thomas Monjalon:
> 06/03/2020 08:08, Savinay Dharmappa:
> > test app to measures the performance of libipsec
> > api rte_ipsec_pkt_crypto and rte_ipsec_pkt_process.
> 
> Please make sentences in commit logs.
> 
> > Signed-off-by: Savinay Dharmappa <savinay.dharmappa@intel.com>
> > Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> > ---
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -1259,6 +1259,8 @@ F: lib/librte_ipsec/
> >  M: Bernard Iremonger <bernard.iremonger@intel.com>
> >  F: app/test/test_ipsec.c
> >  F: doc/guides/prog_guide/ipsec_lib.rst
> > +M: Savinay Dharmappa <savinay.dharmappa@intel.com>
> > +F: app/test/test_ipsec_perf.c
> >  M: Vladimir Medvedkin <vladimir.medvedkin@intel.com>
> >  F: app/test/test_ipsec_sad.c
> >  F: app/test-sad/
> 
> Repeating what I said on v3:
> Having one different maintainer per test file is quite ridiculous.
> The maintainers of a lib are expected to maintain the related tests.


In addition, reading the first lines of the file, I see two mistakes:

> --- /dev/null
> +++ b/app/test/test_ipsec_perf.c
> @@ -0,0 +1,619 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2010-2014 Intel Corporation

The Copyright year should be 2020 I guess.

> + */
> +
> +#include <stdio.h>
> +#include <rte_ip.h>
> +#include <rte_malloc.h>
> +#include <rte_ring.h>
> +#include <rte_mbuf.h>
> +#include <rte_malloc.h>

rte_malloc.h is already included 3 lines above.


I have a bad feeling about this patch,
I think it should be dropped from 20.05-rc1.
  
Ananyev, Konstantin April 21, 2020, 10:21 a.m. UTC | #4
> 
> 21/04/2020 04:29, Thomas Monjalon:
> > 06/03/2020 08:08, Savinay Dharmappa:
> > > test app to measures the performance of libipsec
> > > api rte_ipsec_pkt_crypto and rte_ipsec_pkt_process.
> >
> > Please make sentences in commit logs.
> >
> > > Signed-off-by: Savinay Dharmappa <savinay.dharmappa@intel.com>
> > > Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> > > ---
> > > --- a/MAINTAINERS
> > > +++ b/MAINTAINERS
> > > @@ -1259,6 +1259,8 @@ F: lib/librte_ipsec/
> > >  M: Bernard Iremonger <bernard.iremonger@intel.com>
> > >  F: app/test/test_ipsec.c
> > >  F: doc/guides/prog_guide/ipsec_lib.rst
> > > +M: Savinay Dharmappa <savinay.dharmappa@intel.com>
> > > +F: app/test/test_ipsec_perf.c
> > >  M: Vladimir Medvedkin <vladimir.medvedkin@intel.com>
> > >  F: app/test/test_ipsec_sad.c
> > >  F: app/test-sad/
> >
> > Repeating what I said on v3:
> > Having one different maintainer per test file is quite ridiculous.
> > The maintainers of a lib are expected to maintain the related tests.
> 
> 
> In addition, reading the first lines of the file, I see two mistakes:
> 
> > --- /dev/null
> > +++ b/app/test/test_ipsec_perf.c
> > @@ -0,0 +1,619 @@
> > +/* SPDX-License-Identifier: BSD-3-Clause
> > + * Copyright(c) 2010-2014 Intel Corporation
> 
> The Copyright year should be 2020 I guess.
> 
> > + */
> > +
> > +#include <stdio.h>
> > +#include <rte_ip.h>
> > +#include <rte_malloc.h>
> > +#include <rte_ring.h>
> > +#include <rte_mbuf.h>
> > +#include <rte_malloc.h>
> 
> rte_malloc.h is already included 3 lines above.
> 
> 
> I have a bad feeling about this patch,
> I think it should be dropped from 20.05-rc1.

If you feel patch is not good enough - sure feel free to drop it,
we'll try to fix the issues and resubmit it for rc2.
About having separate MAINTAINER for the test -
honestly I don't understand why it is a problem for you.
Obviously we would like to spread the load - what's wrong with it?
Konstantin
  
Thomas Monjalon April 21, 2020, 10:28 a.m. UTC | #5
21/04/2020 12:21, Ananyev, Konstantin:
> > 21/04/2020 04:29, Thomas Monjalon:
> > > > --- a/MAINTAINERS
> > > > +++ b/MAINTAINERS
> > > > @@ -1259,6 +1259,8 @@ F: lib/librte_ipsec/
> > > >  M: Bernard Iremonger <bernard.iremonger@intel.com>
> > > >  F: app/test/test_ipsec.c
> > > >  F: doc/guides/prog_guide/ipsec_lib.rst
> > > > +M: Savinay Dharmappa <savinay.dharmappa@intel.com>
> > > > +F: app/test/test_ipsec_perf.c
> > > >  M: Vladimir Medvedkin <vladimir.medvedkin@intel.com>
> > > >  F: app/test/test_ipsec_sad.c
> > > >  F: app/test-sad/
> > >
> > > Repeating what I said on v3:
> > > Having one different maintainer per test file is quite ridiculous.
> > > The maintainers of a lib are expected to maintain the related tests.
[...]
> About having separate MAINTAINER for the test -
> honestly I don't understand why it is a problem for you.
> Obviously we would like to spread the load - what's wrong with it?

This is a problem of ownership.
Maintaining a library means you take care of every aspect, including tests.
That's why I would like to see you as a global maintainer of IPsec.

It doesn't prevent you to delegate workload, of course.
But at the end it is more convenient to know there is a limited number
of persons responsible for the global quality of a component,
a person which is accountable and answering questions on the topic,
no matter which exact file we are talking about.
  
Ananyev, Konstantin April 21, 2020, 11:07 a.m. UTC | #6
> 
> 21/04/2020 12:21, Ananyev, Konstantin:
> > > 21/04/2020 04:29, Thomas Monjalon:
> > > > > --- a/MAINTAINERS
> > > > > +++ b/MAINTAINERS
> > > > > @@ -1259,6 +1259,8 @@ F: lib/librte_ipsec/
> > > > >  M: Bernard Iremonger <bernard.iremonger@intel.com>
> > > > >  F: app/test/test_ipsec.c
> > > > >  F: doc/guides/prog_guide/ipsec_lib.rst
> > > > > +M: Savinay Dharmappa <savinay.dharmappa@intel.com>
> > > > > +F: app/test/test_ipsec_perf.c
> > > > >  M: Vladimir Medvedkin <vladimir.medvedkin@intel.com>
> > > > >  F: app/test/test_ipsec_sad.c
> > > > >  F: app/test-sad/
> > > >
> > > > Repeating what I said on v3:
> > > > Having one different maintainer per test file is quite ridiculous.
> > > > The maintainers of a lib are expected to maintain the related tests.
> [...]
> > About having separate MAINTAINER for the test -
> > honestly I don't understand why it is a problem for you.
> > Obviously we would like to spread the load - what's wrong with it?
> 
> This is a problem of ownership.
> Maintaining a library means you take care of every aspect, including tests.
> That's why I would like to see you as a global maintainer of IPsec.
> 
> It doesn't prevent you to delegate workload, of course.
> But at the end it is more convenient to know there is a limited number
> of persons responsible for the global quality of a component,
> a person which is accountable and answering questions on the topic,
> no matter which exact file we are talking about.

Just talked with Bernard, he kindly agreed to be a maintainer for all ipsec UT:
app/test/test_ipsec*
Hope that will fulfil your concern?
  
Thomas Monjalon April 21, 2020, 11:49 a.m. UTC | #7
21/04/2020 13:07, Ananyev, Konstantin:
> > 21/04/2020 12:21, Ananyev, Konstantin:
> > > > 21/04/2020 04:29, Thomas Monjalon:
> > > > > > --- a/MAINTAINERS
> > > > > > +++ b/MAINTAINERS
> > > > > > @@ -1259,6 +1259,8 @@ F: lib/librte_ipsec/
> > > > > >  M: Bernard Iremonger <bernard.iremonger@intel.com>
> > > > > >  F: app/test/test_ipsec.c
> > > > > >  F: doc/guides/prog_guide/ipsec_lib.rst
> > > > > > +M: Savinay Dharmappa <savinay.dharmappa@intel.com>
> > > > > > +F: app/test/test_ipsec_perf.c
> > > > > >  M: Vladimir Medvedkin <vladimir.medvedkin@intel.com>
> > > > > >  F: app/test/test_ipsec_sad.c
> > > > > >  F: app/test-sad/
> > > > >
> > > > > Repeating what I said on v3:
> > > > > Having one different maintainer per test file is quite ridiculous.
> > > > > The maintainers of a lib are expected to maintain the related tests.
> > [...]
> > > About having separate MAINTAINER for the test -
> > > honestly I don't understand why it is a problem for you.
> > > Obviously we would like to spread the load - what's wrong with it?
> > 
> > This is a problem of ownership.
> > Maintaining a library means you take care of every aspect, including tests.
> > That's why I would like to see you as a global maintainer of IPsec.
> > 
> > It doesn't prevent you to delegate workload, of course.
> > But at the end it is more convenient to know there is a limited number
> > of persons responsible for the global quality of a component,
> > a person which is accountable and answering questions on the topic,
> > no matter which exact file we are talking about.
> 
> Just talked with Bernard, he kindly agreed to be a maintainer for all ipsec UT:
> app/test/test_ipsec*
> Hope that will fulfil your concern?

My concern was to have the library maintainer maintaining also the related tests.
I don't understand why you don't want to take this responsibility,
but I cannot force you.
Having only one maintainer for IPsec tests is better than the current situation.
  
Ananyev, Konstantin April 21, 2020, 12:04 p.m. UTC | #8
> 21/04/2020 13:07, Ananyev, Konstantin:
> > > 21/04/2020 12:21, Ananyev, Konstantin:
> > > > > 21/04/2020 04:29, Thomas Monjalon:
> > > > > > > --- a/MAINTAINERS
> > > > > > > +++ b/MAINTAINERS
> > > > > > > @@ -1259,6 +1259,8 @@ F: lib/librte_ipsec/
> > > > > > >  M: Bernard Iremonger <bernard.iremonger@intel.com>
> > > > > > >  F: app/test/test_ipsec.c
> > > > > > >  F: doc/guides/prog_guide/ipsec_lib.rst
> > > > > > > +M: Savinay Dharmappa <savinay.dharmappa@intel.com>
> > > > > > > +F: app/test/test_ipsec_perf.c
> > > > > > >  M: Vladimir Medvedkin <vladimir.medvedkin@intel.com>
> > > > > > >  F: app/test/test_ipsec_sad.c
> > > > > > >  F: app/test-sad/
> > > > > >
> > > > > > Repeating what I said on v3:
> > > > > > Having one different maintainer per test file is quite ridiculous.
> > > > > > The maintainers of a lib are expected to maintain the related tests.
> > > [...]
> > > > About having separate MAINTAINER for the test -
> > > > honestly I don't understand why it is a problem for you.
> > > > Obviously we would like to spread the load - what's wrong with it?
> > >
> > > This is a problem of ownership.
> > > Maintaining a library means you take care of every aspect, including tests.
> > > That's why I would like to see you as a global maintainer of IPsec.
> > >
> > > It doesn't prevent you to delegate workload, of course.
> > > But at the end it is more convenient to know there is a limited number
> > > of persons responsible for the global quality of a component,
> > > a person which is accountable and answering questions on the topic,
> > > no matter which exact file we are talking about.
> >
> > Just talked with Bernard, he kindly agreed to be a maintainer for all ipsec UT:
> > app/test/test_ipsec*
> > Hope that will fulfil your concern?
> 
> My concern was to have the library maintainer maintaining also the related tests.
> I don't understand why you don't want to take this responsibility,
> but I cannot force you.
> Having only one maintainer for IPsec tests is better than the current situation.

Ok, are you going to drop v4, so we can submit v5 with the fixes?
Or should we submit a patch with fixes on top of v4?
Konstantin
  
Thomas Monjalon April 21, 2020, 12:58 p.m. UTC | #9
21/04/2020 14:04, Ananyev, Konstantin:
> > 21/04/2020 13:07, Ananyev, Konstantin:
> > > > 21/04/2020 12:21, Ananyev, Konstantin:
> > > > > > 21/04/2020 04:29, Thomas Monjalon:
> > > > > > > > --- a/MAINTAINERS
> > > > > > > > +++ b/MAINTAINERS
> > > > > > > > @@ -1259,6 +1259,8 @@ F: lib/librte_ipsec/
> > > > > > > >  M: Bernard Iremonger <bernard.iremonger@intel.com>
> > > > > > > >  F: app/test/test_ipsec.c
> > > > > > > >  F: doc/guides/prog_guide/ipsec_lib.rst
> > > > > > > > +M: Savinay Dharmappa <savinay.dharmappa@intel.com>
> > > > > > > > +F: app/test/test_ipsec_perf.c
> > > > > > > >  M: Vladimir Medvedkin <vladimir.medvedkin@intel.com>
> > > > > > > >  F: app/test/test_ipsec_sad.c
> > > > > > > >  F: app/test-sad/
> > > > > > >
> > > > > > > Repeating what I said on v3:
> > > > > > > Having one different maintainer per test file is quite ridiculous.
> > > > > > > The maintainers of a lib are expected to maintain the related tests.
> > > > [...]
> > > > > About having separate MAINTAINER for the test -
> > > > > honestly I don't understand why it is a problem for you.
> > > > > Obviously we would like to spread the load - what's wrong with it?
> > > >
> > > > This is a problem of ownership.
> > > > Maintaining a library means you take care of every aspect, including tests.
> > > > That's why I would like to see you as a global maintainer of IPsec.
> > > >
> > > > It doesn't prevent you to delegate workload, of course.
> > > > But at the end it is more convenient to know there is a limited number
> > > > of persons responsible for the global quality of a component,
> > > > a person which is accountable and answering questions on the topic,
> > > > no matter which exact file we are talking about.
> > >
> > > Just talked with Bernard, he kindly agreed to be a maintainer for all ipsec UT:
> > > app/test/test_ipsec*
> > > Hope that will fulfil your concern?
> > 
> > My concern was to have the library maintainer maintaining also the related tests.
> > I don't understand why you don't want to take this responsibility,
> > but I cannot force you.
> > Having only one maintainer for IPsec tests is better than the current situation.
> 
> Ok, are you going to drop v4, so we can submit v5 with the fixes?
> Or should we submit a patch with fixes on top of v4?

v4 is dropped, you can send a v5.
  

Patch

diff --git a/MAINTAINERS b/MAINTAINERS
index c3785554f..6448fcb56 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1259,6 +1259,8 @@  F: lib/librte_ipsec/
 M: Bernard Iremonger <bernard.iremonger@intel.com>
 F: app/test/test_ipsec.c
 F: doc/guides/prog_guide/ipsec_lib.rst
+M: Savinay Dharmappa <savinay.dharmappa@intel.com>
+F: app/test/test_ipsec_perf.c
 M: Vladimir Medvedkin <vladimir.medvedkin@intel.com>
 F: app/test/test_ipsec_sad.c
 F: app/test-sad/
diff --git a/app/test/Makefile b/app/test/Makefile
index 1f080d162..83cf4c09d 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -231,7 +231,7 @@  SRCS-$(CONFIG_RTE_LIBRTE_BPF) += test_bpf.c
 
 SRCS-$(CONFIG_RTE_LIBRTE_RCU) += test_rcu_qsbr.c test_rcu_qsbr_perf.c
 
-SRCS-$(CONFIG_RTE_LIBRTE_IPSEC) += test_ipsec.c
+SRCS-$(CONFIG_RTE_LIBRTE_IPSEC) += test_ipsec.c test_ipsec_perf.c
 SRCS-$(CONFIG_RTE_LIBRTE_IPSEC) += test_ipsec_sad.c
 ifeq ($(CONFIG_RTE_LIBRTE_IPSEC),y)
 LDLIBS += -lrte_ipsec
diff --git a/app/test/meson.build b/app/test/meson.build
index 0a2ce710f..618742026 100644
--- a/app/test/meson.build
+++ b/app/test/meson.build
@@ -60,6 +60,7 @@  test_sources = files('commands.c',
 	'test_interrupts.c',
 	'test_ipsec.c',
 	'test_ipsec_sad.c',
+	'test_ipsec_perf.c',
 	'test_kni.c',
 	'test_kvargs.c',
 	'test_link_bonding.c',
@@ -270,6 +271,7 @@  perf_test_names = [
         'rand_perf_autotest',
         'hash_readwrite_perf_autotest',
         'hash_readwrite_lf_perf_autotest',
+	'ipsec_perf_autotest',
 ]
 
 driver_test_names = [
diff --git a/app/test/test_ipsec_perf.c b/app/test/test_ipsec_perf.c
new file mode 100644
index 000000000..d4541afe6
--- /dev/null
+++ b/app/test/test_ipsec_perf.c
@@ -0,0 +1,619 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2014 Intel Corporation
+ */
+
+#include <stdio.h>
+#include <rte_ip.h>
+#include <rte_malloc.h>
+#include <rte_ring.h>
+#include <rte_mbuf.h>
+#include <rte_malloc.h>
+#include <rte_cycles.h>
+#include <rte_ipsec.h>
+#include <rte_random.h>
+
+#include "test.h"
+#include "test_cryptodev.h"
+
+#define RING_SIZE	4096
+#define BURST_SIZE	64
+#define NUM_MBUF	4095
+#define DEFAULT_SPI     7
+
+struct ipsec_test_cfg {
+	uint32_t replay_win_sz;
+	uint32_t esn;
+	uint64_t flags;
+	enum rte_crypto_sym_xform_type type;
+};
+
+struct rte_mempool *mbuf_pool, *cop_pool;
+
+struct stats_counter {
+	uint64_t nb_prepare_call;
+	uint64_t nb_prepare_pkt;
+	uint64_t nb_process_call;
+	uint64_t nb_process_pkt;
+	uint64_t prepare_ticks_elapsed;
+	uint64_t process_ticks_elapsed;
+};
+
+struct ipsec_sa {
+	struct rte_ipsec_session ss[2];
+	struct rte_ipsec_sa_prm sa_prm;
+	struct rte_security_ipsec_xform ipsec_xform;
+	struct rte_crypto_sym_xform cipher_xform;
+	struct rte_crypto_sym_xform auth_xform;
+	struct rte_crypto_sym_xform aead_xform;
+	struct rte_crypto_sym_xform *crypto_xforms;
+	struct rte_crypto_op *cop[BURST_SIZE];
+	enum rte_crypto_sym_xform_type type;
+	struct stats_counter cnt;
+	uint32_t replay_win_sz;
+	uint32_t sa_flags;
+};
+
+static const struct ipsec_test_cfg test_cfg[] = {
+	{0, 0, 0, RTE_CRYPTO_SYM_XFORM_AEAD},
+	{0, 0, 0, RTE_CRYPTO_SYM_XFORM_CIPHER},
+	{128, 1, 0, RTE_CRYPTO_SYM_XFORM_AEAD},
+	{128, 1, 0, RTE_CRYPTO_SYM_XFORM_CIPHER},
+
+};
+
+static struct rte_ipv4_hdr ipv4_outer  = {
+	.version_ihl = IPVERSION << 4 |
+		sizeof(ipv4_outer) / RTE_IPV4_IHL_MULTIPLIER,
+	.time_to_live = IPDEFTTL,
+	.next_proto_id = IPPROTO_ESP,
+	.src_addr = RTE_IPV4(192, 168, 1, 100),
+	.dst_addr = RTE_IPV4(192, 168, 2, 100),
+};
+
+static struct rte_ring *ring_inb_prepare;
+static struct rte_ring *ring_inb_process;
+static struct rte_ring *ring_outb_prepare;
+static struct rte_ring *ring_outb_process;
+
+struct supported_cipher_algo {
+	const char *keyword;
+	enum rte_crypto_cipher_algorithm algo;
+	uint16_t iv_len;
+	uint16_t block_size;
+	uint16_t key_len;
+};
+
+struct supported_auth_algo {
+	const char *keyword;
+	enum rte_crypto_auth_algorithm algo;
+	uint16_t digest_len;
+	uint16_t key_len;
+	uint8_t key_not_req;
+};
+
+struct supported_aead_algo {
+	const char *keyword;
+	enum rte_crypto_aead_algorithm algo;
+	uint16_t iv_len;
+	uint16_t block_size;
+	uint16_t digest_len;
+	uint16_t key_len;
+	uint8_t aad_len;
+};
+
+const struct supported_cipher_algo cipher_algo[] = {
+	{
+		.keyword = "aes-128-cbc",
+		.algo = RTE_CRYPTO_CIPHER_AES_CBC,
+		.iv_len = 16,
+		.block_size = 16,
+		.key_len = 16
+	}
+};
+
+const struct supported_auth_algo auth_algo[] = {
+	{
+		.keyword = "sha1-hmac",
+		.algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
+		.digest_len = 12,
+		.key_len = 20
+	}
+};
+
+const struct supported_aead_algo aead_algo[] = {
+	{
+		.keyword = "aes-128-gcm",
+		.algo = RTE_CRYPTO_AEAD_AES_GCM,
+		.iv_len = 8,
+		.block_size = 4,
+		.key_len = 20,
+		.digest_len = 16,
+		.aad_len = 8,
+	}
+};
+
+static struct rte_mbuf *generate_mbuf_data(struct rte_mempool *mpool)
+{
+	struct rte_mbuf *mbuf = rte_pktmbuf_alloc(mpool);
+
+	if (mbuf) {
+		mbuf->data_len = 64;
+		mbuf->pkt_len  = 64;
+	}
+
+	return mbuf;
+}
+
+static int
+fill_ipsec_param(struct ipsec_sa *sa)
+{
+	struct rte_ipsec_sa_prm *prm = &sa->sa_prm;
+
+	memset(prm, 0, sizeof(*prm));
+
+	prm->flags = sa->sa_flags;
+
+	/* setup ipsec xform */
+	prm->ipsec_xform = sa->ipsec_xform;
+	prm->ipsec_xform.salt = (uint32_t)rte_rand();
+	prm->ipsec_xform.replay_win_sz = sa->replay_win_sz;
+
+	/* setup tunnel related fields */
+	prm->tun.hdr_len = sizeof(ipv4_outer);
+	prm->tun.next_proto = IPPROTO_IPIP;
+	prm->tun.hdr = &ipv4_outer;
+
+	if (sa->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
+		sa->aead_xform.type = sa->type;
+		sa->aead_xform.aead.algo = aead_algo->algo;
+		sa->aead_xform.next = NULL;
+		sa->aead_xform.aead.digest_length = aead_algo->digest_len;
+		sa->aead_xform.aead.iv.offset = IV_OFFSET;
+		sa->aead_xform.aead.iv.length = 12;
+
+		if (sa->ipsec_xform.direction ==
+				RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
+			sa->aead_xform.aead.op = RTE_CRYPTO_AEAD_OP_DECRYPT;
+		} else {
+			sa->aead_xform.aead.op = RTE_CRYPTO_AEAD_OP_ENCRYPT;
+		}
+
+		sa->crypto_xforms = &sa->aead_xform;
+	} else {
+		sa->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+		sa->cipher_xform.cipher.algo = cipher_algo->algo;
+		sa->cipher_xform.cipher.iv.offset = IV_OFFSET;
+		sa->cipher_xform.cipher.iv.length = 12;
+		sa->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH;
+		sa->auth_xform.auth.algo = auth_algo->algo;
+		sa->auth_xform.auth.digest_length = auth_algo->digest_len;
+
+
+		if (sa->ipsec_xform.direction ==
+				RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
+			sa->cipher_xform.cipher.op =
+				RTE_CRYPTO_CIPHER_OP_DECRYPT;
+			sa->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY;
+			sa->cipher_xform.next = NULL;
+			sa->auth_xform.next = &sa->cipher_xform;
+			sa->crypto_xforms = &sa->auth_xform;
+		} else {
+			sa->cipher_xform.cipher.op =
+				RTE_CRYPTO_CIPHER_OP_ENCRYPT;
+			sa->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE;
+			sa->auth_xform.next = NULL;
+			sa->cipher_xform.next = &sa->auth_xform;
+			sa->crypto_xforms = &sa->cipher_xform;
+		}
+	}
+
+	prm->crypto_xform = sa->crypto_xforms;
+
+	return TEST_SUCCESS;
+}
+
+static int
+create_sa(enum rte_security_session_action_type action_type,
+	  struct ipsec_sa *sa)
+{
+	static struct rte_cryptodev_sym_session dummy_ses;
+	size_t sz;
+	int rc;
+
+	memset(&sa->ss[0], 0, sizeof(sa->ss[0]));
+
+	rc = fill_ipsec_param(sa);
+	if (rc != 0) {
+		printf("failed to fill ipsec param\n");
+		return TEST_FAILED;
+	}
+
+	/* create rte_ipsec_sa*/
+	sz = rte_ipsec_sa_size(&sa->sa_prm);
+	TEST_ASSERT(sz > 0, "rte_ipsec_sa_size() failed\n");
+
+	sa->ss[0].sa = rte_zmalloc(NULL, sz, RTE_CACHE_LINE_SIZE);
+	TEST_ASSERT_NOT_NULL(sa->ss[0].sa,
+		"failed to allocate memory for rte_ipsec_sa\n");
+
+	sa->ss[0].type = action_type;
+	sa->ss[0].crypto.ses = &dummy_ses;
+
+	rc = rte_ipsec_sa_init(sa->ss[0].sa, &sa->sa_prm, sz);
+	rc = (rc > 0 && (uint32_t)rc <= sz) ? 0 : -EINVAL;
+
+	if (rc == 0)
+		rc = rte_ipsec_session_prepare(&sa->ss[0]);
+	else
+		return TEST_FAILED;
+
+	return TEST_SUCCESS;
+}
+
+static int
+packet_prepare(struct rte_mbuf **buf, struct ipsec_sa *sa,
+	       uint16_t num_pkts)
+{
+	uint64_t time_stamp;
+	uint16_t k = 0, i;
+
+	for (i = 0; i < num_pkts; i++) {
+
+		sa->cop[i] = rte_crypto_op_alloc(cop_pool,
+				RTE_CRYPTO_OP_TYPE_SYMMETRIC);
+
+		if (sa->cop[i] == NULL) {
+
+			RTE_LOG(ERR, USER1,
+			"Failed to allocate symmetric crypto op\n");
+
+			return k;
+		}
+	}
+
+	/* call crypto prepare */
+	time_stamp = rte_rdtsc_precise();
+
+	k = rte_ipsec_pkt_crypto_prepare(&sa->ss[0], buf,
+		sa->cop, num_pkts);
+
+	time_stamp = rte_rdtsc_precise() - time_stamp;
+
+	if (k != num_pkts) {
+		RTE_LOG(ERR, USER1, "rte_ipsec_pkt_crypto_prepare fail\n");
+		return k;
+	}
+
+	sa->cnt.prepare_ticks_elapsed += time_stamp;
+	sa->cnt.nb_prepare_call++;
+	sa->cnt.nb_prepare_pkt += k;
+
+	for (i = 0; i < num_pkts; i++)
+		rte_crypto_op_free(sa->cop[i]);
+
+	return k;
+}
+
+static int
+packet_process(struct rte_mbuf **buf, struct ipsec_sa *sa,
+	       uint16_t num_pkts)
+{
+	uint64_t time_stamp;
+	uint16_t k = 0;
+
+	time_stamp = rte_rdtsc_precise();
+
+	/* call crypto prepare */
+	k = rte_ipsec_pkt_process(&sa->ss[0], buf, num_pkts);
+
+	time_stamp = rte_rdtsc_precise() - time_stamp;
+
+	if (k != num_pkts) {
+		RTE_LOG(ERR, USER1, "rte_ipsec_pkt_process fail\n");
+		return k;
+	}
+
+	sa->cnt.process_ticks_elapsed += time_stamp;
+	sa->cnt.nb_process_call++;
+	sa->cnt.nb_process_pkt += k;
+
+	return k;
+}
+
+static int
+create_traffic(struct ipsec_sa *sa, struct rte_ring *deq_ring,
+	       struct rte_ring *enq_ring, struct rte_ring *ring)
+{
+	struct rte_mbuf *mbuf[BURST_SIZE];
+	uint16_t num_pkts, n;
+
+	while (rte_ring_empty(deq_ring) == 0) {
+
+		num_pkts = rte_ring_sc_dequeue_burst(deq_ring, (void **)mbuf,
+						     RTE_DIM(mbuf), NULL);
+
+		if (num_pkts == 0)
+			return TEST_FAILED;
+
+		n = packet_prepare(mbuf, sa, num_pkts);
+		if (n != num_pkts)
+			return TEST_FAILED;
+
+		num_pkts = rte_ring_sp_enqueue_burst(enq_ring, (void **)mbuf,
+						     num_pkts, NULL);
+		if (num_pkts == 0)
+			return TEST_FAILED;
+	}
+
+	deq_ring = enq_ring;
+	enq_ring = ring;
+
+	while (rte_ring_empty(deq_ring) == 0) {
+
+		num_pkts = rte_ring_sc_dequeue_burst(deq_ring, (void **)mbuf,
+					       RTE_DIM(mbuf), NULL);
+		if (num_pkts == 0)
+			return TEST_FAILED;
+
+		n = packet_process(mbuf, sa, num_pkts);
+		if (n != num_pkts)
+			return TEST_FAILED;
+
+		num_pkts = rte_ring_sp_enqueue_burst(enq_ring, (void **)mbuf,
+					       num_pkts, NULL);
+		if (num_pkts == 0)
+			return TEST_FAILED;
+	}
+
+	return TEST_SUCCESS;
+}
+
+static void
+fill_ipsec_sa_out(const struct ipsec_test_cfg *test_cfg,
+		  struct ipsec_sa *sa)
+{
+	sa->ipsec_xform.spi = DEFAULT_SPI;
+	sa->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS;
+	sa->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
+	sa->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
+	sa->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
+	sa->ipsec_xform.options.esn = test_cfg->esn;
+	sa->type = test_cfg->type;
+	sa->replay_win_sz = test_cfg->replay_win_sz;
+	sa->sa_flags = test_cfg->flags;
+	sa->cnt.nb_prepare_call = 0;
+	sa->cnt.nb_prepare_pkt = 0;
+	sa->cnt.nb_process_call = 0;
+	sa->cnt.nb_process_pkt = 0;
+	sa->cnt.process_ticks_elapsed = 0;
+	sa->cnt.prepare_ticks_elapsed = 0;
+
+}
+
+static void
+fill_ipsec_sa_in(const struct ipsec_test_cfg *test_cfg,
+		  struct ipsec_sa *sa)
+{
+	sa->ipsec_xform.spi = DEFAULT_SPI;
+	sa->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
+	sa->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
+	sa->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
+	sa->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
+	sa->ipsec_xform.options.esn = test_cfg->esn;
+	sa->type = test_cfg->type;
+	sa->replay_win_sz = test_cfg->replay_win_sz;
+	sa->sa_flags = test_cfg->flags;
+	sa->cnt.nb_prepare_call = 0;
+	sa->cnt.nb_prepare_pkt = 0;
+	sa->cnt.nb_process_call = 0;
+	sa->cnt.nb_process_pkt = 0;
+	sa->cnt.process_ticks_elapsed = 0;
+	sa->cnt.prepare_ticks_elapsed = 0;
+}
+
+static int
+init_sa_session(const struct ipsec_test_cfg *test_cfg,
+		struct ipsec_sa *sa_out, struct ipsec_sa *sa_in)
+{
+
+	int rc;
+
+	fill_ipsec_sa_in(test_cfg, sa_in);
+	fill_ipsec_sa_out(test_cfg, sa_out);
+
+	/* create rte_ipsec_sa*/
+	rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE, sa_out);
+	if (rc != 0) {
+		RTE_LOG(ERR, USER1, "out bound create_sa failed, cfg\n");
+		return TEST_FAILED;
+	}
+
+	rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE, sa_in);
+	if (rc != 0) {
+		RTE_LOG(ERR, USER1, "out bound create_sa failed, cfg\n");
+		return TEST_FAILED;
+	}
+
+	return TEST_SUCCESS;
+}
+
+static int
+testsuite_setup(void)
+{
+	struct rte_mbuf *mbuf;
+	int i;
+
+	mbuf_pool = rte_pktmbuf_pool_create("IPSEC_PERF_MBUFPOOL",
+			NUM_MBUFS, MBUF_CACHE_SIZE, 0, MBUF_SIZE,
+			rte_socket_id());
+	if (mbuf_pool == NULL) {
+		RTE_LOG(ERR, USER1, "Can't create MBUFPOOL\n");
+		return TEST_FAILED;
+	}
+
+	cop_pool = rte_crypto_op_pool_create(
+			"MBUF_CRYPTO_SYM_OP_POOL",
+			RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+			NUM_MBUFS, MBUF_CACHE_SIZE,
+			DEFAULT_NUM_XFORMS *
+			sizeof(struct rte_crypto_sym_xform) +
+			MAXIMUM_IV_LENGTH,
+			rte_socket_id());
+	if (cop_pool == NULL) {
+		RTE_LOG(ERR, USER1, "Can't create CRYPTO_OP_POOL\n");
+		return TEST_FAILED;
+	}
+
+	ring_inb_prepare = rte_ring_create("ring0", RING_SIZE,
+					   SOCKET_ID_ANY, 0);
+	if (ring_inb_prepare == NULL)
+		return TEST_FAILED;
+
+	ring_inb_process = rte_ring_create("ring1", RING_SIZE,
+					   SOCKET_ID_ANY, 0);
+	if (ring_inb_process == NULL)
+		return TEST_FAILED;
+
+	ring_outb_prepare = rte_ring_create("ring2", RING_SIZE,
+					    SOCKET_ID_ANY, 0);
+	if (ring_outb_prepare == NULL)
+		return TEST_FAILED;
+
+	ring_outb_process = rte_ring_create("ring3", RING_SIZE,
+					    SOCKET_ID_ANY, 0);
+	if (ring_outb_process == NULL)
+		return TEST_FAILED;
+
+	for (i = 0; i < NUM_MBUF; i++) {
+		mbuf = generate_mbuf_data(mbuf_pool);
+
+		if (mbuf && rte_ring_sp_enqueue_bulk(ring_inb_prepare,
+			   (void **)&mbuf, 1, NULL))
+			continue;
+		else
+			return TEST_FAILED;
+	}
+
+	return TEST_SUCCESS;
+}
+
+static int
+measure_performance(struct ipsec_sa *sa_out, struct ipsec_sa *sa_in)
+{
+	uint64_t time_diff = 0;
+	uint64_t begin = 0;
+	uint64_t hz = rte_get_timer_hz();
+
+	begin = rte_get_timer_cycles();
+
+	do {
+		if (create_traffic(sa_out, ring_inb_prepare, ring_inb_process,
+				   ring_outb_prepare) < 0)
+			return TEST_FAILED;
+
+		if (create_traffic(sa_in, ring_outb_prepare, ring_outb_process,
+				   ring_inb_prepare) < 0)
+			return TEST_FAILED;
+
+		time_diff = rte_get_timer_cycles() - begin;
+
+	} while (time_diff < (hz * 10));
+
+	return TEST_SUCCESS;
+}
+
+static void
+print_metrics(const struct ipsec_test_cfg *test_cfg,
+	      struct ipsec_sa *sa_out, struct ipsec_sa *sa_in)
+{
+	printf("\nMetrics of libipsec prepare/process api:\n");
+
+	printf("replay window size = %u\n", test_cfg->replay_win_sz);
+	if (test_cfg->esn)
+		printf("replay esn is enabled\n");
+	else
+		printf("replay esn is disabled\n");
+	if (test_cfg->type == RTE_CRYPTO_SYM_XFORM_AEAD)
+		printf("AEAD algo is AES_GCM\n");
+	else
+		printf("CIPHER/AUTH algo is AES_CBC/SHA1\n");
+
+
+	printf("avg cycles for a pkt prepare in outbound is = %.2Lf\n",
+	(long double)sa_out->cnt.prepare_ticks_elapsed
+		    / sa_out->cnt.nb_prepare_pkt);
+	printf("avg cycles for a pkt process in outbound is = %.2Lf\n",
+	(long double)sa_out->cnt.process_ticks_elapsed
+		     / sa_out->cnt.nb_process_pkt);
+	printf("avg cycles for a pkt prepare in inbound is = %.2Lf\n",
+	(long double)sa_in->cnt.prepare_ticks_elapsed
+		     / sa_in->cnt.nb_prepare_pkt);
+	printf("avg cycles for a pkt process in inbound is = %.2Lf\n",
+	(long double)sa_in->cnt.process_ticks_elapsed
+		     / sa_in->cnt.nb_process_pkt);
+
+}
+
+static void
+testsuite_teardown(void)
+{
+	if (mbuf_pool != NULL) {
+		RTE_LOG(DEBUG, USER1, "MBUFPOOL count %u\n",
+		rte_mempool_avail_count(mbuf_pool));
+		rte_mempool_free(mbuf_pool);
+		mbuf_pool = NULL;
+	}
+
+	if (cop_pool != NULL) {
+		RTE_LOG(DEBUG, USER1, "CRYPTO_OP_POOL count %u\n",
+		rte_mempool_avail_count(cop_pool));
+		rte_mempool_free(cop_pool);
+		cop_pool = NULL;
+	}
+
+	rte_ring_free(ring_inb_prepare);
+	rte_ring_free(ring_inb_process);
+	rte_ring_free(ring_outb_prepare);
+	rte_ring_free(ring_outb_process);
+
+	ring_inb_prepare = NULL;
+	ring_inb_process = NULL;
+	ring_outb_prepare = NULL;
+	ring_outb_process = NULL;
+}
+
+static int
+test_libipsec_perf(void)
+{
+	struct ipsec_sa sa_out;
+	struct ipsec_sa sa_in;
+	uint32_t i;
+	int ret;
+
+	if (testsuite_setup() < 0) {
+		testsuite_teardown();
+		return TEST_FAILED;
+	}
+
+	for (i = 0; i < RTE_DIM(test_cfg) ; i++) {
+
+		ret = init_sa_session(&test_cfg[i], &sa_out, &sa_in);
+		if (ret != 0) {
+			testsuite_teardown();
+			return TEST_FAILED;
+		}
+
+		if (measure_performance(&sa_out, &sa_in) < 0) {
+			testsuite_teardown();
+			return TEST_FAILED;
+		}
+
+		print_metrics(&test_cfg[i], &sa_out, &sa_in);
+	}
+
+	testsuite_teardown();
+
+	return TEST_SUCCESS;
+}
+
+REGISTER_TEST_COMMAND(ipsec_perf_autotest, test_libipsec_perf);