diff --git a/app/test-crypto-perf/cperf.h b/app/test-crypto-perf/cperf.h
index 293ba94..42070d6 100644
--- a/app/test-crypto-perf/cperf.h
+++ b/app/test-crypto-perf/cperf.h
@@ -41,7 +41,10 @@ struct cperf_options;
 struct cperf_test_vector;
 struct cperf_op_fns;
 
-typedef void  *(*cperf_constructor_t)(uint8_t dev_id, uint16_t qp_id,
+typedef void  *(*cperf_constructor_t)(
+		struct rte_cryptodev_sym_session *sess,
+		uint8_t dev_id,
+		uint16_t qp_id,
 		const struct cperf_options *options,
 		const struct cperf_test_vector *t_vec,
 		const struct cperf_op_fns *op_fns);
diff --git a/app/test-crypto-perf/cperf_ops.c b/app/test-crypto-perf/cperf_ops.c
index c2c3db5..8f05dbd 100644
--- a/app/test-crypto-perf/cperf_ops.c
+++ b/app/test-crypto-perf/cperf_ops.c
@@ -334,13 +334,13 @@ cperf_set_ops_aead(struct rte_crypto_op **ops,
 }
 
 static struct rte_cryptodev_sym_session *
-cperf_create_session(uint8_t dev_id,
+cperf_create_session(struct rte_cryptodev_sym_session *sess,
+	uint8_t dev_id,
 	const struct cperf_options *options,
 	const struct cperf_test_vector *test_vector)
 {
 	struct rte_crypto_sym_xform cipher_xform;
 	struct rte_crypto_sym_xform auth_xform;
-	struct rte_cryptodev_sym_session *sess = NULL;
 
 	/*
 	 * cipher only
@@ -362,7 +362,7 @@ cperf_create_session(uint8_t dev_id,
 			cipher_xform.cipher.key.length = 0;
 		}
 		/* create crypto session */
-		sess = rte_cryptodev_sym_session_create(dev_id,	&cipher_xform);
+		rte_cryptodev_sym_session_init(dev_id, sess, &cipher_xform);
 	/*
 	 *  auth only
 	 */
@@ -388,7 +388,7 @@ cperf_create_session(uint8_t dev_id,
 			auth_xform.auth.key.data = NULL;
 		}
 		/* create crypto session */
-		sess =  rte_cryptodev_sym_session_create(dev_id, &auth_xform);
+		rte_cryptodev_sym_session_init(dev_id, sess, &auth_xform);
 	/*
 	 * cipher and auth
 	 */
@@ -452,29 +452,31 @@ cperf_create_session(uint8_t dev_id,
 					RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
 				cipher_xform.next = &auth_xform;
 				/* create crypto session */
-				sess = rte_cryptodev_sym_session_create(dev_id,
-					&cipher_xform);
+				rte_cryptodev_sym_session_init(dev_id,
+						sess, &cipher_xform);
+
 			} else { /* decrypt */
 				auth_xform.next = &cipher_xform;
 				/* create crypto session */
-				sess = rte_cryptodev_sym_session_create(dev_id,
-					&auth_xform);
+				rte_cryptodev_sym_session_init(dev_id,
+						sess, &auth_xform);
 			}
 		} else { /* create crypto session for other */
 			/* cipher then auth */
 			if (options->op_type == CPERF_CIPHER_THEN_AUTH) {
 				cipher_xform.next = &auth_xform;
 				/* create crypto session */
-				sess = rte_cryptodev_sym_session_create(dev_id,
-						&cipher_xform);
+				rte_cryptodev_sym_session_init(dev_id,
+						sess, &cipher_xform);
 			} else { /* auth then cipher */
 				auth_xform.next = &cipher_xform;
 				/* create crypto session */
-				sess = rte_cryptodev_sym_session_create(dev_id,
-						&auth_xform);
+				rte_cryptodev_sym_session_init(dev_id,
+						sess, &auth_xform);
 			}
 		}
 	}
+
 	return sess;
 }
 
diff --git a/app/test-crypto-perf/cperf_ops.h b/app/test-crypto-perf/cperf_ops.h
index 1b748da..76abdf2 100644
--- a/app/test-crypto-perf/cperf_ops.h
+++ b/app/test-crypto-perf/cperf_ops.h
@@ -41,6 +41,7 @@
 
 
 typedef struct rte_cryptodev_sym_session *(*cperf_sessions_create_t)(
+		struct rte_cryptodev_sym_session *sess,
 		uint8_t dev_id, const struct cperf_options *options,
 		const struct cperf_test_vector *test_vector);
 
diff --git a/app/test-crypto-perf/cperf_test_latency.c b/app/test-crypto-perf/cperf_test_latency.c
index e61ac97..1a309b6 100644
--- a/app/test-crypto-perf/cperf_test_latency.c
+++ b/app/test-crypto-perf/cperf_test_latency.c
@@ -76,7 +76,7 @@ cperf_latency_test_free(struct cperf_latency_ctx *ctx, uint32_t mbuf_nb)
 
 	if (ctx) {
 		if (ctx->sess)
-			rte_cryptodev_sym_session_free(ctx->dev_id, ctx->sess);
+			rte_cryptodev_sym_session_free(ctx->sess);
 
 		if (ctx->mbufs_in) {
 			for (i = 0; i < mbuf_nb; i++)
@@ -187,7 +187,8 @@ cperf_mbuf_create(struct rte_mempool *mempool,
 }
 
 void *
-cperf_latency_test_constructor(uint8_t dev_id, uint16_t qp_id,
+cperf_latency_test_constructor(struct rte_cryptodev_sym_session *sess,
+		uint8_t dev_id, uint16_t qp_id,
 		const struct cperf_options *options,
 		const struct cperf_test_vector *test_vector,
 		const struct cperf_op_fns *op_fns)
@@ -207,7 +208,7 @@ cperf_latency_test_constructor(uint8_t dev_id, uint16_t qp_id,
 	ctx->options = options;
 	ctx->test_vector = test_vector;
 
-	ctx->sess = op_fns->sess_create(dev_id, options, test_vector);
+	ctx->sess = op_fns->sess_create(sess, dev_id, options, test_vector);
 	if (ctx->sess == NULL)
 		goto err;
 
diff --git a/app/test-crypto-perf/cperf_test_latency.h b/app/test-crypto-perf/cperf_test_latency.h
index 6a2cf61..ddd7404 100644
--- a/app/test-crypto-perf/cperf_test_latency.h
+++ b/app/test-crypto-perf/cperf_test_latency.h
@@ -43,7 +43,10 @@
 #include "cperf_test_vectors.h"
 
 void *
-cperf_latency_test_constructor(uint8_t dev_id, uint16_t qp_id,
+cperf_latency_test_constructor(
+		struct rte_cryptodev_sym_session *sess,
+		uint8_t dev_id,
+		uint16_t qp_id,
 		const struct cperf_options *options,
 		const struct cperf_test_vector *test_vector,
 		const struct cperf_op_fns *ops_fn);
diff --git a/app/test-crypto-perf/cperf_test_throughput.c b/app/test-crypto-perf/cperf_test_throughput.c
index 61b27ea..bcf64fc 100644
--- a/app/test-crypto-perf/cperf_test_throughput.c
+++ b/app/test-crypto-perf/cperf_test_throughput.c
@@ -65,7 +65,7 @@ cperf_throughput_test_free(struct cperf_throughput_ctx *ctx, uint32_t mbuf_nb)
 
 	if (ctx) {
 		if (ctx->sess)
-			rte_cryptodev_sym_session_free(ctx->dev_id, ctx->sess);
+			rte_cryptodev_sym_session_free(ctx->sess);
 
 		if (ctx->mbufs_in) {
 			for (i = 0; i < mbuf_nb; i++)
@@ -175,7 +175,8 @@ cperf_mbuf_create(struct rte_mempool *mempool,
 }
 
 void *
-cperf_throughput_test_constructor(uint8_t dev_id, uint16_t qp_id,
+cperf_throughput_test_constructor(struct rte_cryptodev_sym_session *sess,
+		uint8_t dev_id, uint16_t qp_id,
 		const struct cperf_options *options,
 		const struct cperf_test_vector *test_vector,
 		const struct cperf_op_fns *op_fns)
@@ -195,7 +196,7 @@ cperf_throughput_test_constructor(uint8_t dev_id, uint16_t qp_id,
 	ctx->options = options;
 	ctx->test_vector = test_vector;
 
-	ctx->sess = op_fns->sess_create(dev_id, options, test_vector);
+	ctx->sess = op_fns->sess_create(sess, dev_id, options, test_vector);
 	if (ctx->sess == NULL)
 		goto err;
 
diff --git a/app/test-crypto-perf/cperf_test_throughput.h b/app/test-crypto-perf/cperf_test_throughput.h
index f1b5766..9a8545e 100644
--- a/app/test-crypto-perf/cperf_test_throughput.h
+++ b/app/test-crypto-perf/cperf_test_throughput.h
@@ -44,7 +44,10 @@
 
 
 void *
-cperf_throughput_test_constructor(uint8_t dev_id, uint16_t qp_id,
+cperf_throughput_test_constructor(
+		struct rte_cryptodev_sym_session *sess,
+		uint8_t dev_id,
+		uint16_t qp_id,
 		const struct cperf_options *options,
 		const struct cperf_test_vector *test_vector,
 		const struct cperf_op_fns *ops_fn);
diff --git a/app/test-crypto-perf/cperf_test_verify.c b/app/test-crypto-perf/cperf_test_verify.c
index 454221e..287dabb 100644
--- a/app/test-crypto-perf/cperf_test_verify.c
+++ b/app/test-crypto-perf/cperf_test_verify.c
@@ -69,7 +69,7 @@ cperf_verify_test_free(struct cperf_verify_ctx *ctx, uint32_t mbuf_nb)
 
 	if (ctx) {
 		if (ctx->sess)
-			rte_cryptodev_sym_session_free(ctx->dev_id, ctx->sess);
+			rte_cryptodev_sym_session_free(ctx->sess);
 
 		if (ctx->mbufs_in) {
 			for (i = 0; i < mbuf_nb; i++)
@@ -179,7 +179,8 @@ cperf_mbuf_create(struct rte_mempool *mempool,
 }
 
 void *
-cperf_verify_test_constructor(uint8_t dev_id, uint16_t qp_id,
+cperf_verify_test_constructor(struct rte_cryptodev_sym_session *sess,
+		uint8_t dev_id, uint16_t qp_id,
 		const struct cperf_options *options,
 		const struct cperf_test_vector *test_vector,
 		const struct cperf_op_fns *op_fns)
@@ -199,7 +200,7 @@ cperf_verify_test_constructor(uint8_t dev_id, uint16_t qp_id,
 	ctx->options = options;
 	ctx->test_vector = test_vector;
 
-	ctx->sess = op_fns->sess_create(dev_id, options, test_vector);
+	ctx->sess = op_fns->sess_create(sess, dev_id, options, test_vector);
 	if (ctx->sess == NULL)
 		goto err;
 
diff --git a/app/test-crypto-perf/cperf_test_verify.h b/app/test-crypto-perf/cperf_test_verify.h
index 3fa78ee..f324656 100644
--- a/app/test-crypto-perf/cperf_test_verify.h
+++ b/app/test-crypto-perf/cperf_test_verify.h
@@ -44,7 +44,10 @@
 
 
 void *
-cperf_verify_test_constructor(uint8_t dev_id, uint16_t qp_id,
+cperf_verify_test_constructor(
+		struct rte_cryptodev_sym_session *sess,
+		uint8_t dev_id,
+		uint16_t qp_id,
 		const struct cperf_options *options,
 		const struct cperf_test_vector *test_vector,
 		const struct cperf_op_fns *ops_fn);
diff --git a/app/test-crypto-perf/main.c b/app/test-crypto-perf/main.c
index 9ec2a4b..f889acb 100644
--- a/app/test-crypto-perf/main.c
+++ b/app/test-crypto-perf/main.c
@@ -43,6 +43,9 @@ const struct cperf_test cperf_testmap[] = {
 		}
 };
 
+static struct rte_mempool *cperf_mempool;
+static struct rte_cryptodev_sym_session *cperf_session;
+
 static int
 cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs)
 {
@@ -66,20 +69,21 @@ cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs)
 		return -EINVAL;
 	}
 
+	struct rte_cryptodev_config conf = {
+			.nb_queue_pairs = 1,
+			.socket_id = SOCKET_ID_ANY,
+			.session_mp = {
+				.nb_objs = 2048,
+				.cache_size = 64
+			}
+		};
+	struct rte_cryptodev_qp_conf qp_conf = {
+			.nb_descriptors = 2048
+	};
+
 	for (cdev_id = 0; cdev_id < enabled_cdev_count &&
 			cdev_id < RTE_CRYPTO_MAX_DEVS; cdev_id++) {
 
-		struct rte_cryptodev_config conf = {
-				.nb_queue_pairs = 1,
-				.socket_id = SOCKET_ID_ANY,
-				.session_mp = {
-					.nb_objs = 2048,
-					.cache_size = 64
-				}
-			};
-		struct rte_cryptodev_qp_conf qp_conf = {
-				.nb_descriptors = 2048
-		};
 
 		ret = rte_cryptodev_configure(enabled_cdevs[cdev_id], &conf);
 		if (ret < 0) {
@@ -104,6 +108,14 @@ cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs)
 		}
 	}
 
+	cperf_mempool = rte_cryptodev_sym_session_pool_create(
+			conf.session_mp.nb_objs,
+			enabled_cdevs,
+			enabled_cdev_count,
+			0, rte_socket_id());
+
+	cperf_session = rte_cryptodev_sym_session_create(cperf_mempool);
+
 	return enabled_cdev_count;
 }
 
@@ -367,7 +379,8 @@ main(int argc, char **argv)
 
 		cdev_id = enabled_cdevs[i];
 
-		ctx[cdev_id] = cperf_testmap[opts.test].constructor(cdev_id, 0,
+		ctx[cdev_id] = cperf_testmap[opts.test].constructor(
+				cperf_session, cdev_id, 0,
 				&opts, t_vec, &op_fns);
 		if (ctx[cdev_id] == NULL) {
 			RTE_LOG(ERR, USER1, "Test run constructor failed\n");
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
index b2a0606..9975f1f 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
@@ -145,19 +145,20 @@ aesni_gcm_get_session(struct aesni_gcm_qp *qp, struct rte_crypto_sym_op *op)
 	struct aesni_gcm_session *sess = NULL;
 
 	if (op->sess_type == RTE_CRYPTO_SYM_OP_WITH_SESSION) {
-		if (unlikely(op->session->driver_id !=
-				cryptodev_driver_id))
-			return sess;
-
-		sess = (struct aesni_gcm_session *)op->session->_private;
-	} else  {
+		if (likely(op->session != NULL))
+			sess = (struct aesni_gcm_session *)
+					get_session_private_data(
+					op->session,
+					cryptodev_driver_id);
+	} else {
 		void *_sess;
 
 		if (rte_mempool_get(qp->sess_mp, &_sess))
 			return sess;
 
 		sess = (struct aesni_gcm_session *)
-			((struct rte_cryptodev_sym_session *)_sess)->_private;
+				get_session_private_data(_sess,
+				cryptodev_driver_id);
 
 		if (unlikely(aesni_gcm_set_session_parameters(sess,
 				op->xform) != 0)) {
@@ -330,8 +331,9 @@ post_process_gcm_crypto_op(struct rte_crypto_op *op)
 {
 	struct rte_mbuf *m = op->sym->m_dst ? op->sym->m_dst : op->sym->m_src;
 
-	struct aesni_gcm_session *session =
-		(struct aesni_gcm_session *)op->sym->session->_private;
+	struct aesni_gcm_session *session = (struct aesni_gcm_session *)
+			get_session_private_data(op->sym->session,
+			cryptodev_driver_id);
 
 	op->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
 
diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
index 9a701ce..ab854f1 100644
--- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
+++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
@@ -347,20 +347,19 @@ get_session(struct aesni_mb_qp *qp, struct rte_crypto_op *op)
 	struct aesni_mb_session *sess = NULL;
 
 	if (op->sym->sess_type == RTE_CRYPTO_SYM_OP_WITH_SESSION) {
-		if (unlikely(op->sym->session->driver_id !=
-				cryptodev_driver_id)) {
-			return NULL;
-		}
-
-		sess = (struct aesni_mb_session *)op->sym->session->_private;
-	} else  {
+		if (likely(op->sym->session != NULL))
+			sess = (struct aesni_mb_session *)
+					get_session_private_data(
+					op->sym->session,
+					cryptodev_driver_id);
+	} else {
 		void *_sess = NULL;
 
 		if (rte_mempool_get(qp->sess_mp, (void **)&_sess))
 			return NULL;
 
-		sess = (struct aesni_mb_session *)
-			((struct rte_cryptodev_sym_session *)_sess)->_private;
+		sess = (struct aesni_mb_session *) get_session_private_data(
+				_sess, cryptodev_driver_id);
 
 		if (unlikely(aesni_mb_set_session_parameters(qp->op_fns,
 				sess, op->sym->xform) != 0)) {
@@ -533,7 +532,9 @@ post_process_mb_job(struct aesni_mb_qp *qp, JOB_AES_HMAC *job)
 
 			if (job->hash_alg != NULL_HASH) {
 				sess = (struct aesni_mb_session *)
-						op->sym->session->_private;
+						get_session_private_data(
+						op->sym->session,
+						cryptodev_driver_id);
 
 				if (sess->auth.operation ==
 						RTE_CRYPTO_AUTH_OP_VERIFY)
diff --git a/drivers/crypto/armv8/rte_armv8_pmd.c b/drivers/crypto/armv8/rte_armv8_pmd.c
index 17dde0b..fdf56ef 100644
--- a/drivers/crypto/armv8/rte_armv8_pmd.c
+++ b/drivers/crypto/armv8/rte_armv8_pmd.c
@@ -548,20 +548,19 @@ get_session(struct armv8_crypto_qp *qp, struct rte_crypto_op *op)
 
 	if (op->sym->sess_type == RTE_CRYPTO_SYM_OP_WITH_SESSION) {
 		/* get existing session */
-		if (likely(op->sym->session != NULL &&
-				op->sym->session->driver_id ==
-				cryptodev_driver_id)) {
+		if (likely(op->sym->session != NULL))
 			sess = (struct armv8_crypto_session *)
-				op->sym->session->_private;
-		}
+					get_session_private_data(
+					op->sym->session,
+					cryptodev_driver_id);
 	} else {
 		/* provide internal session */
 		void *_sess = NULL;
 
 		if (!rte_mempool_get(qp->sess_mp, (void **)&_sess)) {
 			sess = (struct armv8_crypto_session *)
-				((struct rte_cryptodev_sym_session *)_sess)
-				->_private;
+					get_session_private_data(_sess,
+					cryptodev_driver_id);
 
 			if (unlikely(armv8_crypto_set_session_parameters(
 					sess, op->sym->xform) != 0)) {
diff --git a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
index 5bb9041..175a591 100644
--- a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
+++ b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
@@ -465,7 +465,9 @@ dpaa2_sec_enqueue_burst(void *qp, struct rte_crypto_op **ops,
 			/*Clear the unused FD fields before sending*/
 			memset(&fd_arr[loop], 0, sizeof(struct qbman_fd));
 			sess = (dpaa2_sec_session *)
-				(*ops)->sym->session->_private;
+					get_session_private_data(
+					(*ops)->sym->session,
+					cryptodev_driver_id);
 			mb_pool = (*ops)->sym->m_src->pool;
 			bpid = mempool_to_bpid(mb_pool);
 			ret = build_sec_fd(sess, *ops, &fd_arr[loop], bpid);
diff --git a/drivers/crypto/kasumi/rte_kasumi_pmd.c b/drivers/crypto/kasumi/rte_kasumi_pmd.c
index aa7eab5..a11596c 100644
--- a/drivers/crypto/kasumi/rte_kasumi_pmd.c
+++ b/drivers/crypto/kasumi/rte_kasumi_pmd.c
@@ -142,21 +142,22 @@ kasumi_set_session_parameters(struct kasumi_session *sess,
 static struct kasumi_session *
 kasumi_get_session(struct kasumi_qp *qp, struct rte_crypto_op *op)
 {
-	struct kasumi_session *sess;
+	struct kasumi_session *sess = NULL;
 
 	if (op->sym->sess_type == RTE_CRYPTO_SYM_OP_WITH_SESSION) {
-		if (unlikely(op->sym->session->driver_id !=
-				cryptodev_driver_id))
-			return NULL;
-
-		sess = (struct kasumi_session *)op->sym->session->_private;
-	} else  {
-		struct rte_cryptodev_session *c_sess = NULL;
+		if (likely(op->sym->session != NULL))
+			sess = (struct kasumi_session *)
+					get_session_private_data(
+					op->sym->session,
+					cryptodev_driver_id);
+	} else {
+		void *c_sess = NULL;
 
 		if (rte_mempool_get(qp->sess_mp, (void **)&c_sess))
 			return NULL;
 
-		sess = (struct kasumi_session *)c_sess->_private;
+		sess = (struct kasumi_session *)get_session_private_data(
+				c_sess, cryptodev_driver_id);
 
 		if (unlikely(kasumi_set_session_parameters(sess,
 				op->sym->xform) != 0))
@@ -300,7 +301,7 @@ process_kasumi_hash_op(struct rte_crypto_op **ops,
 			/* Trim area used for digest from mbuf. */
 			rte_pktmbuf_trim(ops[i]->sym->m_src,
 					ops[i]->sym->auth.digest.length);
-		} else  {
+		} else {
 			dst = ops[i]->sym->auth.digest.data;
 
 			sso_kasumi_f9_1_buffer_user(&session->pKeySched_hash,
diff --git a/drivers/crypto/null/null_crypto_pmd.c b/drivers/crypto/null/null_crypto_pmd.c
index 6788865..65ee16c 100644
--- a/drivers/crypto/null/null_crypto_pmd.c
+++ b/drivers/crypto/null/null_crypto_pmd.c
@@ -93,21 +93,22 @@ process_op(const struct null_crypto_qp *qp, struct rte_crypto_op *op,
 static struct null_crypto_session *
 get_session(struct null_crypto_qp *qp, struct rte_crypto_sym_op *op)
 {
-	struct null_crypto_session *sess;
+	struct null_crypto_session *sess = NULL;
 
 	if (op->sess_type == RTE_CRYPTO_SYM_OP_WITH_SESSION) {
-		if (unlikely(op->session == NULL || op->session->driver_id !=
-				cryptodev_driver_id))
-			return NULL;
-
-		sess = (struct null_crypto_session *)op->session->_private;
-	} else  {
-		struct rte_cryptodev_session *c_sess = NULL;
+		if (likely(op->session != NULL))
+			sess = (struct null_crypto_session *)
+					get_session_private_data(
+					op->session, cryptodev_driver_id);
+	} else {
+		struct rte_cryptodev_sym_session *c_sess = NULL;
 
 		if (rte_mempool_get(qp->sess_mp, (void **)&c_sess))
 			return NULL;
 
-		sess = (struct null_crypto_session *)c_sess->_private;
+		sess = (struct null_crypto_session *)
+				get_session_private_data(
+				c_sess, cryptodev_driver_id);
 
 		if (null_crypto_set_session_parameters(sess, op->xform)	!= 0)
 			return NULL;
diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c
index eb5dda3..c5b63dc 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -449,19 +449,19 @@ get_session(struct openssl_qp *qp, struct rte_crypto_op *op)
 
 	if (op->sym->sess_type == RTE_CRYPTO_SYM_OP_WITH_SESSION) {
 		/* get existing session */
-		if (likely(op->sym->session != NULL &&
-				op->sym->session->driver_id ==
-				cryptodev_driver_id))
+		if (likely(op->sym->session != NULL))
 			sess = (struct openssl_session *)
-				op->sym->session->_private;
-	} else  {
+					get_session_private_data(
+					op->sym->session,
+					cryptodev_driver_id);
+	} else {
 		/* provide internal session */
 		void *_sess = NULL;
 
 		if (!rte_mempool_get(qp->sess_mp, (void **)&_sess)) {
 			sess = (struct openssl_session *)
-				((struct rte_cryptodev_sym_session *)_sess)
-				->_private;
+					get_session_private_data(_sess,
+					cryptodev_driver_id);
 
 			if (unlikely(openssl_set_session_parameters(
 					sess, op->sym->xform) != 0)) {
diff --git a/drivers/crypto/qat/qat_crypto.c b/drivers/crypto/qat/qat_crypto.c
index 9dc3150..12b8c7f 100644
--- a/drivers/crypto/qat/qat_crypto.c
+++ b/drivers/crypto/qat/qat_crypto.c
@@ -60,6 +60,7 @@
 #include <rte_spinlock.h>
 #include <rte_hexdump.h>
 #include <rte_crypto_sym.h>
+#include <rte_cryptodev_pmd.h>
 #include <openssl/evp.h>
 
 #include "qat_logs.h"
@@ -808,7 +809,10 @@ qat_pmd_dequeue_op_burst(void *qp, struct rte_crypto_op **ops,
 			rx_op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
 		} else {
 			struct qat_session *sess = (struct qat_session *)
-						(rx_op->sym->session->_private);
+					get_session_private_data(
+					rx_op->sym->session,
+					cryptodev_qat_driver_id);
+
 			if (sess->bpi_ctx)
 				qat_bpicipher_postprocess(sess, rx_op);
 			rx_op->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
@@ -898,7 +902,6 @@ qat_write_hw_desc_entry(struct rte_crypto_op *op, uint8_t *out_msg,
 	uint64_t src_buf_start = 0, dst_buf_start = 0;
 	uint8_t do_sgl = 0;
 
-
 #ifdef RTE_LIBRTE_PMD_QAT_DEBUG_TX
 	if (unlikely(op->type != RTE_CRYPTO_OP_TYPE_SYMMETRIC)) {
 		PMD_DRV_LOG(ERR, "QAT PMD only supports symmetric crypto "
@@ -913,13 +916,14 @@ qat_write_hw_desc_entry(struct rte_crypto_op *op, uint8_t *out_msg,
 		return -EINVAL;
 	}
 
-	if (unlikely(op->sym->session->driver_id !=
-			cryptodev_qat_driver_id)) {
+	ctx = (struct qat_session *)get_session_private_data(
+			op->sym->session, cryptodev_qat_driver_id);
+
+	if (unlikely(ctx != NULL)) {
 		PMD_DRV_LOG(ERR, "Session was not created for this device");
 		return -EINVAL;
 	}
 
-	ctx = (struct qat_session *)op->sym->session->_private;
 	qat_req = (struct icp_qat_fw_la_bulk_req *)out_msg;
 	rte_mov128((uint8_t *)qat_req, (const uint8_t *)&(ctx->fw_req));
 	qat_req->comn_mid.opaque_data = (uint64_t)(uintptr_t)op;
@@ -1200,12 +1204,11 @@ static inline uint32_t adf_modulo(uint32_t data, uint32_t shift)
 void qat_crypto_sym_session_init(struct rte_mempool *mp, void *sym_sess)
 {
 	struct rte_cryptodev_sym_session *sess = sym_sess;
-	struct qat_session *s = (void *)sess->_private;
+	struct qat_session *s = (struct qat_session *)get_session_private_data(
+			sess, cryptodev_qat_driver_id);
 
 	PMD_INIT_FUNC_TRACE();
-	s->cd_paddr = rte_mempool_virt2phy(mp, sess) +
-		offsetof(struct qat_session, cd) +
-		offsetof(struct rte_cryptodev_sym_session, _private);
+	s->cd_paddr = rte_mempool_virt2phy(mp, sess);
 }
 
 int qat_dev_config(__rte_unused struct rte_cryptodev *dev,
diff --git a/drivers/crypto/scheduler/scheduler_failover.c b/drivers/crypto/scheduler/scheduler_failover.c
index 2471a5f..2989be1 100644
--- a/drivers/crypto/scheduler/scheduler_failover.c
+++ b/drivers/crypto/scheduler/scheduler_failover.c
@@ -31,6 +31,7 @@
  */
 
 #include <rte_cryptodev.h>
+#include <rte_cryptodev_pmd.h>
 #include <rte_malloc.h>
 
 #include "rte_cryptodev_scheduler_operations.h"
@@ -65,14 +66,18 @@ failover_slave_enqueue(struct scheduler_slave *slave, uint8_t slave_idx,
 		rte_prefetch0(ops[i + 6]->sym->session);
 		rte_prefetch0(ops[i + 7]->sym->session);
 
-		sess0 = (struct scheduler_session *)
-				ops[i]->sym->session->_private;
-		sess1 = (struct scheduler_session *)
-				ops[i+1]->sym->session->_private;
-		sess2 = (struct scheduler_session *)
-				ops[i+2]->sym->session->_private;
-		sess3 = (struct scheduler_session *)
-				ops[i+3]->sym->session->_private;
+		sess0 = (struct scheduler_session *)get_session_private_data(
+				ops[i]->sym->session,
+				cryptodev_scheduler_driver_id);
+		sess1 = (struct scheduler_session *)get_session_private_data(
+				ops[i+1]->sym->session,
+				cryptodev_scheduler_driver_id);
+		sess2 = (struct scheduler_session *)get_session_private_data(
+				ops[i+2]->sym->session,
+				cryptodev_scheduler_driver_id);
+		sess3 = (struct scheduler_session *)get_session_private_data(
+				ops[i+3]->sym->session,
+				cryptodev_scheduler_driver_id);
 
 		sessions[i] = ops[i]->sym->session;
 		sessions[i + 1] = ops[i + 1]->sym->session;
@@ -86,8 +91,9 @@ failover_slave_enqueue(struct scheduler_slave *slave, uint8_t slave_idx,
 	}
 
 	for (; i < nb_ops; i++) {
-		sess0 = (struct scheduler_session *)
-				ops[i]->sym->session->_private;
+		sess0 = (struct scheduler_session *)get_session_private_data(
+				ops[i]->sym->session,
+				cryptodev_scheduler_driver_id);
 		sessions[i] = ops[i]->sym->session;
 		ops[i]->sym->session = sess0->sessions[slave_idx];
 	}
diff --git a/drivers/crypto/scheduler/scheduler_pkt_size_distr.c b/drivers/crypto/scheduler/scheduler_pkt_size_distr.c
index 6b628df..2b61f41 100644
--- a/drivers/crypto/scheduler/scheduler_pkt_size_distr.c
+++ b/drivers/crypto/scheduler/scheduler_pkt_size_distr.c
@@ -31,6 +31,7 @@
  */
 
 #include <rte_cryptodev.h>
+#include <rte_cryptodev_pmd.h>
 #include <rte_malloc.h>
 
 #include "rte_cryptodev_scheduler_operations.h"
@@ -97,8 +98,9 @@ schedule_enqueue(void *qp, struct rte_crypto_op **ops, uint16_t nb_ops)
 		rte_prefetch0(ops[i + 7]->sym);
 		rte_prefetch0(ops[i + 7]->sym->session);
 
-		sess = (struct scheduler_session *)
-				ops[i]->sym->session->_private;
+		sess = (struct scheduler_session *)get_session_private_data(
+				ops[i]->sym->session,
+				cryptodev_scheduler_driver_id);
 		/* job_len is initialized as cipher data length, once
 		 * it is 0, equals to auth data length
 		 */
@@ -121,8 +123,10 @@ schedule_enqueue(void *qp, struct rte_crypto_op **ops, uint16_t nb_ops)
 		ops[i]->sym->session = sess->sessions[p_enq_op->slave_idx];
 		p_enq_op->pos++;
 
-		sess = (struct scheduler_session *)
-				ops[i+1]->sym->session->_private;
+		sess = (struct scheduler_session *)get_session_private_data(
+				ops[i+1]->sym->session,
+				cryptodev_scheduler_driver_id);
+
 		job_len = ops[i+1]->sym->cipher.data.length;
 		job_len += (ops[i+1]->sym->cipher.data.length == 0) *
 				ops[i+1]->sym->auth.data.length;
@@ -138,8 +142,10 @@ schedule_enqueue(void *qp, struct rte_crypto_op **ops, uint16_t nb_ops)
 		ops[i+1]->sym->session = sess->sessions[p_enq_op->slave_idx];
 		p_enq_op->pos++;
 
-		sess = (struct scheduler_session *)
-				ops[i+2]->sym->session->_private;
+		sess = (struct scheduler_session *)get_session_private_data(
+				ops[i+2]->sym->session,
+				cryptodev_scheduler_driver_id);
+
 		job_len = ops[i+2]->sym->cipher.data.length;
 		job_len += (ops[i+2]->sym->cipher.data.length == 0) *
 				ops[i+2]->sym->auth.data.length;
@@ -155,8 +161,9 @@ schedule_enqueue(void *qp, struct rte_crypto_op **ops, uint16_t nb_ops)
 		ops[i+2]->sym->session = sess->sessions[p_enq_op->slave_idx];
 		p_enq_op->pos++;
 
-		sess = (struct scheduler_session *)
-				ops[i+3]->sym->session->_private;
+		sess = (struct scheduler_session *)get_session_private_data(
+				ops[i+3]->sym->session,
+				cryptodev_scheduler_driver_id);
 
 		job_len = ops[i+3]->sym->cipher.data.length;
 		job_len += (ops[i+3]->sym->cipher.data.length == 0) *
@@ -175,8 +182,9 @@ schedule_enqueue(void *qp, struct rte_crypto_op **ops, uint16_t nb_ops)
 	}
 
 	for (; i < nb_ops; i++) {
-		sess = (struct scheduler_session *)
-				ops[i]->sym->session->_private;
+		sess = (struct scheduler_session *)get_session_private_data(
+				ops[i]->sym->session,
+				cryptodev_scheduler_driver_id);
 
 		job_len = ops[i]->sym->cipher.data.length;
 		job_len += (ops[i]->sym->cipher.data.length == 0) *
diff --git a/drivers/crypto/scheduler/scheduler_pmd_ops.c b/drivers/crypto/scheduler/scheduler_pmd_ops.c
index 1f91bce..8dd3edd 100644
--- a/drivers/crypto/scheduler/scheduler_pmd_ops.c
+++ b/drivers/crypto/scheduler/scheduler_pmd_ops.c
@@ -501,15 +501,13 @@ config_slave_sess(struct scheduler_ctx *sched_ctx,
 			if (create)
 				continue;
 			/* !create */
-			sess->sessions[i] = rte_cryptodev_sym_session_free(
-					slave->dev_id, sess->sessions[i]);
+			rte_cryptodev_sym_session_free(sess->sessions[i]);
 		} else {
 			if (!create)
 				continue;
 			/* create */
-			sess->sessions[i] =
-					rte_cryptodev_sym_session_create(
-							slave->dev_id, xform);
+			rte_cryptodev_sym_session_init(slave->dev_id,
+					sess->sessions[i], xform);
 			if (!sess->sessions[i]) {
 				config_slave_sess(sched_ctx, NULL, sess, 0);
 				return -1;
diff --git a/drivers/crypto/scheduler/scheduler_roundrobin.c b/drivers/crypto/scheduler/scheduler_roundrobin.c
index 0116276..08b4b4f 100644
--- a/drivers/crypto/scheduler/scheduler_roundrobin.c
+++ b/drivers/crypto/scheduler/scheduler_roundrobin.c
@@ -31,6 +31,7 @@
  */
 
 #include <rte_cryptodev.h>
+#include <rte_cryptodev_pmd.h>
 #include <rte_malloc.h>
 
 #include "rte_cryptodev_scheduler_operations.h"
@@ -62,14 +63,18 @@ schedule_enqueue(void *qp, struct rte_crypto_op **ops, uint16_t nb_ops)
 		rte_prefetch0(ops[i]->sym->session);
 
 	for (i = 0; (i < (nb_ops - 8)) && (nb_ops > 8); i += 4) {
-		sess0 = (struct scheduler_session *)
-				ops[i]->sym->session->_private;
-		sess1 = (struct scheduler_session *)
-				ops[i+1]->sym->session->_private;
-		sess2 = (struct scheduler_session *)
-				ops[i+2]->sym->session->_private;
-		sess3 = (struct scheduler_session *)
-				ops[i+3]->sym->session->_private;
+		sess0 = (struct scheduler_session *)get_session_private_data(
+				ops[i]->sym->session,
+				cryptodev_scheduler_driver_id);
+		sess1 = (struct scheduler_session *)get_session_private_data(
+				ops[i+1]->sym->session,
+				cryptodev_scheduler_driver_id);
+		sess2 = (struct scheduler_session *)get_session_private_data(
+				ops[i+2]->sym->session,
+				cryptodev_scheduler_driver_id);
+		sess3 = (struct scheduler_session *)get_session_private_data(
+				ops[i+3]->sym->session,
+				cryptodev_scheduler_driver_id);
 
 		sessions[i] = ops[i]->sym->session;
 		sessions[i + 1] = ops[i + 1]->sym->session;
@@ -88,8 +93,10 @@ schedule_enqueue(void *qp, struct rte_crypto_op **ops, uint16_t nb_ops)
 	}
 
 	for (; i < nb_ops; i++) {
-		sess0 = (struct scheduler_session *)
-				ops[i]->sym->session->_private;
+		sess0 = (struct scheduler_session *)get_session_private_data(
+				ops[i]->sym->session,
+				cryptodev_scheduler_driver_id);
+
 		sessions[i] = ops[i]->sym->session;
 		ops[i]->sym->session = sess0->sessions[slave_idx];
 	}
diff --git a/drivers/crypto/snow3g/rte_snow3g_pmd.c b/drivers/crypto/snow3g/rte_snow3g_pmd.c
index 7db6409..9f4bb04 100644
--- a/drivers/crypto/snow3g/rte_snow3g_pmd.c
+++ b/drivers/crypto/snow3g/rte_snow3g_pmd.c
@@ -142,21 +142,22 @@ snow3g_set_session_parameters(struct snow3g_session *sess,
 static struct snow3g_session *
 snow3g_get_session(struct snow3g_qp *qp, struct rte_crypto_op *op)
 {
-	struct snow3g_session *sess;
+	struct snow3g_session *sess = NULL;
 
 	if (op->sym->sess_type == RTE_CRYPTO_SYM_OP_WITH_SESSION) {
-		if (unlikely(op->sym->session->driver_id !=
-				cryptodev_driver_id))
-			return NULL;
-
-		sess = (struct snow3g_session *)op->sym->session->_private;
-	} else  {
-		struct rte_cryptodev_session *c_sess = NULL;
+		if (likely(op->sym->session != NULL))
+			sess = (struct snow3g_session *)
+					get_session_private_data(
+					op->sym->session,
+					cryptodev_driver_id);
+	} else {
+		void *c_sess = NULL;
 
 		if (rte_mempool_get(qp->sess_mp, (void **)&c_sess))
 			return NULL;
 
-		sess = (struct snow3g_session *)c_sess->_private;
+		sess = (struct snow3g_session *)get_session_private_data(
+				c_sess,	cryptodev_driver_id);
 
 		if (unlikely(snow3g_set_session_parameters(sess,
 				op->sym->xform) != 0))
@@ -289,7 +290,7 @@ process_snow3g_hash_op(struct rte_crypto_op **ops,
 			/* Trim area used for digest from mbuf. */
 			rte_pktmbuf_trim(ops[i]->sym->m_src,
 					ops[i]->sym->auth.digest.length);
-		} else  {
+		} else {
 			dst = ops[i]->sym->auth.digest.data;
 
 			sso_snow3g_f9_1_buffer(&session->pKeySched_hash,
diff --git a/drivers/crypto/zuc/rte_zuc_pmd.c b/drivers/crypto/zuc/rte_zuc_pmd.c
index 5d50bab..99a9e35 100644
--- a/drivers/crypto/zuc/rte_zuc_pmd.c
+++ b/drivers/crypto/zuc/rte_zuc_pmd.c
@@ -141,21 +141,21 @@ zuc_set_session_parameters(struct zuc_session *sess,
 static struct zuc_session *
 zuc_get_session(struct zuc_qp *qp, struct rte_crypto_op *op)
 {
-	struct zuc_session *sess;
+	struct zuc_session *sess = NULL;
 
 	if (op->sym->sess_type == RTE_CRYPTO_SYM_OP_WITH_SESSION) {
-		if (unlikely(op->sym->session->driver_id !=
-				cryptodev_driver_id))
-			return NULL;
-
-		sess = (struct zuc_session *)op->sym->session->_private;
-	} else  {
-		struct rte_cryptodev_session *c_sess = NULL;
+		if (likely(op->sym->session != NULL))
+			sess = (struct zuc_session *)get_session_private_data(
+					op->sym->session,
+					cryptodev_driver_id);
+	} else {
+		void *c_sess = NULL;
 
 		if (rte_mempool_get(qp->sess_mp, (void **)&c_sess))
 			return NULL;
 
-		sess = (struct zuc_session *)c_sess->_private;
+		sess = (struct zuc_session *)get_session_private_data(c_sess,
+				cryptodev_driver_id);
 
 		if (unlikely(zuc_set_session_parameters(sess,
 				op->sym->xform) != 0))
@@ -280,7 +280,7 @@ process_zuc_hash_op(struct rte_crypto_op **ops,
 			/* Trim area used for digest from mbuf. */
 			rte_pktmbuf_trim(ops[i]->sym->m_src,
 					ops[i]->sym->auth.digest.length);
-		} else  {
+		} else {
 			dst = (uint32_t *)ops[i]->sym->auth.digest.data;
 
 			sso_zuc_eia3_1_buffer(session->pKey_hash,
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index b8e1018..8f30114 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -934,10 +934,6 @@ rte_cryptodev_queue_pair_stop(uint8_t dev_id, uint16_t queue_pair_id)
 
 }
 
-static int
-rte_cryptodev_sym_session_pool_create(struct rte_cryptodev *dev,
-		unsigned nb_objs, unsigned obj_cache_size, int socket_id);
-
 int
 rte_cryptodev_configure(uint8_t dev_id, struct rte_cryptodev_config *config)
 {
@@ -968,14 +964,6 @@ rte_cryptodev_configure(uint8_t dev_id, struct rte_cryptodev_config *config)
 		return diag;
 	}
 
-	/* Setup Session mempool for device */
-	diag = rte_cryptodev_sym_session_pool_create(dev,
-			config->session_mp.nb_objs,
-			config->session_mp.cache_size,
-			config->socket_id);
-	if (diag != 0)
-		return diag;
-
 	return (*dev->dev_ops->dev_configure)(dev, config);
 }
 
@@ -1280,65 +1268,154 @@ rte_cryptodev_pmd_callback_process(struct rte_cryptodev *dev,
 	rte_spinlock_unlock(&rte_cryptodev_cb_lock);
 }
 
+static inline void
+set_session_private_data(struct rte_cryptodev_sym_session *sess,
+		uint8_t driver_id, void *private_data) {
+	sess->sess_private_data[driver_id] = private_data;
+}
 
-static void
-rte_cryptodev_sym_session_init(struct rte_mempool *mp,
-		void *opaque_arg,
-		void *_sess,
-		__rte_unused unsigned i)
-{
-	struct rte_cryptodev_sym_session *sess = _sess;
-	struct rte_cryptodev *dev = opaque_arg;
+int
+rte_cryptodev_sym_session_init(uint8_t dev_id,
+		struct rte_cryptodev_sym_session *sess,
+		struct rte_crypto_sym_xform *xforms) {
+
+	struct rte_cryptodev *dev;
+	void *sess_private_data;
+	int index;
 
-	memset(sess, 0, mp->elt_size);
+	dev = rte_cryptodev_pmd_get_dev(dev_id);
+
+	/* No more than 32 device types are expected */
+	index = dev->driver_id;
+
+	if ((sess->sess_mask & (1 << index)) == 0) {
+		sess->sess_mask |= (1 << index);
+
+		if (rte_mempool_get(sess->mp, &sess_private_data)) {
+			CDEV_LOG_ERR(
+				"Couldn't get object from session mempool");
+			return -1;
+		}
+
+		if (dev->dev_ops->session_initialize)
+			(*dev->dev_ops->session_initialize)(sess->mp, sess);
 
-	sess->dev_id = dev->data->dev_id;
-	sess->driver_id = dev->driver_id;
-	sess->mp = mp;
+		if (dev->dev_ops->session_configure(dev, xforms,
+				sess_private_data) == NULL) {
+			CDEV_LOG_ERR(
+				"dev_id %d failed to configure session details",
+				dev_id);
+
+			/* Return session to mempool */
+			rte_mempool_put(sess->mp, sess_private_data);
+			return -1;
+		}
+
+		set_session_private_data(sess, dev->driver_id,
+				sess_private_data);
+	}
 
-	if (dev->dev_ops->session_initialize)
-		(*dev->dev_ops->session_initialize)(mp, sess);
+	return 0;
 }
 
-static int
-rte_cryptodev_sym_session_pool_create(struct rte_cryptodev *dev,
-		unsigned nb_objs, unsigned obj_cache_size, int socket_id)
+struct rte_mempool *
+rte_cryptodev_sym_session_pool_create(uint32_t nb_objs,
+		uint8_t *device_ids,
+		uint8_t nb_device_ids,
+		uint32_t obj_cache_size,
+		uint8_t socket_id)
 {
+	unsigned int max_priv_sess_size =
+			sizeof(struct rte_cryptodev_sym_session);
+	unsigned int priv_sess_size;
+	unsigned int dev_id, i;
+	struct rte_cryptodev *dev;
+	struct rte_mempool *mempool;
+
 	char mp_name[RTE_CRYPTODEV_NAME_MAX_LEN];
-	unsigned priv_sess_size;
 
-	unsigned n = snprintf(mp_name, sizeof(mp_name), "cdev_%d_sess_mp",
-			dev->data->dev_id);
+	unsigned int n = snprintf(mp_name, sizeof(mp_name),
+			"rte_cryptodev_%d_sess_mp",
+			socket_id);
 	if (n > sizeof(mp_name)) {
 		CDEV_LOG_ERR("Unable to create unique name for session mempool");
-		return -ENOMEM;
+		return NULL;
 	}
 
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->session_get_size, -ENOTSUP);
-	priv_sess_size = (*dev->dev_ops->session_get_size)(dev);
-	if (priv_sess_size == 0) {
-		CDEV_LOG_ERR("%s returned and invalid private session size ",
+	if (device_ids == NULL) {
+
+		/* Walk through all devices */
+		for (dev_id = 0; dev_id < rte_cryptodev_globals->nb_devs;
+				dev_id++) {
+
+			if (!rte_cryptodev_pmd_is_valid_dev(dev_id))
+				continue;
+
+			dev = rte_cryptodev_pmd_get_dev(dev_id);
+
+			if (*dev->dev_ops->session_get_size == NULL)
+				continue;
+
+			priv_sess_size = (*dev->dev_ops->session_get_size)(dev);
+
+			if (priv_sess_size == 0) {
+				CDEV_LOG_ERR("%s returned and invalid private "
+						"session size ",
 						dev->data->name);
-		return -ENOMEM;
+				return NULL;
+			}
+
+			if (max_priv_sess_size < priv_sess_size)
+				max_priv_sess_size = priv_sess_size;
+
+		}
+	} else {
+		for (i = 0; i < nb_device_ids; i++) {
+
+			if (!rte_cryptodev_pmd_is_valid_dev(device_ids[i]))
+				continue;
+
+			dev = rte_cryptodev_pmd_get_dev(device_ids[i]);
+
+			if (*dev->dev_ops->session_get_size == NULL)
+				continue;
+
+			priv_sess_size = (*dev->dev_ops->session_get_size)(dev);
+
+			if (priv_sess_size == 0) {
+				CDEV_LOG_ERR("%s returned and invalid private "
+						"session size ",
+						dev->data->name);
+				return NULL;
+			}
+
+			if (max_priv_sess_size < priv_sess_size)
+				max_priv_sess_size = priv_sess_size;
+
+		}
 	}
 
-	unsigned elt_size = sizeof(struct rte_cryptodev_sym_session) +
-			priv_sess_size;
+	if (max_priv_sess_size == 0) {
+		CDEV_LOG_ERR("Cannot determinate maximal private data");
+		return NULL;
+	}
 
-	dev->data->session_pool = rte_mempool_lookup(mp_name);
-	if (dev->data->session_pool != NULL) {
-		if ((dev->data->session_pool->elt_size != elt_size) ||
-				(dev->data->session_pool->cache_size <
+	unsigned int elt_size = max_priv_sess_size;
+
+	mempool = rte_mempool_lookup(mp_name);
+	if (mempool != NULL) {
+		if ((mempool->elt_size != elt_size) ||
+				(mempool->cache_size <
 				obj_cache_size) ||
-				(dev->data->session_pool->size < nb_objs)) {
+				(mempool->size < nb_objs)) {
 
 			CDEV_LOG_ERR("%s mempool already exists with different"
 					" initialization parameters", mp_name);
-			dev->data->session_pool = NULL;
-			return -ENOMEM;
+			mempool = NULL;
+			return NULL;
 		}
 	} else {
-		dev->data->session_pool = rte_mempool_create(
+		mempool = rte_mempool_create(
 				mp_name, /* mempool name */
 				nb_objs, /* number of elements*/
 				elt_size, /* element size*/
@@ -1346,77 +1423,65 @@ rte_cryptodev_sym_session_pool_create(struct rte_cryptodev *dev,
 				0, /* private data size */
 				NULL, /* obj initialization constructor */
 				NULL, /* obj initialization constructor arg */
-				rte_cryptodev_sym_session_init,
+				NULL /* rte_crypto_sym_session_init */,
 				/**< obj constructor*/
-				dev, /* obj constructor arg */
+				NULL /* dev */, /* obj constructor arg */
 				socket_id, /* socket id */
 				0); /* flags */
 
-		if (dev->data->session_pool == NULL) {
+		if (mempool == NULL) {
 			CDEV_LOG_ERR("%s mempool allocation failed", mp_name);
-			return -ENOMEM;
+			return NULL;
 		}
 	}
 
 	CDEV_LOG_DEBUG("%s mempool created!", mp_name);
-	return 0;
+
+	return mempool;
 }
 
 struct rte_cryptodev_sym_session *
-rte_cryptodev_sym_session_create(uint8_t dev_id,
-		struct rte_crypto_sym_xform *xform)
-{
-	struct rte_cryptodev *dev;
+rte_cryptodev_sym_session_create(struct rte_mempool *mempool) {
 	struct rte_cryptodev_sym_session *sess;
 	void *_sess;
 
-	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
-		CDEV_LOG_ERR("Invalid dev_id=%d", dev_id);
-		return NULL;
-	}
-
-	dev = &rte_crypto_devices[dev_id];
-
 	/* Allocate a session structure from the session pool */
-	if (rte_mempool_get(dev->data->session_pool, &_sess)) {
+	if (rte_mempool_get(mempool, &_sess)) {
 		CDEV_LOG_ERR("Couldn't get object from session mempool");
 		return NULL;
 	}
 
 	sess = _sess;
-
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->session_configure, NULL);
-	if (dev->dev_ops->session_configure(dev, xform, sess->_private) ==
-			NULL) {
-		CDEV_LOG_ERR("dev_id %d failed to configure session details",
-				dev_id);
-
-		/* Return session to mempool */
-		rte_mempool_put(sess->mp, _sess);
-		return NULL;
-	}
+	sess->mp = mempool;
 
 	return sess;
 }
 
+void
+rte_cryptodev_sym_session_free(struct rte_cryptodev_sym_session *sess) {
+	if (sess != NULL)
+		sess->mp = NULL;
+}
+
 int
-rte_cryptodev_queue_pair_attach_sym_session(uint16_t qp_id,
+rte_cryptodev_queue_pair_attach_sym_session(uint8_t dev_id, uint16_t qp_id,
 		struct rte_cryptodev_sym_session *sess)
 {
 	struct rte_cryptodev *dev;
 
-	if (!rte_cryptodev_pmd_is_valid_dev(sess->dev_id)) {
-		CDEV_LOG_ERR("Invalid dev_id=%d", sess->dev_id);
+	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
+		CDEV_LOG_ERR("Invalid dev_id=%d", dev_id);
 		return -EINVAL;
 	}
 
-	dev = &rte_crypto_devices[sess->dev_id];
+	dev = &rte_crypto_devices[dev_id];
 
 	/* The API is optional, not returning error if driver do not suuport */
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->qp_attach_session, 0);
-	if (dev->dev_ops->qp_attach_session(dev, qp_id, sess->_private)) {
+	if (dev->dev_ops->qp_attach_session(dev, qp_id,
+			(void *)get_session_private_data(sess, dev_id))) {
 		CDEV_LOG_ERR("dev_id %d failed to attach qp: %d with session",
-				sess->dev_id, qp_id);
+				dev_id, qp_id);
 		return -EPERM;
 	}
 
@@ -1424,54 +1489,29 @@ rte_cryptodev_queue_pair_attach_sym_session(uint16_t qp_id,
 }
 
 int
-rte_cryptodev_queue_pair_detach_sym_session(uint16_t qp_id,
+rte_cryptodev_queue_pair_detach_sym_session(uint8_t dev_id, uint16_t qp_id,
 		struct rte_cryptodev_sym_session *sess)
 {
 	struct rte_cryptodev *dev;
 
-	if (!rte_cryptodev_pmd_is_valid_dev(sess->dev_id)) {
-		CDEV_LOG_ERR("Invalid dev_id=%d", sess->dev_id);
+	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
+		CDEV_LOG_ERR("Invalid dev_id=%d", dev_id);
 		return -EINVAL;
 	}
 
-	dev = &rte_crypto_devices[sess->dev_id];
+	dev = &rte_crypto_devices[dev_id];
 
 	/* The API is optional, not returning error if driver do not suuport */
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->qp_detach_session, 0);
-	if (dev->dev_ops->qp_detach_session(dev, qp_id, sess->_private)) {
+	if (dev->dev_ops->qp_detach_session(dev, qp_id,
+			(void *)get_session_private_data(sess, dev_id))) {
 		CDEV_LOG_ERR("dev_id %d failed to detach qp: %d from session",
-				sess->dev_id, qp_id);
+				dev_id, qp_id);
 		return -EPERM;
 	}
 
 	return 0;
 }
-struct rte_cryptodev_sym_session *
-rte_cryptodev_sym_session_free(uint8_t dev_id,
-		struct rte_cryptodev_sym_session *sess)
-{
-	struct rte_cryptodev *dev;
-
-	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
-		CDEV_LOG_ERR("Invalid dev_id=%d", dev_id);
-		return sess;
-	}
-
-	dev = &rte_crypto_devices[dev_id];
-
-	/* Check the session belongs to this device type */
-	if (sess->driver_id != dev->driver_id)
-		return sess;
-
-	/* Let device implementation clear session material */
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->session_clear, sess);
-	dev->dev_ops->session_clear(dev, (void *)sess->_private);
-
-	/* Return session to mempool */
-	rte_mempool_put(sess->mp, (void *)sess);
-
-	return NULL;
-}
 
 /** Initialise rte_crypto_op mempool element */
 static void
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index 27a3a07..dfec7ea 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -827,67 +827,61 @@ rte_cryptodev_enqueue_burst(uint8_t dev_id, uint16_t qp_id,
 }
 
 
+/** Cryptodev maximal number of session private data */
+#define RTE_CRYPTODEV_SESS_PRIVATE_NUM 32
+
 /** Cryptodev symmetric crypto session */
 struct rte_cryptodev_sym_session {
-	RTE_STD_C11
-	struct {
-		uint8_t dev_id;
-		/**< Device Id */
-		uint8_t driver_id;
-		/** Crypto driver identifier session created on */
-		struct rte_mempool *mp;
-		/**< Mempool session allocated from */
-	} __rte_aligned(8);
-	/**< Public symmetric session details */
-
-	__extension__ char _private[0];
-	/**< Private session material */
+	struct rte_mempool *mp;
+	/**< Mempool session allocated from */
+	uint32_t sess_mask;
+	/**< Mask containing which private data is set */
+	void *sess_private_data[RTE_CRYPTODEV_SESS_PRIVATE_NUM];
+	/**< Device type specific session private data */
 };
 
-
-/**
- * Initialise a session for symmetric cryptographic operations.
- *
- * This function is used by the client to initialize immutable
- * parameters of symmetric cryptographic operation.
- * To perform the operation the rte_cryptodev_enqueue_burst function is
- * used.  Each mbuf should contain a reference to the session
- * pointer returned from this function contained within it's crypto_op if a
- * session-based operation is being provisioned. Memory to contain the session
- * information is allocated from within mempool managed by the cryptodev.
- *
- * The rte_cryptodev_session_free must be called to free allocated
- * memory when the session is no longer required.
+/**<
+ * Frees symmetric crypto session and all related device type specific
+ * private data objects associated with session
  *
- * @param	dev_id		The device identifier.
- * @param	xform		Crypto transform chain.
+ * @param   sess     Session where the private data will be attached to
+ */
+void
+rte_cryptodev_sym_session_free(struct rte_cryptodev_sym_session *sess);
 
+/**<
+ * Fill out private data for the device id, based on its device type
+ *
+ * @param   dev_id   ID of device that we want the session to be used on
+ * @param   sess     Session where the private data will be attached to
+ * @param   xforms   Symmetric crypto transform operations to apply on flow
+ *                   processed with this session
  *
  * @return
- *  Pointer to the created session or NULL
+ *  - On success, zero.
+ *  - On failure, a negative value.
  */
-extern struct rte_cryptodev_sym_session *
-rte_cryptodev_sym_session_create(uint8_t dev_id,
-		struct rte_crypto_sym_xform *xform);
+int
+rte_cryptodev_sym_session_init(uint8_t dev_id,
+		struct rte_cryptodev_sym_session *sess,
+		struct rte_crypto_sym_xform *xforms);
 
-/**
- * Free the memory associated with a previously allocated session.
- *
- * @param	dev_id		The device identifier.
- * @param	session		Session pointer previously allocated by
- *				*rte_cryptodev_sym_session_create*.
+/**<
+ * Create symmetric crypto session (generic with no private data)
  *
+ * @param   mempool    Symmetric session mempool to allocate session
+ *                     objects from
  * @return
- *   NULL on successful freeing of session.
- *   Session pointer on failure to free session.
+ *  - On success return pointer to sym-session
+ *  - On failure returns NULL
  */
-extern struct rte_cryptodev_sym_session *
-rte_cryptodev_sym_session_free(uint8_t dev_id,
-		struct rte_cryptodev_sym_session *session);
+struct rte_cryptodev_sym_session *
+rte_cryptodev_sym_session_create(struct rte_mempool *mempool);
 
 /**
  * Attach queue pair with sym session.
  *
+ * @param	dev_id		The identifier of the device.
  * @param	qp_id		Queue pair to which session will be attached.
  * @param	session		Session pointer previously allocated by
  *				*rte_cryptodev_sym_session_create*.
@@ -897,12 +891,13 @@ rte_cryptodev_sym_session_free(uint8_t dev_id,
  *  - On failure, a negative value.
  */
 int
-rte_cryptodev_queue_pair_attach_sym_session(uint16_t qp_id,
+rte_cryptodev_queue_pair_attach_sym_session(uint8_t dev_id, uint16_t qp_id,
 		struct rte_cryptodev_sym_session *session);
 
 /**
  * Detach queue pair with sym session.
  *
+ * @param	dev_id		The identifier of the device.
  * @param	qp_id		Queue pair to which session is attached.
  * @param	session		Session pointer previously allocated by
  *				*rte_cryptodev_sym_session_create*.
@@ -912,10 +907,30 @@ rte_cryptodev_queue_pair_attach_sym_session(uint16_t qp_id,
  *  - On failure, a negative value.
  */
 int
-rte_cryptodev_queue_pair_detach_sym_session(uint16_t qp_id,
+rte_cryptodev_queue_pair_detach_sym_session(uint8_t dev_id, uint16_t qp_id,
 		struct rte_cryptodev_sym_session *session);
 
 /**
+ * Create session mempool.
+ *
+ * @param	nb_objs		Number of sessions objects in mempool.
+ * @param	device_ids	The table of the devices identifiers.
+ * @param	nb_device_ids	Number of the devices identifiers.
+ * @param	obj_cache_size	l-core object cache size.
+ * @param	socket_id	Socket to allocate memory on
+ *
+ * @return
+ *  - The created mempool pointer on success.
+ *  - NULL on failure.
+ */
+struct rte_mempool *
+rte_cryptodev_sym_session_pool_create(uint32_t nb_objs,
+		uint8_t *device_ids,
+		uint8_t nb_device_ids,
+		uint32_t obj_cache_size,
+		uint8_t socket_id);
+
+/**
  * Provide driver identifier.
  *
  * @param name
@@ -954,7 +969,6 @@ static void init_ ##driver_id(void)\
 	driver_id = rte_cryptodev_allocate_driver_id(RTE_STR(name));\
 }
 
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h b/lib/librte_cryptodev/rte_cryptodev_pmd.h
index fb3972b..79c128f 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
@@ -518,6 +518,21 @@ int rte_cryptodev_pci_remove(struct rte_pci_device *pci_dev);
 int
 rte_cryptodev_pmd_create_dev_name(char *name, const char *dev_name_prefix);
 
+/**
+ * Provide session private data.
+ *
+ * @param	sess		The cryptodev session
+ * @param	driver_id	The driver identifier
+ *
+ * @return
+ *  void
+ */
+static inline void *
+get_session_private_data(struct rte_cryptodev_sym_session *sess,
+		uint8_t driver_id) {
+	return sess->sess_private_data[driver_id];
+}
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index 91f2e56..ec4d792 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -81,5 +81,7 @@ DPDK_17.08 {
 	rte_cryptodev_device_count_by_driver;
 	rte_cryptodev_driver_id_get;
 	rte_cryptodev_driver_name_get;
+	rte_cryptodev_sym_session_init;
+	rte_cryptodev_sym_session_pool_create;
 
 } DPDK_17.05;
