From patchwork Tue Nov 5 18:41:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Ananyev, Konstantin" X-Patchwork-Id: 62493 X-Patchwork-Delegate: gakhil@marvell.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 2EBCAA04A2; Tue, 5 Nov 2019 19:42:28 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 409591BF85; Tue, 5 Nov 2019 19:42:21 +0100 (CET) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id E57FC1BF83; Tue, 5 Nov 2019 19:42:19 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 05 Nov 2019 10:42:19 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.68,271,1569308400"; d="scan'208";a="403454651" Received: from sivswdev08.ir.intel.com ([10.237.217.47]) by fmsmga006.fm.intel.com with ESMTP; 05 Nov 2019 10:42:15 -0800 From: Konstantin Ananyev To: dev@dpdk.org, techboard@dpdk.org Cc: roy.fan.zhang@intel.com, declan.doherty@intel.com, akhil.goyal@nxp.com, Konstantin Ananyev Date: Tue, 5 Nov 2019 18:41:22 +0000 Message-Id: <20191105184122.15172-5-konstantin.ananyev@intel.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20191105184122.15172-1-konstantin.ananyev@intel.com> References: <20191105184122.15172-1-konstantin.ananyev@intel.com> Subject: [dpdk-dev] [RFC 4/4] cryptodev: introduce rte_crypto_cpu_sym_session API X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 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 --- 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