DPDK patches and discussions
 help / color / mirror / Atom feed
From: Konstantin Ananyev <konstantin.ananyev@intel.com>
To: dev@dpdk.org, techboard@dpdk.org
Cc: roy.fan.zhang@intel.com, declan.doherty@intel.com,
	akhil.goyal@nxp.com,
	Konstantin Ananyev <konstantin.ananyev@intel.com>
Subject: [dpdk-dev] [RFC 4/4] cryptodev: introduce rte_crypto_cpu_sym_session API
Date: Tue,  5 Nov 2019 18:41:22 +0000	[thread overview]
Message-ID: <20191105184122.15172-5-konstantin.ananyev@intel.com> (raw)
In-Reply-To: <20191105184122.15172-1-konstantin.ananyev@intel.com>

This patch extends rte_cryptodev API with CPU-CRYPTO mode.
This is done by reusing of existing rte_crypto_sym_xform data structures
and introducing new opaque rte_crypto_cpu_sym_session data structure
and related control and data path API.

Crypto PMD that wants to support that functionality would need to:
1. claim RTE_CRYPTODEV_FF_SYM_CPU_CRYPTO capability supported.
2. implement new functions for rte_cryptodev_ops:
	. cpu_sym_session_size,
	. cpu_sym_session_init,
3. implement new functions for rte_crypto_cpu_sym_session:
	.clear,
	.process
	
For data-path processing consumer would have to maintain:
	struct rte_crypto_cpu_sym_session *sess

Below is a summary of reasons why I think adding new API is a preferable
over reusing existing  rte_crypto_sym_session API:

1. Inside rte_crypto_sym_session there is an array of pointers
to PMD private session structures (indexed by driver id).
Some of them might be initialized, others not.
So even now, user has to maintain a list of dev_ids that
can be used with this session.
With patch #3 in-place it becomes even more complex -
user will have to maintain two lists of dev_ids:
  - one for async crypto-devices that can be used with that session
  - another one for sync crypto-devices that can be used with that session
In majority of examples within dpdk.org tree, we usually don't bother
and use just one device per session.
But for intermediate libraries (librte_ipsec, etc.) that
have to be as generic as possible and can't make such assumptions
such design choice is not very convenient.

From other hand, cpu-crypto is SW based synchronous operation
and it doesn't need any device/queue data during crypto-processing,
all necessary information is stored inside session itself.
The only stage where we really need dev_id - during session init().
So it seems natural to exclude dev_id from data and majority of control
path completely.

2. Current  rte_cryptodev_sym_session_init() expects PMD session data
to be allocated via provided mempool. That seems not very flexible.
Preferred way would be to allow user can allocate memory for cpu-crypto
session whenever he likes.
    
3. Would allow PMD writer to expose a separate process() functions for
different session types and hopefully save extra function call and
reduce data-dependencies for fast-path comparing to previous patch.  

Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
 lib/librte_cryptodev/rte_crypto_sym.h    |  8 +++
 lib/librte_cryptodev/rte_cryptodev.c     | 46 +++++++++++++++
 lib/librte_cryptodev/rte_cryptodev.h     | 71 ++++++++++++++++++++++++
 lib/librte_cryptodev/rte_cryptodev_pmd.h | 49 ++++++++++++++++
 4 files changed, 174 insertions(+)

diff --git a/lib/librte_cryptodev/rte_crypto_sym.h b/lib/librte_cryptodev/rte_crypto_sym.h
index d8d9e9514..45f3840bb 100644
--- a/lib/librte_cryptodev/rte_crypto_sym.h
+++ b/lib/librte_cryptodev/rte_crypto_sym.h
@@ -166,6 +166,10 @@ struct rte_crypto_cipher_xform {
 	 *  - Both keys must have the same size.
 	 **/
 
+	/**
+	 * CPU-CRYPTO specific data, used only by rte_crypto_cpu_sym_session
+	 * initialisation pass, otherwise ignored.
+	 */
 	struct {
 		/**
 		 * offset for cipher to start within user provided data buffer.
@@ -415,6 +419,10 @@ struct rte_crypto_aead_xform {
 		uint16_t length;	/**< key length in bytes */
 	} __attribute__((__packed__)) key;
 
+	/**
+	 * CPU-CRYPTO specific data, used only by rte_crypto_cpu_sym_session
+	 * initialisation pass, otherwise ignored.
+	 */
 	struct {
 		/**
 		 * offset for cipher to start within user provided data buffer.
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 89aa2ed3e..8109665c2 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -1616,6 +1616,52 @@ rte_cryptodev_sym_session_get_user_data(
 	return (void *)(sess->sess_data + sess->nb_drivers);
 }
 
+__rte_experimental
+int
+rte_crypto_cpu_sym_session_size(uint8_t dev_id,
+	const struct rte_crypto_sym_xform *xforms)
+{
+	struct rte_cryptodev *dev;
+
+	dev = rte_cryptodev_pmd_get_dev(dev_id);
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->cpu_sym_session_size, -ENOTSUP);
+
+	return dev->dev_ops->cpu_sym_session_size(dev, xforms);
+}
+
+__rte_experimental
+int
+rte_crypto_cpu_sym_session_init(uint8_t dev_id,
+	struct rte_crypto_cpu_sym_session *sess,
+	const struct rte_crypto_sym_xform *xforms)
+{
+	struct rte_cryptodev *dev;
+
+	dev = rte_cryptodev_pmd_get_dev(dev_id);
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->cpu_sym_session_init, -ENOTSUP);
+
+	return dev->dev_ops->cpu_sym_session_init(dev, sess, xforms);
+}
+
+__rte_experimental
+void
+rte_crypto_cpu_sym_session_clear(struct rte_crypto_cpu_sym_session *sess)
+{
+	if (sess != NULL && sess->ops.clear != NULL)
+		return sess->ops.clear(sess);
+}
+
+__rte_experimental
+int
+rte_crypto_cpu_sym_session_process(struct rte_crypto_cpu_sym_session *sess,
+	struct rte_crypto_sym_vec *vec, int32_t status[], uint32_t num)
+{
+	if (sess == NULL || sess->ops.process == NULL)
+		return -EINVAL;
+
+	return sess->ops.process(sess, vec, status, num);
+}
+
 /** Initialise rte_crypto_op mempool element */
 static void
 rte_crypto_op_init(struct rte_mempool *mempool,
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index c6ffa3b35..3333bbe09 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -450,6 +450,8 @@ rte_cryptodev_asym_get_xform_enum(enum rte_crypto_asym_xform_type *xform_enum,
 /**< Support encrypted-digest operations where digest is appended to data */
 #define RTE_CRYPTODEV_FF_ASYM_SESSIONLESS		(1ULL << 20)
 /**< Support asymmetric session-less operations */
+#define RTE_CRYPTODEV_FF_SYM_CPU_CRYPTO		(1ULL << 21)
+/**< Support symmeteric cpu-crypto processing */
 
 
 /**
@@ -1274,6 +1276,75 @@ void *
 rte_cryptodev_sym_session_get_user_data(
 					struct rte_cryptodev_sym_session *sess);
 
+/**
+ * opaque session structure for symmetric CPU-CRYPTO operations.
+ */
+struct rte_crypto_cpu_sym_session;
+
+/**
+ * Calculate required session size in bytes for given set of xforms.
+ * if xforms == NULL, then return the max possible session size,
+ * that would fit session for any supported by the device algorithm.
+ * if CPU-CRYPTO is not supported at all, or requeted in xform
+ * algorithm is not supported, then return -ENOTSUP.
+ * @param   dev_id   ID of device that we want the session to be used on
+ * @param   xforms   Symmetric crypto transform operations to apply on flow
+ *                   processed with this session
+ * @return
+ *  - On success, positive value for required session size in bytes.
+ *  - negative errno value otherwise.
+ */
+__rte_experimental
+int
+rte_crypto_cpu_sym_session_size(uint8_t dev_id,
+		const struct rte_crypto_sym_xform *xforms);
+
+/**
+ * Initialize symmetric CPU-CRYPTO session.
+ * It is caller responsibility to allocate enough space for it.
+ * See rte_crypto_cpu_sym_session_size above.
+ * @param   dev_id   ID of device that we want the session to be used on
+ * @param   sess     Pointer to the raw session buffer
+ * @param   xforms   Symmetric crypto transform operations to apply on flow
+ *                   processed with this session
+ * @return
+ *  - On success, zero.
+ *  - negative errno value otherwise.
+ */
+__rte_experimental
+int
+rte_crypto_cpu_sym_session_init(uint8_t dev_id,
+		struct rte_crypto_cpu_sym_session *sess,
+		const struct rte_crypto_sym_xform *xforms);
+
+/**
+ * De-initialize symmetric CPU-CRYPTO session.
+ * It is caller responsibility to free  the session pointer afterwards.
+ */
+__rte_experimental
+void
+rte_crypto_cpu_sym_session_clear(struct rte_crypto_cpu_sym_session *sess);
+
+/**
+ * Perform actual crypto processing (encrypt/digest or auth/decrypt)
+ * on user provided data.
+ *
+ * @param	sess	cpu-crypto session structure
+ * @param	vec	Array of vectors for input data
+ * @param	status	Array of status values (one per vec)
+ * 			(RTE_CRYPTO_OP_STATUS_* values)
+ * @param	num	Number of elems in vec and status arrays.
+ *
+ * @return
+ *  - Returns negative errno value on error, or non-negative number
+ *    of successfully processed input vectors.
+ *
++*/
+__rte_experimental
+int
+rte_crypto_cpu_sym_session_process(struct rte_crypto_cpu_sym_session *sess,
+	struct rte_crypto_sym_vec *vec, int32_t status[], uint32_t num);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h b/lib/librte_cryptodev/rte_cryptodev_pmd.h
index fba14f2fa..629461315 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
@@ -309,6 +309,38 @@ typedef void (*cryptodev_sym_free_session_t)(struct rte_cryptodev *dev,
 typedef void (*cryptodev_asym_free_session_t)(struct rte_cryptodev *dev,
 		struct rte_cryptodev_asym_session *sess);
 
+/**
+ * Calculate required session size in bytes for given set of xforms.
+ * if xforms == NULL, then return the max possible session size,
+ * that would fit session for any supported by the device algorithm.
+ * if CPU-CRYPTO is not supported at all, or requeted in xform
+ * algorithm is not supported, then return -ENOTSUP.
+ * @param	dev	Crypto device pointer
+ * @param	xforms	Symmetric crypto transform operations to apply on flow
+ *                      processed with this session
+ * @return
+ *  - On success, positive value for required session size in bytes.
+ *  - negative errno value otherwise.
+ */
+typedef int (*cryptodev_cpu_sym_session_size_t)(struct rte_cryptodev *dev,
+		const struct rte_crypto_sym_xform *xforms);
+
+/**
+ * Initialize symmetric CPU-CRYPTO session.
+ * It is caller responsibility to allocate enough space for it.
+ * See rte_crypto_cpu_sym_session_size above.
+ * @param	dev	Crypto device pointer
+ * @param	sess	Pointer to the raw session buffer
+ * @param	xforms	Symmetric crypto transform operations to apply on flow
+ *                       processed with this session
+ * @return
+ *  - On success, zero.
+ *  - negative errno value otherwise.
+ */
+typedef int (*cryptodev_cpu_sym_session_init_t)(struct rte_cryptodev *dev,
+		struct rte_crypto_cpu_sym_session *sess,
+		const struct rte_crypto_sym_xform *xforms);
+
 /** Crypto device operations function pointer table */
 struct rte_cryptodev_ops {
 	cryptodev_configure_t dev_configure;	/**< Configure device. */
@@ -342,6 +374,10 @@ struct rte_cryptodev_ops {
 	/**< Clear a Crypto sessions private data. */
 	cryptodev_asym_free_session_t asym_session_clear;
 	/**< Clear a Crypto sessions private data. */
+	cryptodev_cpu_sym_session_size_t cpu_sym_session_size;
+	/**< Calculate required cpu-crypto session size. */
+	cryptodev_cpu_sym_session_init_t cpu_sym_session_init;
+	/**< Initialise cpu-crypto session. */
 };
 
 
@@ -506,6 +542,19 @@ set_asym_session_private_data(struct rte_cryptodev_asym_session *sess,
 	sess->sess_private_data[driver_id] = private_data;
 }
 
+
+struct rte_crypto_cpu_sym_session_ops {
+	void (*clear)(struct rte_crypto_cpu_sym_session *);
+	int (*process)(struct rte_crypto_cpu_sym_session *,
+		struct rte_crypto_sym_vec *, int32_t [], uint32_t);
+};
+
+struct rte_crypto_cpu_sym_session {
+	struct rte_crypto_cpu_sym_session_ops ops;
+	/** session private data starts here. */
+	void *sess_data[0] __rte_cache_min_aligned;
+};
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.17.1


  parent reply	other threads:[~2019-11-05 18:42 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-05 18:41 [dpdk-dev] [RFC 0/4] cpu-crypto API choices Konstantin Ananyev
2019-11-05 18:41 ` [dpdk-dev] [RFC 1/4] cpu-crypto: Introduce basic data structures Konstantin Ananyev
2019-11-05 18:41 ` [dpdk-dev] [RFC 2/4] security: introduce cpu-crypto API Konstantin Ananyev
2019-11-05 18:41 ` [dpdk-dev] [RFC 3/4] cryptodev: " Konstantin Ananyev
2019-11-05 21:41   ` Akhil Goyal
2019-11-06 14:49     ` Ananyev, Konstantin
2019-11-05 18:41 ` Konstantin Ananyev [this message]
2019-11-06  4:54 ` [dpdk-dev] [dpdk-techboard] [RFC 0/4] cpu-crypto API choices Honnappa Nagarahalli
2019-11-06  9:35   ` Thomas Monjalon
2019-11-06  9:48     ` Thomas Monjalon
2019-11-06 10:14       ` Ananyev, Konstantin
2019-11-06 11:33         ` Ananyev, Konstantin
2019-11-06 12:18           ` Thomas Monjalon
2019-11-06 12:22             ` Hemant Agrawal
2019-11-06 15:19             ` Ananyev, Konstantin
2019-11-14  5:46 ` [dpdk-dev] " Jerin Jacob
2019-11-18 11:57   ` Ananyev, Konstantin
2019-11-20 14:27     ` Jerin Jacob

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191105184122.15172-5-konstantin.ananyev@intel.com \
    --to=konstantin.ananyev@intel.com \
    --cc=akhil.goyal@nxp.com \
    --cc=declan.doherty@intel.com \
    --cc=dev@dpdk.org \
    --cc=roy.fan.zhang@intel.com \
    --cc=techboard@dpdk.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).