From: Lee Daly Date: Wed, 9 May 2018 16:14:29 +0000 (+0100) Subject: compress/isal: add private xform related ops X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=c720cd2b35faedbed17df151b3cb1fcf48e1a0bf;p=dpdk.git compress/isal: add private xform related ops This patch creates, configures and frees the private xform, taking the applications xform and using it to populate the PMDs own private xform with the information which will be required for the compress/decompress functions. This information includes the level, algorithm, type of huffman code, type of checksum etc. Signed-off-by: Lee Daly Reviewed-by: Pablo de Lara --- diff --git a/drivers/compress/isal/isal_compress_pmd.c b/drivers/compress/isal/isal_compress_pmd.c index 5cc9409132..1224dd0d3c 100644 --- a/drivers/compress/isal/isal_compress_pmd.c +++ b/drivers/compress/isal/isal_compress_pmd.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright(c) 2018 Intel Corporation */ +#include #include #include @@ -9,8 +10,183 @@ #include "isal_compress_pmd_private.h" +#define RTE_COMP_ISAL_WINDOW_SIZE 15 +#define RTE_COMP_ISAL_LEVEL_ZERO 0 /* ISA-L Level 0 used for fixed Huffman */ +#define RTE_COMP_ISAL_LEVEL_ONE 1 +#define RTE_COMP_ISAL_LEVEL_TWO 2 +#define RTE_COMP_ISAL_LEVEL_THREE 3 /* Optimised for AVX512 & AVX2 only */ + int isal_logtype_driver; +/* Verify and set private xform parameters */ +int +isal_comp_set_priv_xform_parameters(struct isal_priv_xform *priv_xform, + const struct rte_comp_xform *xform) +{ + if (xform == NULL) + return -EINVAL; + + /* Set compression private xform variables */ + if (xform->type == RTE_COMP_COMPRESS) { + /* Set private xform type - COMPRESS/DECOMPRESS */ + priv_xform->type = RTE_COMP_COMPRESS; + + /* Set private xform algorithm */ + if (xform->compress.algo != RTE_COMP_ALGO_DEFLATE) { + if (xform->compress.algo == RTE_COMP_ALGO_NULL) { + ISAL_PMD_LOG(ERR, "By-pass not supported\n"); + return -ENOTSUP; + } + ISAL_PMD_LOG(ERR, "Algorithm not supported\n"); + return -ENOTSUP; + } + priv_xform->compress.algo = RTE_COMP_ALGO_DEFLATE; + + /* Set private xform checksum - raw deflate by default */ + if (xform->compress.chksum != RTE_COMP_CHECKSUM_NONE) { + ISAL_PMD_LOG(ERR, "Checksum not supported\n"); + return -ENOTSUP; + } + + /* Set private xform window size, 32K supported */ + if (xform->compress.window_size == RTE_COMP_ISAL_WINDOW_SIZE) + priv_xform->compress.window_size = + RTE_COMP_ISAL_WINDOW_SIZE; + else { + ISAL_PMD_LOG(ERR, "Window size not supported\n"); + return -ENOTSUP; + } + + /* Set private xform huffman type */ + switch (xform->compress.deflate.huffman) { + case(RTE_COMP_HUFFMAN_DEFAULT): + priv_xform->compress.deflate.huffman = + RTE_COMP_HUFFMAN_DEFAULT; + break; + case(RTE_COMP_HUFFMAN_FIXED): + priv_xform->compress.deflate.huffman = + RTE_COMP_HUFFMAN_FIXED; + break; + case(RTE_COMP_HUFFMAN_DYNAMIC): + priv_xform->compress.deflate.huffman = + RTE_COMP_HUFFMAN_DYNAMIC; + break; + default: + ISAL_PMD_LOG(ERR, "Huffman code not supported\n"); + return -ENOTSUP; + } + + /* Set private xform level. + * Checking compliance with compressdev API, -1 <= level => 9 + */ + if (xform->compress.level < RTE_COMP_LEVEL_PMD_DEFAULT || + xform->compress.level > RTE_COMP_LEVEL_MAX) { + ISAL_PMD_LOG(ERR, "Compression level out of range\n"); + return -EINVAL; + } + /* Check for Compressdev API level 0, No compression + * not supported in ISA-L + */ + else if (xform->compress.level == RTE_COMP_LEVEL_NONE) { + ISAL_PMD_LOG(ERR, "No Compression not supported\n"); + return -ENOTSUP; + } + /* If using fixed huffman code, level must be 0 */ + else if (priv_xform->compress.deflate.huffman == + RTE_COMP_HUFFMAN_FIXED) { + ISAL_PMD_LOG(DEBUG, "ISA-L level 0 used due to a" + " fixed huffman code\n"); + priv_xform->compress.level = RTE_COMP_ISAL_LEVEL_ZERO; + priv_xform->level_buffer_size = + ISAL_DEF_LVL0_DEFAULT; + } else { + /* Mapping API levels to ISA-L levels 1,2 & 3 */ + switch (xform->compress.level) { + case RTE_COMP_LEVEL_PMD_DEFAULT: + /* Default is 1 if not using fixed huffman */ + priv_xform->compress.level = + RTE_COMP_ISAL_LEVEL_ONE; + priv_xform->level_buffer_size = + ISAL_DEF_LVL1_DEFAULT; + break; + case RTE_COMP_LEVEL_MIN: + priv_xform->compress.level = + RTE_COMP_ISAL_LEVEL_ONE; + priv_xform->level_buffer_size = + ISAL_DEF_LVL1_DEFAULT; + break; + case RTE_COMP_ISAL_LEVEL_TWO: + priv_xform->compress.level = + RTE_COMP_ISAL_LEVEL_TWO; + priv_xform->level_buffer_size = + ISAL_DEF_LVL2_DEFAULT; + break; + /* Level 3 or higher requested */ + default: + /* Check for AVX512, to use ISA-L level 3 */ + if (rte_cpu_get_flag_enabled( + RTE_CPUFLAG_AVX512F)) { + priv_xform->compress.level = + RTE_COMP_ISAL_LEVEL_THREE; + priv_xform->level_buffer_size = + ISAL_DEF_LVL3_DEFAULT; + } + /* Check for AVX2, to use ISA-L level 3 */ + else if (rte_cpu_get_flag_enabled( + RTE_CPUFLAG_AVX2)) { + priv_xform->compress.level = + RTE_COMP_ISAL_LEVEL_THREE; + priv_xform->level_buffer_size = + ISAL_DEF_LVL3_DEFAULT; + } else { + ISAL_PMD_LOG(DEBUG, "Requested ISA-L level" + " 3 or above; Level 3 optimized" + " for AVX512 & AVX2 only." + " level changed to 2.\n"); + priv_xform->compress.level = + RTE_COMP_ISAL_LEVEL_TWO; + priv_xform->level_buffer_size = + ISAL_DEF_LVL2_DEFAULT; + } + } + } + } + + /* Set decompression private xform variables */ + else if (xform->type == RTE_COMP_DECOMPRESS) { + + /* Set private xform type - COMPRESS/DECOMPRESS */ + priv_xform->type = RTE_COMP_DECOMPRESS; + + /* Set private xform algorithm */ + if (xform->decompress.algo != RTE_COMP_ALGO_DEFLATE) { + if (xform->decompress.algo == RTE_COMP_ALGO_NULL) { + ISAL_PMD_LOG(ERR, "By pass not supported\n"); + return -ENOTSUP; + } + ISAL_PMD_LOG(ERR, "Algorithm not supported\n"); + return -ENOTSUP; + } + priv_xform->decompress.algo = RTE_COMP_ALGO_DEFLATE; + + /* Set private xform checksum - raw deflate by default */ + if (xform->compress.chksum != RTE_COMP_CHECKSUM_NONE) { + ISAL_PMD_LOG(ERR, "Checksum not supported\n"); + return -ENOTSUP; + } + + /* Set private xform window size, 32K supported */ + if (xform->decompress.window_size == RTE_COMP_ISAL_WINDOW_SIZE) + priv_xform->decompress.window_size = + RTE_COMP_ISAL_WINDOW_SIZE; + else { + ISAL_PMD_LOG(ERR, "Window size not supported\n"); + return -ENOTSUP; + } + } + return 0; +} + /* Create ISA-L compression device */ static int compdev_isal_create(const char *name, struct rte_vdev_device *vdev, diff --git a/drivers/compress/isal/isal_compress_pmd_ops.c b/drivers/compress/isal/isal_compress_pmd_ops.c index 2f828c5f7a..9c89df0dad 100644 --- a/drivers/compress/isal/isal_compress_pmd_ops.c +++ b/drivers/compress/isal/isal_compress_pmd_ops.c @@ -13,10 +13,59 @@ static const struct rte_compressdev_capabilities isal_pmd_capabilities[] = { /** Configure device */ static int -isal_comp_pmd_config(struct rte_compressdev *dev __rte_unused, - struct rte_compressdev_config *config __rte_unused) +isal_comp_pmd_config(struct rte_compressdev *dev, + struct rte_compressdev_config *config) { - return 0; + int ret = 0; + unsigned int n; + char mp_name[RTE_COMPRESSDEV_NAME_MAX_LEN]; + unsigned int elt_size = sizeof(struct isal_priv_xform); + struct isal_comp_private *internals = dev->data->dev_private; + + n = snprintf(mp_name, sizeof(mp_name), "compdev_%d_xform_mp", + dev->data->dev_id); + if (n > sizeof(mp_name)) { + ISAL_PMD_LOG(ERR, + "Unable to create unique name for xform mempool"); + return -ENOMEM; + } + + internals->priv_xform_mp = rte_mempool_lookup(mp_name); + + if (internals->priv_xform_mp != NULL) { + if (((internals->priv_xform_mp)->elt_size != elt_size) || + ((internals->priv_xform_mp)->size < + config->max_nb_priv_xforms)) { + + ISAL_PMD_LOG(ERR, "%s mempool already exists with different" + " initialization parameters", mp_name); + internals->priv_xform_mp = NULL; + return -ENOMEM; + } + } else { /* First time configuration */ + internals->priv_xform_mp = rte_mempool_create( + mp_name, /* mempool name */ + /* number of elements*/ + config->max_nb_priv_xforms, + elt_size, /* element size*/ + 0, /* Cache size*/ + 0, /* private data size */ + NULL, /* obj initialization constructor */ + NULL, /* obj initialization constructor arg */ + NULL, /**< obj constructor*/ + NULL, /* obj constructor arg */ + config->socket_id, /* socket id */ + 0); /* flags */ + } + + if (internals->priv_xform_mp == NULL) { + ISAL_PMD_LOG(ERR, "%s mempool allocation failed", mp_name); + return -ENOMEM; + } + + dev->data->dev_private = internals; + + return ret; } /** Start device */ @@ -57,6 +106,50 @@ isal_comp_pmd_info_get(struct rte_compressdev *dev __rte_unused, } } +/** Set private xform data*/ +static int +isal_comp_pmd_priv_xform_create(struct rte_compressdev *dev, + const struct rte_comp_xform *xform, void **priv_xform) +{ + int ret; + struct isal_comp_private *internals = dev->data->dev_private; + + if (xform == NULL) { + ISAL_PMD_LOG(ERR, "Invalid Xform struct"); + return -EINVAL; + } + + if (rte_mempool_get(internals->priv_xform_mp, priv_xform)) { + ISAL_PMD_LOG(ERR, + "Couldn't get object from private xform mempool"); + return -ENOMEM; + } + + ret = isal_comp_set_priv_xform_parameters(*priv_xform, xform); + if (ret != 0) { + ISAL_PMD_LOG(ERR, "Failed to configure private xform parameters"); + + /* Return private xform to mempool */ + rte_mempool_put(internals->priv_xform_mp, priv_xform); + return ret; + } + return 0; +} + +/** Clear memory of the private xform so it doesn't leave key material behind */ +static int +isal_comp_pmd_priv_xform_free(struct rte_compressdev *dev, void *priv_xform) +{ + struct isal_comp_private *internals = dev->data->dev_private; + + /* Zero out the whole structure */ + if (priv_xform) { + memset(priv_xform, 0, sizeof(struct isal_priv_xform)); + rte_mempool_put(internals->priv_xform_mp, priv_xform); + } + return 0; +} + struct rte_compressdev_ops isal_pmd_ops = { .dev_configure = isal_comp_pmd_config, .dev_start = isal_comp_pmd_start, @@ -71,8 +164,8 @@ struct rte_compressdev_ops isal_pmd_ops = { .queue_pair_setup = NULL, .queue_pair_release = NULL, - .private_xform_create = NULL, - .private_xform_free = NULL, + .private_xform_create = isal_comp_pmd_priv_xform_create, + .private_xform_free = isal_comp_pmd_priv_xform_free, }; struct rte_compressdev_ops *isal_compress_pmd_ops = &isal_pmd_ops; diff --git a/drivers/compress/isal/isal_compress_pmd_private.h b/drivers/compress/isal/isal_compress_pmd_private.h index efbe68b992..7e3b8402c9 100644 --- a/drivers/compress/isal/isal_compress_pmd_private.h +++ b/drivers/compress/isal/isal_compress_pmd_private.h @@ -30,6 +30,21 @@ struct isal_comp_qp { uint16_t num_free_elements; } __rte_cache_aligned; +/** ISA-L private xform structure */ +struct isal_priv_xform { + enum rte_comp_xform_type type; + union { + struct rte_comp_compress_xform compress; + struct rte_comp_decompress_xform decompress; + }; + uint32_t level_buffer_size; +} __rte_cache_aligned; + +/** Set and validate NULL comp private xform parameters */ +extern int +isal_comp_set_priv_xform_parameters(struct isal_priv_xform *priv_xform, + const struct rte_comp_xform *xform); + /** device specific operations function pointer structure */ extern struct rte_compressdev_ops *isal_compress_pmd_ops;