From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id A6379A00C5; Thu, 7 May 2020 12:59:29 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 91A531DC2A; Thu, 7 May 2020 12:59:29 +0200 (CEST) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by dpdk.org (Postfix) with ESMTP id ED6251DC04 for ; Thu, 7 May 2020 12:59:26 +0200 (CEST) IronPort-SDR: WwHY03hoOot6GciSDq0P80sUB+iVACKmLa1uzCpT0R4mrXD0TTZyeKfduA1OfBymWPaTliiS9g jcwBSk+yeOYw== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 May 2020 03:59:25 -0700 IronPort-SDR: O1hWKERlDV5c0+7TNkqmQlowulv3x6DezaDq1eqFKZphPs0kIeZZ0x5BQ4HGEsBGr3foOMMNjG EBWfX/+hErAA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.73,363,1583222400"; d="scan'208";a="278562456" Received: from akusztax-mobl.ger.corp.intel.com ([10.104.121.88]) by orsmga002.jf.intel.com with ESMTP; 07 May 2020 03:59:23 -0700 From: Arek Kusztal To: dev@dpdk.org Cc: fiona.trahe@intel.com, ray.kinsella@intel.com, akhil.goyal@nxp.com, bruce.richardson@intel.com, Arek Kusztal Date: Thu, 7 May 2020 12:57:03 +0200 Message-Id: <20200507105703.11804-2-arkadiuszx.kusztal@intel.com> X-Mailer: git-send-email 2.19.1.windows.1 In-Reply-To: <20200507105703.11804-1-arkadiuszx.kusztal@intel.com> References: <20200507105703.11804-1-arkadiuszx.kusztal@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [dpdk-dev] [PATCH v5 2/2] cryptodev: version cryptodev info get function 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 adds versioned function rte_cryptodev_info_get() to prevent some issues with ABI policy. Node v21 works in same way as before, returning driver capabilities directly to the API caller. These capabilities may include new elements not part of the v20 ABI. Node v20 function maintains compatibility with v20 ABI releases by stripping out elements not supported in v20 ABI. Because rte_cryptodev_info_get is called by other API functions, rte_cryptodev_sym_capability_get function is versioned the same way. Signed-off-by: Arek Kusztal --- v2: - changed version numbers of symbols to 20.0.2 v3: - added v2/v3 informations - changed version numbers of symbols to 21 v4: - fixed clang build by movind binding default symbol - implemented mailing list comments - added abidiff tool suppression entries v5: - fixed meson build devtools/libabigail.abignore | 8 ++ lib/librte_cryptodev/meson.build | 1 + lib/librte_cryptodev/rte_cryptodev.c | 147 ++++++++++++++++++++++++- lib/librte_cryptodev/rte_cryptodev.h | 34 +++++- lib/librte_cryptodev/rte_cryptodev_version.map | 7 ++ 5 files changed, 191 insertions(+), 6 deletions(-) diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore index 1911890..e479e20 100644 --- a/devtools/libabigail.abignore +++ b/devtools/libabigail.abignore @@ -24,3 +24,11 @@ type_kind = enum name = rte_eth_event_type changed_enumerators = RTE_ETH_EVENT_MAX +; Ignore Cryptodev AEAD xform enum and AEAD xform strings change +; due to addition of Chacha20-Poly1305 +[suppress_type] + type_kind = enum + name = rte_crypto_aead_algorithm + changed_enumerators = RTE_CRYPTO_AEAD_LIST_END +[suppress_variable] + name = rte_crypto_aead_algorithm_strings diff --git a/lib/librte_cryptodev/meson.build b/lib/librte_cryptodev/meson.build index c4c6b3b..df11440 100644 --- a/lib/librte_cryptodev/meson.build +++ b/lib/librte_cryptodev/meson.build @@ -1,6 +1,7 @@ # SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2017-2019 Intel Corporation +use_function_versioning = true sources = files('rte_cryptodev.c', 'rte_cryptodev_pmd.c', 'cryptodev_trace_points.c') headers = files('rte_cryptodev.h', 'rte_cryptodev_pmd.h', diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c index a499c47..e4a7b71 100644 --- a/lib/librte_cryptodev/rte_cryptodev.c +++ b/lib/librte_cryptodev/rte_cryptodev.c @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include "rte_crypto.h" #include "rte_cryptodev.h" @@ -57,6 +59,14 @@ static struct rte_cryptodev_global cryptodev_globals = { /* spinlock for crypto device callbacks */ static rte_spinlock_t rte_cryptodev_cb_lock = RTE_SPINLOCK_INITIALIZER; +static const struct rte_cryptodev_capabilities + cryptodev_undefined_capabilities[] = { + RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST() +}; + +static struct rte_cryptodev_capabilities + *capability_copy[RTE_CRYPTO_MAX_DEVS]; +static uint8_t is_capability_checked[RTE_CRYPTO_MAX_DEVS]; /** * The user application callback description. @@ -281,15 +291,15 @@ rte_crypto_auth_operation_strings[] = { [RTE_CRYPTO_AUTH_OP_GENERATE] = "generate" }; -const struct rte_cryptodev_symmetric_capability * -rte_cryptodev_sym_capability_get(uint8_t dev_id, +const struct rte_cryptodev_symmetric_capability __vsym * +rte_cryptodev_sym_capability_get_v20(uint8_t dev_id, const struct rte_cryptodev_sym_capability_idx *idx) { const struct rte_cryptodev_capabilities *capability; struct rte_cryptodev_info dev_info; int i = 0; - rte_cryptodev_info_get(dev_id, &dev_info); + rte_cryptodev_info_get_v20(dev_id, &dev_info); while ((capability = &dev_info.capabilities[i++])->op != RTE_CRYPTO_OP_TYPE_UNDEFINED) { @@ -313,8 +323,47 @@ rte_cryptodev_sym_capability_get(uint8_t dev_id, } return NULL; +} +VERSION_SYMBOL(rte_cryptodev_sym_capability_get, _v20, 20.0); + +const struct rte_cryptodev_symmetric_capability __vsym * +rte_cryptodev_sym_capability_get_v21(uint8_t dev_id, + const struct rte_cryptodev_sym_capability_idx *idx) +{ + const struct rte_cryptodev_capabilities *capability; + struct rte_cryptodev_info dev_info; + int i = 0; + + rte_cryptodev_info_get(dev_id, &dev_info); + + while ((capability = &dev_info.capabilities[i++])->op != + RTE_CRYPTO_OP_TYPE_UNDEFINED) { + if (capability->op != RTE_CRYPTO_OP_TYPE_SYMMETRIC) + continue; + if (capability->sym.xform_type != idx->type) + continue; + + if (idx->type == RTE_CRYPTO_SYM_XFORM_AUTH && + capability->sym.auth.algo == idx->algo.auth) + return &capability->sym; + + if (idx->type == RTE_CRYPTO_SYM_XFORM_CIPHER && + capability->sym.cipher.algo == idx->algo.cipher) + return &capability->sym; + + if (idx->type == RTE_CRYPTO_SYM_XFORM_AEAD && + capability->sym.aead.algo == idx->algo.aead) + return &capability->sym; + } + + return NULL; } +MAP_STATIC_SYMBOL(const struct rte_cryptodev_symmetric_capability * + rte_cryptodev_sym_capability_get(uint8_t dev_id, + const struct rte_cryptodev_sym_capability_idx *idx), + rte_cryptodev_sym_capability_get_v21); +BIND_DEFAULT_SYMBOL(rte_cryptodev_sym_capability_get, _v21, 21); static int param_range_check(uint16_t size, const struct rte_crypto_param_range *range) @@ -1016,6 +1065,12 @@ rte_cryptodev_close(uint8_t dev_id) retval = (*dev->dev_ops->dev_close)(dev); rte_cryptodev_trace_close(dev_id, retval); + if (capability_copy[dev_id]) { + free(capability_copy[dev_id]); + capability_copy[dev_id] = NULL; + } + is_capability_checked[dev_id] = 0; + if (retval < 0) return retval; @@ -1129,9 +1184,61 @@ rte_cryptodev_stats_reset(uint8_t dev_id) (*dev->dev_ops->stats_reset)(dev); } +static void +get_v20_capabilities(uint8_t dev_id, struct rte_cryptodev_info *dev_info) +{ + const struct rte_cryptodev_capabilities *capability; + uint8_t found_invalid_capa = 0; + uint8_t counter = 0; + + for (capability = dev_info->capabilities; + capability->op != RTE_CRYPTO_OP_TYPE_UNDEFINED; + ++capability, ++counter) { + if (capability->op == RTE_CRYPTO_OP_TYPE_SYMMETRIC && + capability->sym.xform_type == + RTE_CRYPTO_SYM_XFORM_AEAD + && capability->sym.aead.algo >= + RTE_CRYPTO_AEAD_CHACHA20_POLY1305) { + found_invalid_capa = 1; + counter--; + } + } + is_capability_checked[dev_id] = 1; + if (!found_invalid_capa) + return; + capability_copy[dev_id] = malloc(counter * + sizeof(struct rte_cryptodev_capabilities)); + if (capability_copy[dev_id] == NULL) { + /* + * error case - no memory to store the trimmed + * list, so have to return an empty list + */ + dev_info->capabilities = + cryptodev_undefined_capabilities; + is_capability_checked[dev_id] = 0; + } else { + counter = 0; + for (capability = dev_info->capabilities; + capability->op != + RTE_CRYPTO_OP_TYPE_UNDEFINED; + capability++) { + if (!(capability->op == + RTE_CRYPTO_OP_TYPE_SYMMETRIC + && capability->sym.xform_type == + RTE_CRYPTO_SYM_XFORM_AEAD + && capability->sym.aead.algo >= + RTE_CRYPTO_AEAD_CHACHA20_POLY1305)) { + capability_copy[dev_id][counter++] = + *capability; + } + } + dev_info->capabilities = + capability_copy[dev_id]; + } +} -void -rte_cryptodev_info_get(uint8_t dev_id, struct rte_cryptodev_info *dev_info) +void __vsym +rte_cryptodev_info_get_v20(uint8_t dev_id, struct rte_cryptodev_info *dev_info) { struct rte_cryptodev *dev; @@ -1147,10 +1254,40 @@ rte_cryptodev_info_get(uint8_t dev_id, struct rte_cryptodev_info *dev_info) RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get); (*dev->dev_ops->dev_infos_get)(dev, dev_info); + if (capability_copy[dev_id] == NULL) { + if (!is_capability_checked[dev_id]) + get_v20_capabilities(dev_id, dev_info); + } else + dev_info->capabilities = capability_copy[dev_id]; + dev_info->driver_name = dev->device->driver->name; dev_info->device = dev->device; } +VERSION_SYMBOL(rte_cryptodev_info_get, _v20, 20.0); +void __vsym +rte_cryptodev_info_get_v21(uint8_t dev_id, struct rte_cryptodev_info *dev_info) +{ + struct rte_cryptodev *dev; + + if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) { + CDEV_LOG_ERR("Invalid dev_id=%d", dev_id); + return; + } + + dev = &rte_crypto_devices[dev_id]; + + memset(dev_info, 0, sizeof(struct rte_cryptodev_info)); + + RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get); + (*dev->dev_ops->dev_infos_get)(dev, dev_info); + + dev_info->driver_name = dev->device->driver->name; + dev_info->device = dev->device; +} +MAP_STATIC_SYMBOL(void rte_cryptodev_info_get(uint8_t dev_id, + struct rte_cryptodev_info *dev_info), rte_cryptodev_info_get_v21); +BIND_DEFAULT_SYMBOL(rte_cryptodev_info_get, _v21, 21); int rte_cryptodev_callback_register(uint8_t dev_id, diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h index 3dbb5ce..d8e8e46 100644 --- a/lib/librte_cryptodev/rte_cryptodev.h +++ b/lib/librte_cryptodev/rte_cryptodev.h @@ -219,6 +219,14 @@ struct rte_cryptodev_asym_capability_idx { * - Return NULL if the capability not exist. */ const struct rte_cryptodev_symmetric_capability * +rte_cryptodev_sym_capability_get_v20(uint8_t dev_id, + const struct rte_cryptodev_sym_capability_idx *idx); + +const struct rte_cryptodev_symmetric_capability * +rte_cryptodev_sym_capability_get_v21(uint8_t dev_id, + const struct rte_cryptodev_sym_capability_idx *idx); + +const struct rte_cryptodev_symmetric_capability * rte_cryptodev_sym_capability_get(uint8_t dev_id, const struct rte_cryptodev_sym_capability_idx *idx); @@ -762,9 +770,33 @@ rte_cryptodev_stats_reset(uint8_t dev_id); * the last valid element has it's op field set to * RTE_CRYPTO_OP_TYPE_UNDEFINED. */ -extern void + +void rte_cryptodev_info_get(uint8_t dev_id, struct rte_cryptodev_info *dev_info); +/* An extra element RTE_CRYPTO_AEAD_CHACHA20_POLY1305 is added + * to enum rte_crypto_aead_algorithm, also changing the value of + * RTE_CRYPTO_AEAD_LIST_END. To maintain ABI compatibility with applications + * which linked against earlier versions, preventing them, for example, from + * picking up the new value and using it to index into an array sized too small + * for it, it is necessary to have two versions of rte_cryptodev_info_get() + * The latest version just returns directly the capabilities retrieved from + * the device. The compatible version inspects the capabilities retrieved + * from the device, but only returns them directly if the new value + * is not included. If the new value is included, it allocates space + * for a copy of the device capabilities, trims the new value from this + * and returns this copy. It only needs to do this once per device. + * For the corner case of a corner case when the alloc may fail, + * an empty capability list is returned, as there is no mechanism to return + * an error and adding such a mechanism would itself be an ABI breakage. + * The compatible version can be removed after the next major ABI release. + */ + +void +rte_cryptodev_info_get_v20(uint8_t dev_id, struct rte_cryptodev_info *dev_info); + +void +rte_cryptodev_info_get_v21(uint8_t dev_id, struct rte_cryptodev_info *dev_info); /** * Register a callback function for specific device id. diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map index 87f5cd1..07a2d2f 100644 --- a/lib/librte_cryptodev/rte_cryptodev_version.map +++ b/lib/librte_cryptodev/rte_cryptodev_version.map @@ -58,6 +58,13 @@ DPDK_20.0 { local: *; }; +DPDK_21 { + global: + rte_cryptodev_info_get; + rte_cryptodev_sym_capability_get; +} DPDK_20.0; + + EXPERIMENTAL { global: -- 2.1.0