LCOV - code coverage report
Current view: top level - spdk/module/accel/dpdk_compressdev - accel_dpdk_compressdev.c (source / functions) Hit Total Coverage
Test: Combined Lines: 289 421 68.6 %
Date: 2024-11-20 17:01:08 Functions: 22 22 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 128 262 48.9 %

           Branch data     Line data    Source code
       1                 :            : /*   SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *   Copyright (C) 2018 Intel Corporation.
       3                 :            :  *   All rights reserved.
       4                 :            :  *   Copyright (c) 2021-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
       5                 :            :  */
       6                 :            : 
       7                 :            : #include "accel_dpdk_compressdev.h"
       8                 :            : #include "spdk/accel_module.h"
       9                 :            : 
      10                 :            : #include "spdk/stdinc.h"
      11                 :            : #include "spdk/rpc.h"
      12                 :            : #include "spdk/env.h"
      13                 :            : #include "spdk/endian.h"
      14                 :            : #include "spdk/string.h"
      15                 :            : #include "spdk/thread.h"
      16                 :            : #include "spdk/util.h"
      17                 :            : #include "spdk/likely.h"
      18                 :            : 
      19                 :            : #include "spdk/log.h"
      20                 :            : 
      21                 :            : #include <rte_config.h>
      22                 :            : #include <rte_bus_vdev.h>
      23                 :            : #include <rte_compressdev.h>
      24                 :            : #include <rte_comp.h>
      25                 :            : #include <rte_mbuf_dyn.h>
      26                 :            : 
      27                 :            : /* Used to store IO context in mbuf */
      28                 :            : static const struct rte_mbuf_dynfield rte_mbuf_dynfield_io_context = {
      29                 :            :         .name = "context_accel_comp",
      30                 :            :         .size = sizeof(uint64_t),
      31                 :            :         .align = __alignof__(uint64_t),
      32                 :            :         .flags = 0,
      33                 :            : };
      34                 :            : static int g_mbuf_offset;
      35                 :            : static enum compress_pmd g_opts;
      36                 :            : static bool g_compressdev_enable = false;
      37                 :            : static bool g_compressdev_initialized = false;
      38                 :            : 
      39                 :            : #define NUM_MAX_XFORMS          2
      40                 :            : #define NUM_MAX_INFLIGHT_OPS    128
      41                 :            : #define DEFAULT_WINDOW_SIZE     15
      42                 :            : #define MBUF_SPLIT              (1UL << DEFAULT_WINDOW_SIZE)
      43                 :            : #define QAT_PMD                 "compress_qat"
      44                 :            : #define MLX5_PMD                "mlx5_pci"
      45                 :            : #define UADK_PMD                "compress_uadk"
      46                 :            : #define NUM_MBUFS               65536
      47                 :            : #define POOL_CACHE_SIZE         256
      48                 :            : 
      49                 :            : /* Global list of available compression devices. */
      50                 :            : struct compress_dev {
      51                 :            :         struct rte_compressdev_info     cdev_info;      /* includes device friendly name */
      52                 :            :         uint8_t                         cdev_id;        /* identifier for the device */
      53                 :            :         void                            *comp_xform;    /* shared private xform for comp on this PMD */
      54                 :            :         void                            *decomp_xform;  /* shared private xform for decomp on this PMD */
      55                 :            :         bool                            sgl_in;
      56                 :            :         bool                            sgl_out;
      57                 :            :         TAILQ_ENTRY(compress_dev)       link;
      58                 :            : };
      59                 :            : static TAILQ_HEAD(, compress_dev) g_compress_devs = TAILQ_HEAD_INITIALIZER(g_compress_devs);
      60                 :            : 
      61                 :            : #define MAX_NUM_QP 48
      62                 :            : /* Global list and lock for unique device/queue pair combos */
      63                 :            : struct comp_device_qp {
      64                 :            :         struct compress_dev             *device;        /* ptr to compression device */
      65                 :            :         uint8_t                         qp;             /* queue pair for this node */
      66                 :            :         struct compress_io_channel      *chan;
      67                 :            :         TAILQ_ENTRY(comp_device_qp)     link;
      68                 :            : };
      69                 :            : static TAILQ_HEAD(, comp_device_qp) g_comp_device_qp = TAILQ_HEAD_INITIALIZER(g_comp_device_qp);
      70                 :            : static pthread_mutex_t g_comp_device_qp_lock = PTHREAD_MUTEX_INITIALIZER;
      71                 :            : 
      72                 :            : struct compress_io_channel {
      73                 :            :         char                            *drv_name;      /* name of the compression device driver */
      74                 :            :         struct comp_device_qp           *device_qp;
      75                 :            :         struct spdk_poller              *poller;
      76                 :            :         struct rte_mbuf                 **src_mbufs;
      77                 :            :         struct rte_mbuf                 **dst_mbufs;
      78                 :            :         STAILQ_HEAD(, spdk_accel_task)  queued_tasks;
      79                 :            : };
      80                 :            : 
      81                 :            : /* Shared mempools between all devices on this system */
      82                 :            : static struct rte_mempool *g_mbuf_mp = NULL;            /* mbuf mempool */
      83                 :            : static struct rte_mempool *g_comp_op_mp = NULL;         /* comp operations, must be rte* mempool */
      84                 :            : static struct rte_mbuf_ext_shared_info g_shinfo = {};   /* used by DPDK mbuf macros */
      85                 :            : static bool g_qat_available = false;
      86                 :            : static bool g_mlx5_pci_available = false;
      87                 :            : static bool g_uadk_available = false;
      88                 :            : 
      89                 :            : /* Create shared (between all ops per PMD) compress xforms. */
      90                 :            : static struct rte_comp_xform g_comp_xform = {
      91                 :            :         .type = RTE_COMP_COMPRESS,
      92                 :            :         .compress = {
      93                 :            :                 .algo = RTE_COMP_ALGO_DEFLATE,
      94                 :            :                 .deflate.huffman = RTE_COMP_HUFFMAN_DEFAULT,
      95                 :            :                 .level = RTE_COMP_LEVEL_MAX,
      96                 :            :                 .window_size = DEFAULT_WINDOW_SIZE,
      97                 :            :                 .chksum = RTE_COMP_CHECKSUM_NONE,
      98                 :            :                 .hash_algo = RTE_COMP_HASH_ALGO_NONE
      99                 :            :         }
     100                 :            : };
     101                 :            : /* Create shared (between all ops per PMD) decompress xforms. */
     102                 :            : static struct rte_comp_xform g_decomp_xform = {
     103                 :            :         .type = RTE_COMP_DECOMPRESS,
     104                 :            :         .decompress = {
     105                 :            :                 .algo = RTE_COMP_ALGO_DEFLATE,
     106                 :            :                 .chksum = RTE_COMP_CHECKSUM_NONE,
     107                 :            :                 .window_size = DEFAULT_WINDOW_SIZE,
     108                 :            :                 .hash_algo = RTE_COMP_HASH_ALGO_NONE
     109                 :            :         }
     110                 :            : };
     111                 :            : 
     112                 :            : /* Dummy function used by DPDK to free ext attached buffers
     113                 :            :  * to mbufs, we free them ourselves but this callback has to
     114                 :            :  * be here.
     115                 :            :  */
     116                 :            : static void
     117                 :         51 : shinfo_free_cb(void *arg1, void *arg2)
     118                 :            : {
     119                 :         51 : }
     120                 :            : 
     121                 :            : /* Called by accel_init_compress_drivers() to init each discovered compression device */
     122                 :            : static int
     123                 :        864 : create_compress_dev(uint8_t index)
     124                 :            : {
     125                 :            :         struct compress_dev *device;
     126                 :            :         uint16_t q_pairs;
     127                 :            :         uint8_t cdev_id;
     128                 :            :         int rc, i;
     129                 :            :         struct comp_device_qp *dev_qp;
     130                 :            :         struct comp_device_qp *tmp_qp;
     131                 :            : 
     132                 :        864 :         device = calloc(1, sizeof(struct compress_dev));
     133         [ -  + ]:        864 :         if (!device) {
     134                 :          0 :                 return -ENOMEM;
     135                 :            :         }
     136                 :            : 
     137                 :            :         /* Get details about this device. */
     138                 :        864 :         rte_compressdev_info_get(index, &device->cdev_info);
     139                 :            : 
     140                 :        864 :         cdev_id = device->cdev_id = index;
     141                 :            : 
     142                 :            :         /* Zero means no limit so choose number of lcores. */
     143         [ -  + ]:        864 :         if (device->cdev_info.max_nb_queue_pairs == 0) {
     144                 :          0 :                 q_pairs = MAX_NUM_QP;
     145                 :            :         } else {
     146                 :        864 :                 q_pairs = spdk_min(device->cdev_info.max_nb_queue_pairs, MAX_NUM_QP);
     147                 :            :         }
     148                 :            : 
     149                 :            :         /* Configure the compression device. */
     150                 :        864 :         struct rte_compressdev_config config = {
     151                 :        864 :                 .socket_id = rte_socket_id(),
     152                 :            :                 .nb_queue_pairs = q_pairs,
     153                 :            :                 .max_nb_priv_xforms = NUM_MAX_XFORMS,
     154                 :            :                 .max_nb_streams = 0
     155                 :            :         };
     156                 :        864 :         rc = rte_compressdev_configure(cdev_id, &config);
     157         [ -  + ]:        864 :         if (rc < 0) {
     158                 :          0 :                 SPDK_ERRLOG("Failed to configure compressdev %u\n", cdev_id);
     159                 :          0 :                 goto err_close;
     160                 :            :         }
     161                 :            : 
     162                 :            :         /* Pre-setup all potential qpairs now and assign them in the channel
     163                 :            :          * callback.
     164                 :            :          */
     165         [ +  + ]:       2592 :         for (i = 0; i < q_pairs; i++) {
     166                 :       1728 :                 rc = rte_compressdev_queue_pair_setup(cdev_id, i,
     167                 :            :                                                       NUM_MAX_INFLIGHT_OPS,
     168                 :       1728 :                                                       rte_socket_id());
     169         [ -  + ]:       1728 :                 if (rc) {
     170         [ #  # ]:          0 :                         if (i > 0) {
     171                 :          0 :                                 q_pairs = i;
     172                 :          0 :                                 SPDK_NOTICELOG("FYI failed to setup a queue pair on "
     173                 :            :                                                "compressdev %u with error %u "
     174                 :            :                                                "so limiting to %u qpairs\n",
     175                 :            :                                                cdev_id, rc, q_pairs);
     176                 :          0 :                                 break;
     177                 :            :                         } else {
     178                 :          0 :                                 SPDK_ERRLOG("Failed to setup queue pair on "
     179                 :            :                                             "compressdev %u with error %u\n", cdev_id, rc);
     180                 :          0 :                                 rc = -EINVAL;
     181                 :          0 :                                 goto err_close;
     182                 :            :                         }
     183                 :            :                 }
     184                 :            :         }
     185                 :            : 
     186                 :        864 :         rc = rte_compressdev_start(cdev_id);
     187         [ -  + ]:        864 :         if (rc < 0) {
     188                 :          0 :                 SPDK_ERRLOG("Failed to start device %u: error %d\n",
     189                 :            :                             cdev_id, rc);
     190                 :          0 :                 goto err_close;
     191                 :            :         }
     192                 :            : 
     193         [ +  - ]:        864 :         if (device->cdev_info.capabilities->comp_feature_flags & RTE_COMP_FF_SHAREABLE_PRIV_XFORM) {
     194                 :        864 :                 rc = rte_compressdev_private_xform_create(cdev_id, &g_comp_xform,
     195                 :            :                                 &device->comp_xform);
     196         [ -  + ]:        864 :                 if (rc < 0) {
     197                 :          0 :                         SPDK_ERRLOG("Failed to create private comp xform device %u: error %d\n",
     198                 :            :                                     cdev_id, rc);
     199                 :          0 :                         goto err_stop;
     200                 :            :                 }
     201                 :            : 
     202                 :        864 :                 rc = rte_compressdev_private_xform_create(cdev_id, &g_decomp_xform,
     203                 :            :                                 &device->decomp_xform);
     204         [ -  + ]:        864 :                 if (rc) {
     205                 :          0 :                         SPDK_ERRLOG("Failed to create private decomp xform device %u: error %d\n",
     206                 :            :                                     cdev_id, rc);
     207                 :          0 :                         goto err_stop;
     208                 :            :                 }
     209                 :            :         } else {
     210                 :          0 :                 SPDK_ERRLOG("PMD does not support shared transforms\n");
     211                 :          0 :                 goto err_stop;
     212                 :            :         }
     213                 :            : 
     214                 :            :         /* Build up list of device/qp combinations */
     215         [ +  + ]:       2592 :         for (i = 0; i < q_pairs; i++) {
     216                 :       1728 :                 dev_qp = calloc(1, sizeof(struct comp_device_qp));
     217         [ -  + ]:       1728 :                 if (!dev_qp) {
     218                 :          0 :                         rc = -ENOMEM;
     219                 :          0 :                         goto err_qp;
     220                 :            :                 }
     221                 :       1728 :                 dev_qp->device = device;
     222                 :       1728 :                 dev_qp->qp = i;
     223                 :       1728 :                 dev_qp->chan = NULL;
     224                 :       1728 :                 TAILQ_INSERT_TAIL(&g_comp_device_qp, dev_qp, link);
     225                 :            :         }
     226                 :            : 
     227                 :        864 :         TAILQ_INSERT_TAIL(&g_compress_devs, device, link);
     228                 :            : 
     229   [ -  +  +  - ]:        864 :         if (strcmp(device->cdev_info.driver_name, QAT_PMD) == 0) {
     230                 :        864 :                 g_qat_available = true;
     231                 :            :         }
     232                 :            : 
     233   [ -  +  -  + ]:        864 :         if (strcmp(device->cdev_info.driver_name, MLX5_PMD) == 0) {
     234                 :          0 :                 g_mlx5_pci_available = true;
     235                 :            :         }
     236                 :            : 
     237   [ -  +  -  + ]:        864 :         if (strcmp(device->cdev_info.driver_name, UADK_PMD) == 0) {
     238                 :          0 :                 g_uadk_available = true;
     239                 :            :         }
     240                 :            : 
     241                 :        864 :         return 0;
     242                 :            : 
     243                 :          0 : err_qp:
     244         [ #  # ]:          0 :         TAILQ_FOREACH_SAFE(dev_qp, &g_comp_device_qp, link, tmp_qp) {
     245         [ #  # ]:          0 :                 TAILQ_REMOVE(&g_comp_device_qp, dev_qp, link);
     246                 :          0 :                 free(dev_qp);
     247                 :            :         }
     248                 :          0 : err_stop:
     249                 :          0 :         rte_compressdev_stop(cdev_id);
     250                 :          0 : err_close:
     251                 :          0 :         rte_compressdev_close(cdev_id);
     252                 :          0 :         free(device);
     253                 :          0 :         return rc;
     254                 :            : }
     255                 :            : 
     256                 :            : /* Called from driver init entry point, accel_compress_init() */
     257                 :            : static int
     258                 :         18 : accel_init_compress_drivers(void)
     259                 :            : {
     260                 :            :         uint8_t cdev_count, i;
     261                 :            :         struct compress_dev *tmp_dev;
     262                 :            :         struct compress_dev *device;
     263                 :            :         int rc;
     264                 :            : 
     265                 :            :         /* If we have no compression devices, report error to fallback on other modules. */
     266                 :         18 :         cdev_count = rte_compressdev_count();
     267         [ -  + ]:         18 :         if (cdev_count == 0) {
     268                 :          0 :                 return -ENODEV;
     269                 :            :         }
     270         [ -  + ]:         18 :         if (cdev_count > RTE_COMPRESS_MAX_DEVS) {
     271                 :          0 :                 SPDK_ERRLOG("invalid device count from rte_compressdev_count()\n");
     272                 :          0 :                 return -EINVAL;
     273                 :            :         }
     274                 :            : 
     275                 :         18 :         g_mbuf_offset = rte_mbuf_dynfield_register(&rte_mbuf_dynfield_io_context);
     276         [ -  + ]:         18 :         if (g_mbuf_offset < 0) {
     277                 :          0 :                 SPDK_ERRLOG("error registering dynamic field with DPDK\n");
     278                 :          0 :                 return -EINVAL;
     279                 :            :         }
     280                 :            : 
     281                 :         18 :         g_mbuf_mp = rte_pktmbuf_pool_create("comp_mbuf_mp", NUM_MBUFS, POOL_CACHE_SIZE,
     282                 :         18 :                                             sizeof(struct rte_mbuf), 0, rte_socket_id());
     283         [ -  + ]:         18 :         if (g_mbuf_mp == NULL) {
     284                 :          0 :                 SPDK_ERRLOG("Cannot create mbuf pool\n");
     285                 :          0 :                 rc = -ENOMEM;
     286                 :          0 :                 goto error_create_mbuf;
     287                 :            :         }
     288                 :            : 
     289                 :         18 :         g_comp_op_mp = rte_comp_op_pool_create("comp_op_pool", NUM_MBUFS, POOL_CACHE_SIZE,
     290                 :         18 :                                                0, rte_socket_id());
     291         [ -  + ]:         18 :         if (g_comp_op_mp == NULL) {
     292                 :          0 :                 SPDK_ERRLOG("Cannot create comp op pool\n");
     293                 :          0 :                 rc = -ENOMEM;
     294                 :          0 :                 goto error_create_op;
     295                 :            :         }
     296                 :            : 
     297                 :            :         /* Init all devices */
     298         [ +  + ]:        882 :         for (i = 0; i < cdev_count; i++) {
     299                 :        864 :                 rc = create_compress_dev(i);
     300         [ -  + ]:        864 :                 if (rc != 0) {
     301                 :          0 :                         goto error_create_compress_devs;
     302                 :            :                 }
     303                 :            :         }
     304                 :            : 
     305   [ -  +  +  - ]:         18 :         if (g_qat_available == true) {
     306                 :         18 :                 SPDK_NOTICELOG("initialized QAT PMD\n");
     307                 :            :         }
     308                 :            : 
     309                 :         18 :         g_shinfo.free_cb = shinfo_free_cb;
     310                 :            : 
     311                 :         18 :         return 0;
     312                 :            : 
     313                 :            :         /* Error cleanup paths. */
     314                 :          0 : error_create_compress_devs:
     315         [ #  # ]:          0 :         TAILQ_FOREACH_SAFE(device, &g_compress_devs, link, tmp_dev) {
     316         [ #  # ]:          0 :                 TAILQ_REMOVE(&g_compress_devs, device, link);
     317                 :          0 :                 free(device);
     318                 :            :         }
     319                 :          0 : error_create_op:
     320                 :          0 : error_create_mbuf:
     321                 :          0 :         rte_mempool_free(g_mbuf_mp);
     322                 :            : 
     323                 :          0 :         return rc;
     324                 :            : }
     325                 :            : 
     326                 :            : int
     327                 :         18 : accel_compressdev_enable_probe(enum compress_pmd *opts)
     328                 :            : {
     329                 :         18 :         g_opts = *opts;
     330                 :         18 :         g_compressdev_enable = true;
     331                 :            : 
     332                 :         18 :         return 0;
     333                 :            : }
     334                 :            : 
     335                 :            : static int
     336                 :    3005092 : _setup_compress_mbuf(struct rte_mbuf **mbufs, int *mbuf_total, uint64_t *total_length,
     337                 :            :                      struct iovec *iovs, int iovcnt, struct spdk_accel_task *task)
     338                 :            : {
     339                 :            :         uint64_t iovec_length, updated_length, phys_addr;
     340                 :            :         uint64_t processed, mbuf_length, remainder;
     341                 :    3005092 :         uint8_t *current_base = NULL;
     342                 :            :         int iov_index, mbuf_index;
     343                 :    3005092 :         int rc = 0;
     344                 :            : 
     345                 :            :         /* Setup mbufs */
     346                 :    3005092 :         iov_index = mbuf_index = 0;
     347         [ +  + ]:    6010184 :         while (iov_index < iovcnt) {
     348                 :            : 
     349                 :    3005092 :                 processed = 0;
     350                 :    3005092 :                 iovec_length = iovs[iov_index].iov_len;
     351                 :            : 
     352                 :    3005092 :                 current_base = iovs[iov_index].iov_base;
     353         [ +  + ]:    3005092 :                 if (total_length) {
     354                 :    1502546 :                         *total_length += iovec_length;
     355                 :            :                 }
     356                 :            : 
     357         [ -  + ]:    3005092 :                 assert(mbufs[mbuf_index] != NULL);
     358                 :    3005092 :                 *RTE_MBUF_DYNFIELD(mbufs[mbuf_index], g_mbuf_offset, uint64_t *) = (uint64_t)task;
     359                 :            : 
     360                 :            :                 do {
     361                 :            :                         /* new length is min of remaining left or max mbuf size of MBUF_SPLIT */
     362                 :    3648494 :                         mbuf_length = updated_length = spdk_min(MBUF_SPLIT, iovec_length - processed);
     363                 :            : 
     364                 :    3648494 :                         phys_addr = spdk_vtophys((void *)current_base, &updated_length);
     365                 :            : 
     366                 :    3648494 :                         rte_pktmbuf_attach_extbuf(mbufs[mbuf_index],
     367                 :            :                                                   current_base,
     368                 :            :                                                   phys_addr,
     369                 :            :                                                   updated_length,
     370                 :            :                                                   &g_shinfo);
     371                 :    3648494 :                         rte_pktmbuf_append(mbufs[mbuf_index], updated_length);
     372                 :    3648494 :                         remainder = mbuf_length - updated_length;
     373                 :            : 
     374                 :            :                         /* although the mbufs were preallocated, we still need to chain them */
     375         [ +  + ]:    3648494 :                         if (mbuf_index > 0) {
     376                 :     643402 :                                 rte_pktmbuf_chain(mbufs[0], mbufs[mbuf_index]);
     377                 :            :                         }
     378                 :            : 
     379                 :            :                         /* keep track of the total we've put into the mbuf chain */
     380                 :    3648494 :                         processed += updated_length;
     381                 :            :                         /* bump the base by what was previously added */
     382                 :    3648494 :                         current_base += updated_length;
     383                 :            : 
     384                 :            :                         /* If we crossed 2MB boundary we need another mbuf for the remainder */
     385         [ -  + ]:    3648494 :                         if (remainder > 0) {
     386                 :            : 
     387         [ #  # ]:          0 :                                 assert(remainder <= MBUF_SPLIT);
     388                 :            : 
     389                 :            :                                 /* allocate an mbuf at the end of the array */
     390                 :          0 :                                 rc = rte_pktmbuf_alloc_bulk(g_mbuf_mp,
     391                 :          0 :                                                             (struct rte_mbuf **)&mbufs[*mbuf_total], 1);
     392         [ #  # ]:          0 :                                 if (rc) {
     393                 :          0 :                                         SPDK_ERRLOG("ERROR trying to get an extra mbuf!\n");
     394                 :          0 :                                         return -1;
     395                 :            :                                 }
     396                 :          0 :                                 (*mbuf_total)++;
     397                 :          0 :                                 mbuf_index++;
     398                 :          0 :                                 *RTE_MBUF_DYNFIELD(mbufs[mbuf_index], g_mbuf_offset, uint64_t *) = (uint64_t)task;
     399                 :            : 
     400                 :            :                                 /* bump the base by what was previously added */
     401                 :          0 :                                 current_base += updated_length;
     402                 :            : 
     403                 :          0 :                                 updated_length = remainder;
     404                 :          0 :                                 phys_addr = spdk_vtophys((void *)current_base, &updated_length);
     405                 :            : 
     406                 :            :                                 /* assert we don't cross another */
     407         [ #  # ]:          0 :                                 assert(remainder == updated_length);
     408                 :            : 
     409                 :          0 :                                 rte_pktmbuf_attach_extbuf(mbufs[mbuf_index],
     410                 :            :                                                           current_base,
     411                 :            :                                                           phys_addr,
     412                 :            :                                                           remainder,
     413                 :            :                                                           &g_shinfo);
     414                 :          0 :                                 rte_pktmbuf_append(mbufs[mbuf_index], remainder);
     415                 :          0 :                                 rte_pktmbuf_chain(mbufs[0], mbufs[mbuf_index]);
     416                 :            : 
     417                 :            :                                 /* keep track of the total we've put into the mbuf chain */
     418                 :          0 :                                 processed += remainder;
     419                 :            :                         }
     420                 :            : 
     421                 :    3648494 :                         mbuf_index++;
     422                 :            : 
     423         [ +  + ]:    3648494 :                 } while (processed < iovec_length);
     424                 :            : 
     425         [ -  + ]:    3005092 :                 assert(processed == iovec_length);
     426                 :    3005092 :                 iov_index++;
     427                 :            :         }
     428                 :            : 
     429                 :    3005092 :         return 0;
     430                 :            : }
     431                 :            : 
     432                 :            : static int
     433                 :    1502546 : _compress_operation(struct compress_io_channel *chan,  struct spdk_accel_task *task)
     434                 :            : {
     435                 :    1502546 :         int dst_iovcnt = task->d.iovcnt;
     436                 :    1502546 :         struct iovec *dst_iovs = task->d.iovs;
     437                 :    1502546 :         int src_iovcnt = task->s.iovcnt;
     438                 :    1502546 :         struct iovec *src_iovs = task->s.iovs;
     439                 :            :         struct rte_comp_op *comp_op;
     440                 :            :         uint8_t cdev_id;
     441                 :    1502546 :         uint64_t total_length = 0;
     442                 :    1502546 :         int rc = 0, i;
     443                 :    1502546 :         int src_mbuf_total = 0;
     444                 :    1502546 :         int dst_mbuf_total = 0;
     445                 :    1502546 :         bool device_error = false;
     446                 :    1502546 :         bool compress = (task->op_code == SPDK_ACCEL_OPC_COMPRESS);
     447                 :            : 
     448         [ -  + ]:    1502546 :         assert(chan->device_qp->device != NULL);
     449                 :    1502546 :         cdev_id = chan->device_qp->device->cdev_id;
     450                 :            : 
     451                 :            :         /* calc our mbuf totals based on max MBUF size allowed so we can pre-alloc mbufs in bulk */
     452         [ +  + ]:    3005092 :         for (i = 0 ; i < src_iovcnt; i++) {
     453                 :    1502546 :                 src_mbuf_total += spdk_divide_round_up(src_iovs[i].iov_len, MBUF_SPLIT);
     454                 :            :         }
     455         [ +  + ]:    3005092 :         for (i = 0 ; i < dst_iovcnt; i++) {
     456                 :    1502546 :                 dst_mbuf_total += spdk_divide_round_up(dst_iovs[i].iov_len, MBUF_SPLIT);
     457                 :            :         }
     458                 :            : 
     459                 :    1502546 :         comp_op = rte_comp_op_alloc(g_comp_op_mp);
     460         [ -  + ]:    1502546 :         if (!comp_op) {
     461                 :          0 :                 SPDK_ERRLOG("trying to get a comp op!\n");
     462                 :          0 :                 rc = -ENOMEM;
     463                 :          0 :                 goto error_get_op;
     464                 :            :         }
     465                 :            : 
     466                 :            :         /* get an mbuf per iov, src and dst */
     467                 :    1502546 :         rc = rte_pktmbuf_alloc_bulk(g_mbuf_mp, chan->src_mbufs, src_mbuf_total);
     468         [ -  + ]:    1502546 :         if (rc) {
     469                 :          0 :                 SPDK_ERRLOG("ERROR trying to get src_mbufs!\n");
     470                 :          0 :                 rc = -ENOMEM;
     471                 :          0 :                 goto error_get_src;
     472                 :            :         }
     473         [ -  + ]:    1502546 :         assert(chan->src_mbufs[0]);
     474                 :            : 
     475                 :    1502546 :         rc = rte_pktmbuf_alloc_bulk(g_mbuf_mp, chan->dst_mbufs, dst_mbuf_total);
     476         [ -  + ]:    1502546 :         if (rc) {
     477                 :          0 :                 SPDK_ERRLOG("ERROR trying to get dst_mbufs!\n");
     478                 :          0 :                 rc = -ENOMEM;
     479                 :          0 :                 goto error_get_dst;
     480                 :            :         }
     481         [ -  + ]:    1502546 :         assert(chan->dst_mbufs[0]);
     482                 :            : 
     483                 :    1502546 :         rc = _setup_compress_mbuf(chan->src_mbufs, &src_mbuf_total, &total_length,
     484                 :            :                                   src_iovs, src_iovcnt, task);
     485                 :            : 
     486         [ -  + ]:    1502546 :         if (rc < 0) {
     487                 :          0 :                 goto error_src_dst;
     488                 :            :         }
     489   [ -  +  -  +  :    1502546 :         if (!chan->device_qp->device->sgl_in && src_mbuf_total > 1) {
                   -  - ]
     490                 :          0 :                 SPDK_ERRLOG("Src buffer uses chained mbufs but driver %s doesn't support SGL input\n",
     491                 :            :                             chan->drv_name);
     492                 :          0 :                 rc = -EINVAL;
     493                 :          0 :                 goto error_src_dst;
     494                 :            :         }
     495                 :            : 
     496                 :    1502546 :         comp_op->m_src = chan->src_mbufs[0];
     497                 :    1502546 :         comp_op->src.offset = 0;
     498                 :    1502546 :         comp_op->src.length = total_length;
     499                 :            : 
     500                 :    1502546 :         rc = _setup_compress_mbuf(chan->dst_mbufs, &dst_mbuf_total, NULL,
     501                 :            :                                   dst_iovs, dst_iovcnt, task);
     502         [ -  + ]:    1502546 :         if (rc < 0) {
     503                 :          0 :                 goto error_src_dst;
     504                 :            :         }
     505   [ -  +  -  +  :    1502546 :         if (!chan->device_qp->device->sgl_out && dst_mbuf_total > 1) {
                   -  - ]
     506                 :          0 :                 SPDK_ERRLOG("Dst buffer uses chained mbufs but driver %s doesn't support SGL output\n",
     507                 :            :                             chan->drv_name);
     508                 :          0 :                 rc = -EINVAL;
     509                 :          0 :                 goto error_src_dst;
     510                 :            :         }
     511                 :            : 
     512                 :    1502546 :         comp_op->m_dst = chan->dst_mbufs[0];
     513                 :    1502546 :         comp_op->dst.offset = 0;
     514                 :            : 
     515         [ +  + ]:    1502546 :         if (compress == true) {
     516                 :     465534 :                 comp_op->private_xform = chan->device_qp->device->comp_xform;
     517                 :            :         } else {
     518                 :    1037012 :                 comp_op->private_xform = chan->device_qp->device->decomp_xform;
     519                 :            :         }
     520                 :            : 
     521                 :    1502546 :         comp_op->op_type = RTE_COMP_OP_STATELESS;
     522                 :    1502546 :         comp_op->flush_flag = RTE_COMP_FLUSH_FINAL;
     523                 :            : 
     524                 :    1502546 :         rc = rte_compressdev_enqueue_burst(cdev_id, chan->device_qp->qp, &comp_op, 1);
     525         [ -  + ]:    1502546 :         assert(rc <= 1);
     526                 :            : 
     527                 :            :         /* We always expect 1 got queued, if 0 then we need to queue it up. */
     528         [ +  + ]:    1502546 :         if (rc == 1) {
     529                 :    1502545 :                 return 0;
     530         [ +  - ]:          1 :         } else if (comp_op->status == RTE_COMP_OP_STATUS_NOT_PROCESSED) {
     531                 :          1 :                 rc = -EAGAIN;
     532                 :            :         } else {
     533                 :          0 :                 device_error = true;
     534                 :            :         }
     535                 :            : 
     536                 :            :         /* Error cleanup paths. */
     537                 :          1 : error_src_dst:
     538                 :          1 :         rte_pktmbuf_free_bulk(chan->dst_mbufs, dst_iovcnt);
     539                 :          1 : error_get_dst:
     540                 :          1 :         rte_pktmbuf_free_bulk(chan->src_mbufs, src_iovcnt);
     541                 :          1 : error_get_src:
     542                 :          1 :         rte_comp_op_free(comp_op);
     543                 :          1 : error_get_op:
     544                 :            : 
     545         [ -  + ]:          1 :         if (device_error == true) {
     546                 :            :                 /* There was an error sending the op to the device, most
     547                 :            :                  * likely with the parameters.
     548                 :            :                  */
     549                 :          0 :                 SPDK_ERRLOG("Compression API returned 0x%x\n", comp_op->status);
     550                 :          0 :                 return -EINVAL;
     551                 :            :         }
     552   [ +  -  -  + ]:          1 :         if (rc != -ENOMEM && rc != -EAGAIN) {
     553                 :          0 :                 return rc;
     554                 :            :         }
     555                 :            : 
     556                 :          1 :         STAILQ_INSERT_TAIL(&chan->queued_tasks, task, link);
     557                 :          1 :         return 0;
     558                 :            : }
     559                 :            : 
     560                 :            : /* Poller for the DPDK compression driver. */
     561                 :            : static int
     562                 :   24927147 : comp_dev_poller(void *args)
     563                 :            : {
     564                 :   24927147 :         struct compress_io_channel *chan = args;
     565                 :            :         uint8_t cdev_id;
     566                 :            :         struct rte_comp_op *deq_ops[NUM_MAX_INFLIGHT_OPS];
     567                 :            :         uint16_t num_deq;
     568                 :            :         struct spdk_accel_task *task, *task_to_resubmit;
     569                 :            :         int rc, i, status;
     570                 :            : 
     571         [ -  + ]:   24927147 :         assert(chan->device_qp->device != NULL);
     572                 :   24927147 :         cdev_id = chan->device_qp->device->cdev_id;
     573                 :            : 
     574                 :   24927147 :         num_deq = rte_compressdev_dequeue_burst(cdev_id, chan->device_qp->qp, deq_ops,
     575                 :            :                                                 NUM_MAX_INFLIGHT_OPS);
     576         [ +  + ]:   26429692 :         for (i = 0; i < num_deq; i++) {
     577                 :            : 
     578                 :            :                 /* We store this off regardless of success/error so we know how to construct the
     579                 :            :                  * next task
     580                 :            :                  */
     581                 :    1502545 :                 task = (struct spdk_accel_task *)*RTE_MBUF_DYNFIELD(deq_ops[i]->m_src, g_mbuf_offset,
     582                 :            :                                 uint64_t *);
     583                 :    1502545 :                 status = deq_ops[i]->status;
     584                 :            : 
     585         [ +  - ]:    1502545 :                 if (spdk_likely(status == RTE_COMP_OP_STATUS_SUCCESS)) {
     586         [ +  + ]:    1502545 :                         if (task->output_size != NULL) {
     587                 :     887532 :                                 *task->output_size = deq_ops[i]->produced;
     588                 :            :                         }
     589                 :    1502545 :                         status = 0;
     590                 :            :                 } else {
     591                 :          0 :                         SPDK_NOTICELOG("Deque status %u\n", status);
     592                 :          0 :                         status = -EIO;
     593                 :            :                 }
     594                 :            : 
     595                 :    1502545 :                 spdk_accel_task_complete(task, status);
     596                 :            : 
     597                 :            :                 /* Now free both mbufs and the compress operation. The rte_pktmbuf_free()
     598                 :            :                  * call takes care of freeing all of the mbufs in the chain back to their
     599                 :            :                  * original pool.
     600                 :            :                  */
     601                 :    1502545 :                 rte_pktmbuf_free(deq_ops[i]->m_src);
     602                 :    1502545 :                 rte_pktmbuf_free(deq_ops[i]->m_dst);
     603                 :            : 
     604                 :            :                 /* There is no bulk free for com ops so we have to free them one at a time
     605                 :            :                  * here however it would be rare that we'd ever have more than 1 at a time
     606                 :            :                  * anyways.
     607                 :            :                  */
     608                 :    1502545 :                 rte_comp_op_free(deq_ops[i]);
     609                 :            : 
     610                 :            :                 /* Check if there are any pending comp ops to process, only pull one
     611                 :            :                  * at a time off as _compress_operation() may re-queue the op.
     612                 :            :                  */
     613         [ +  + ]:    1502545 :                 if (!STAILQ_EMPTY(&chan->queued_tasks)) {
     614                 :          1 :                         task_to_resubmit = STAILQ_FIRST(&chan->queued_tasks);
     615                 :          1 :                         rc = _compress_operation(chan, task_to_resubmit);
     616         [ +  - ]:          1 :                         if (rc == 0) {
     617         [ +  - ]:          1 :                                 STAILQ_REMOVE_HEAD(&chan->queued_tasks, link);
     618                 :            :                         }
     619                 :            :                 }
     620                 :            :         }
     621                 :            : 
     622                 :   24927147 :         return num_deq == 0 ? SPDK_POLLER_IDLE : SPDK_POLLER_BUSY;
     623                 :            : }
     624                 :            : 
     625                 :            : static int
     626                 :    1502545 : _process_single_task(struct spdk_io_channel *ch, struct spdk_accel_task *task)
     627                 :            : {
     628                 :    1502545 :         struct compress_io_channel *chan = spdk_io_channel_get_ctx(ch);
     629                 :            :         int rc;
     630                 :            : 
     631                 :    1502545 :         rc = _compress_operation(chan, task);
     632         [ -  + ]:    1502545 :         if (rc) {
     633                 :          0 :                 SPDK_ERRLOG("Error (%d) in compress operation\n", rc);
     634                 :          0 :                 assert(false);
     635                 :            :         }
     636                 :            : 
     637                 :    1502545 :         return rc;
     638                 :            : }
     639                 :            : 
     640                 :            : static int
     641                 :    1502545 : compress_submit_tasks(struct spdk_io_channel *ch, struct spdk_accel_task *first_task)
     642                 :            : {
     643                 :    1502545 :         struct compress_io_channel *chan = spdk_io_channel_get_ctx(ch);
     644                 :            :         struct spdk_accel_task *task, *tmp;
     645                 :    1502545 :         int rc = 0;
     646                 :            : 
     647                 :    1502545 :         task = first_task;
     648                 :            : 
     649         [ -  + ]:    1502545 :         if (!STAILQ_EMPTY(&chan->queued_tasks)) {
     650                 :          0 :                 goto queue_tasks;
     651                 :            :         }
     652                 :            : 
     653                 :            :         /* The caller will either submit a single task or a group of tasks that are
     654                 :            :          * linked together but they cannot be on a list. For example, see poller
     655                 :            :          * where a list of queued tasks is being resubmitted, the list they are on
     656                 :            :          * is initialized after saving off the first task from the list which is then
     657                 :            :          * passed in here.  Similar thing is done in the accel framework.
     658                 :            :          */
     659         [ +  + ]:    3005090 :         while (task) {
     660                 :    1502545 :                 tmp = STAILQ_NEXT(task, link);
     661                 :    1502545 :                 rc = _process_single_task(ch, task);
     662                 :            : 
     663         [ -  + ]:    1502545 :                 if (rc == -EBUSY) {
     664                 :          0 :                         goto queue_tasks;
     665         [ -  + ]:    1502545 :                 } else if (rc) {
     666                 :          0 :                         spdk_accel_task_complete(task, rc);
     667                 :            :                 }
     668                 :    1502545 :                 task = tmp;
     669                 :            :         }
     670                 :            : 
     671                 :    1502545 :         return 0;
     672                 :            : 
     673                 :          0 : queue_tasks:
     674         [ #  # ]:          0 :         while (task != NULL) {
     675                 :          0 :                 tmp = STAILQ_NEXT(task, link);
     676                 :          0 :                 STAILQ_INSERT_TAIL(&chan->queued_tasks, task, link);
     677                 :          0 :                 task = tmp;
     678                 :            :         }
     679                 :          0 :         return 0;
     680                 :            : }
     681                 :            : 
     682                 :            : static bool
     683                 :         61 : _set_pmd(struct compress_io_channel *chan)
     684                 :            : {
     685                 :            : 
     686                 :            :         /* Note: the compress_isal PMD is not supported as accel_fw supports native ISAL
     687                 :            :          * using the accel_sw module */
     688         [ +  + ]:         61 :         if (g_opts == COMPRESS_PMD_AUTO) {
     689   [ -  +  +  - ]:         22 :                 if (g_qat_available) {
     690                 :         22 :                         chan->drv_name = QAT_PMD;
     691   [ #  #  #  # ]:          0 :                 } else if (g_mlx5_pci_available) {
     692                 :          0 :                         chan->drv_name = MLX5_PMD;
     693   [ #  #  #  # ]:          0 :                 } else if (g_uadk_available) {
     694                 :          0 :                         chan->drv_name = UADK_PMD;
     695                 :            :                 }
     696   [ +  -  -  +  :         39 :         } else if (g_opts == COMPRESS_PMD_QAT_ONLY && g_qat_available) {
                   +  - ]
     697                 :         39 :                 chan->drv_name = QAT_PMD;
     698   [ #  #  #  #  :          0 :         } else if (g_opts == COMPRESS_PMD_MLX5_PCI_ONLY && g_mlx5_pci_available) {
                   #  # ]
     699                 :          0 :                 chan->drv_name = MLX5_PMD;
     700   [ #  #  #  #  :          0 :         } else if (g_opts == COMPRESS_PMD_UADK_ONLY && g_uadk_available) {
                   #  # ]
     701                 :          0 :                 chan->drv_name = UADK_PMD;
     702                 :            :         } else {
     703                 :          0 :                 SPDK_ERRLOG("Requested PMD is not available.\n");
     704                 :          0 :                 return false;
     705                 :            :         }
     706                 :         61 :         SPDK_NOTICELOG("Channel %p PMD being used: %s\n", chan, chan->drv_name);
     707                 :         61 :         return true;
     708                 :            : }
     709                 :            : 
     710                 :            : static int compress_create_cb(void *io_device, void *ctx_buf);
     711                 :            : static void compress_destroy_cb(void *io_device, void *ctx_buf);
     712                 :            : static struct spdk_accel_module_if g_compress_module;
     713                 :            : static int
     714                 :         18 : accel_compress_init(void)
     715                 :            : {
     716                 :            :         int rc;
     717                 :            : 
     718   [ -  +  -  + ]:         18 :         if (!g_compressdev_enable) {
     719                 :          0 :                 return -EINVAL;
     720                 :            :         }
     721                 :            : 
     722         [ -  + ]:         18 :         if (g_opts == COMPRESS_PMD_UADK_ONLY) {
     723                 :          0 :                 char *driver_name = UADK_PMD;
     724                 :            : 
     725                 :          0 :                 rc = rte_vdev_init(driver_name, NULL);
     726         [ #  # ]:          0 :                 if (rc) {
     727                 :          0 :                         SPDK_NOTICELOG("Failed to create virtual PMD %s: error %d. "
     728                 :            :                                        "Possibly %s is not supported by DPDK library. "
     729                 :            :                                        "Keep going...\n", driver_name, rc, driver_name);
     730                 :            :                 }
     731                 :            :         }
     732                 :            : 
     733                 :         18 :         rc = accel_init_compress_drivers();
     734         [ -  + ]:         18 :         if (rc) {
     735         [ #  # ]:          0 :                 assert(TAILQ_EMPTY(&g_compress_devs));
     736                 :          0 :                 return rc;
     737                 :            :         }
     738                 :            : 
     739                 :         18 :         g_compressdev_initialized = true;
     740                 :         18 :         spdk_io_device_register(&g_compress_module, compress_create_cb, compress_destroy_cb,
     741                 :            :                                 sizeof(struct compress_io_channel), "compressdev_accel_module");
     742                 :         18 :         return 0;
     743                 :            : }
     744                 :            : 
     745                 :            : static int
     746                 :         61 : compress_create_cb(void *io_device, void *ctx_buf)
     747                 :            : {
     748                 :         61 :         struct compress_io_channel *chan = ctx_buf;
     749                 :            :         const struct rte_compressdev_capabilities *capab;
     750                 :            :         struct comp_device_qp *device_qp;
     751                 :            :         size_t length;
     752                 :            : 
     753         [ -  + ]:         61 :         if (_set_pmd(chan) == false) {
     754                 :          0 :                 assert(false);
     755                 :            :                 return -ENODEV;
     756                 :            :         }
     757                 :            : 
     758                 :            :         /* The following variable length arrays of mbuf pointers are required to submit to compressdev */
     759                 :         61 :         length = NUM_MBUFS * sizeof(void *);
     760                 :         61 :         chan->src_mbufs = spdk_zmalloc(length, 0x40, NULL,
     761                 :            :                                        SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
     762         [ -  + ]:         61 :         if (chan->src_mbufs == NULL) {
     763                 :          0 :                 return -ENOMEM;
     764                 :            :         }
     765                 :         61 :         chan->dst_mbufs = spdk_zmalloc(length, 0x40, NULL,
     766                 :            :                                        SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
     767         [ -  + ]:         61 :         if (chan->dst_mbufs == NULL) {
     768                 :          0 :                 spdk_free(chan->src_mbufs);
     769                 :          0 :                 return -ENOMEM;
     770                 :            :         }
     771                 :            : 
     772                 :         61 :         chan->poller = SPDK_POLLER_REGISTER(comp_dev_poller, chan, 0);
     773                 :         61 :         STAILQ_INIT(&chan->queued_tasks);
     774                 :            : 
     775                 :         61 :         pthread_mutex_lock(&g_comp_device_qp_lock);
     776         [ +  - ]:        118 :         TAILQ_FOREACH(device_qp, &g_comp_device_qp, link) {
     777   [ -  +  -  +  :        118 :                 if (strcmp(device_qp->device->cdev_info.driver_name, chan->drv_name) == 0) {
                   +  - ]
     778         [ +  + ]:        118 :                         if (device_qp->chan == NULL) {
     779                 :         61 :                                 chan->device_qp = device_qp;
     780                 :         61 :                                 device_qp->chan = chan;
     781                 :         61 :                                 break;
     782                 :            :                         }
     783                 :            :                 }
     784                 :            :         }
     785                 :         61 :         pthread_mutex_unlock(&g_comp_device_qp_lock);
     786                 :            : 
     787         [ -  + ]:         61 :         if (chan->device_qp == NULL) {
     788                 :          0 :                 SPDK_ERRLOG("out of qpairs, cannot assign one\n");
     789                 :          0 :                 assert(false);
     790                 :            :                 return -ENOMEM;
     791                 :            :         } else {
     792                 :         61 :                 capab = rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE);
     793                 :            : 
     794         [ +  - ]:         61 :                 if (capab->comp_feature_flags & (RTE_COMP_FF_OOP_SGL_IN_SGL_OUT | RTE_COMP_FF_OOP_SGL_IN_LB_OUT)) {
     795                 :         61 :                         chan->device_qp->device->sgl_in = true;
     796                 :            :                 }
     797                 :            : 
     798         [ +  - ]:         61 :                 if (capab->comp_feature_flags & (RTE_COMP_FF_OOP_SGL_IN_SGL_OUT | RTE_COMP_FF_OOP_LB_IN_SGL_OUT)) {
     799                 :         61 :                         chan->device_qp->device->sgl_out = true;
     800                 :            :                 }
     801                 :            :         }
     802                 :            : 
     803                 :         61 :         return 0;
     804                 :            : }
     805                 :            : 
     806                 :            : static void
     807                 :          1 : accel_compress_write_config_json(struct spdk_json_write_ctx *w)
     808                 :            : {
     809   [ -  +  +  - ]:          1 :         if (g_compressdev_enable) {
     810                 :          1 :                 spdk_json_write_object_begin(w);
     811                 :          1 :                 spdk_json_write_named_string(w, "method", "compressdev_scan_accel_module");
     812                 :          1 :                 spdk_json_write_named_object_begin(w, "params");
     813                 :          1 :                 spdk_json_write_named_uint32(w, "pmd", g_opts);
     814                 :          1 :                 spdk_json_write_object_end(w);
     815                 :          1 :                 spdk_json_write_object_end(w);
     816                 :            :         }
     817                 :          1 : }
     818                 :            : 
     819                 :            : static void
     820                 :         61 : compress_destroy_cb(void *io_device, void *ctx_buf)
     821                 :            : {
     822                 :         61 :         struct compress_io_channel *chan = ctx_buf;
     823                 :         61 :         struct comp_device_qp *device_qp = chan->device_qp;
     824                 :            : 
     825                 :         61 :         spdk_free(chan->src_mbufs);
     826                 :         61 :         spdk_free(chan->dst_mbufs);
     827                 :            : 
     828                 :         61 :         spdk_poller_unregister(&chan->poller);
     829                 :            : 
     830         [ -  + ]:         61 :         pthread_mutex_lock(&g_comp_device_qp_lock);
     831                 :         61 :         chan->device_qp = NULL;
     832                 :         61 :         device_qp->chan = NULL;
     833         [ -  + ]:         61 :         pthread_mutex_unlock(&g_comp_device_qp_lock);
     834                 :         61 : }
     835                 :            : 
     836                 :            : static size_t
     837                 :         18 : accel_compress_get_ctx_size(void)
     838                 :            : {
     839                 :         18 :         return 0;
     840                 :            : }
     841                 :            : 
     842                 :            : static bool
     843                 :        306 : compress_supports_opcode(enum spdk_accel_opcode opc)
     844                 :            : {
     845   [ -  +  +  -  :        306 :         if (g_mlx5_pci_available || g_qat_available || g_uadk_available) {
          -  +  -  +  -  
                -  -  - ]
     846         [ +  + ]:        306 :                 switch (opc) {
     847                 :         36 :                 case SPDK_ACCEL_OPC_COMPRESS:
     848                 :            :                 case SPDK_ACCEL_OPC_DECOMPRESS:
     849                 :         36 :                         return true;
     850                 :        270 :                 default:
     851                 :        270 :                         break;
     852                 :            :                 }
     853                 :            :         }
     854                 :            : 
     855                 :        270 :         return false;
     856                 :            : }
     857                 :            : 
     858                 :            : static bool
     859                 :    1502545 : compress_supports_algo(enum spdk_accel_comp_algo algo)
     860                 :            : {
     861         [ +  - ]:    1502545 :         if (algo == SPDK_ACCEL_COMP_ALGO_DEFLATE) {
     862                 :    1502545 :                 return true;
     863                 :            :         }
     864                 :            : 
     865                 :          0 :         return false;
     866                 :            : }
     867                 :            : 
     868                 :            : static int
     869                 :         10 : compress_get_level_range(enum spdk_accel_comp_algo algo,
     870                 :            :                          uint32_t *min_level, uint32_t *max_level)
     871                 :            : {
     872         [ +  - ]:         10 :         switch (algo) {
     873                 :         10 :         case SPDK_ACCEL_COMP_ALGO_DEFLATE:
     874                 :            :                 /**
     875                 :            :                  * Hardware compression is set to the highest level by default and
     876                 :            :                  * will not be affected by cover parameters in actual operation.
     877                 :            :                  * This is set to the maximum range.
     878                 :            :                  * */
     879                 :         10 :                 *min_level = 0;
     880                 :         10 :                 *max_level = 0;
     881                 :            : 
     882                 :         10 :                 return 0;
     883                 :          0 :         default:
     884                 :          0 :                 return -EINVAL;
     885                 :            :         }
     886                 :            : }
     887                 :            : 
     888                 :            : static struct spdk_io_channel *
     889                 :        122 : compress_get_io_channel(void)
     890                 :            : {
     891                 :        122 :         return spdk_get_io_channel(&g_compress_module);
     892                 :            : }
     893                 :            : 
     894                 :            : static void accel_compress_exit(void *ctx);
     895                 :            : static struct spdk_accel_module_if g_compress_module = {
     896                 :            :         .module_init                 = accel_compress_init,
     897                 :            :         .module_fini                 = accel_compress_exit,
     898                 :            :         .write_config_json           = accel_compress_write_config_json,
     899                 :            :         .get_ctx_size                = accel_compress_get_ctx_size,
     900                 :            :         .name                        = "dpdk_compressdev",
     901                 :            :         .supports_opcode             = compress_supports_opcode,
     902                 :            :         .get_io_channel              = compress_get_io_channel,
     903                 :            :         .submit_tasks                = compress_submit_tasks,
     904                 :            :         .compress_supports_algo      = compress_supports_algo,
     905                 :            :         .get_compress_level_range    = compress_get_level_range,
     906                 :            : };
     907                 :            : 
     908                 :            : void
     909                 :         18 : accel_dpdk_compressdev_enable(void)
     910                 :            : {
     911                 :         18 :         spdk_accel_module_list_add(&g_compress_module);
     912                 :         18 : }
     913                 :            : 
     914                 :            : /* Callback for unregistering the IO device. */
     915                 :            : static void
     916                 :         18 : _device_unregister_cb(void *io_device)
     917                 :            : {
     918                 :            :         struct comp_device_qp *dev_qp;
     919                 :            :         struct compress_dev *device;
     920                 :            : 
     921         [ +  + ]:        882 :         while ((device = TAILQ_FIRST(&g_compress_devs))) {
     922         [ +  + ]:        864 :                 TAILQ_REMOVE(&g_compress_devs, device, link);
     923                 :        864 :                 rte_compressdev_stop(device->cdev_id);
     924                 :        864 :                 rte_compressdev_close(device->cdev_id);
     925                 :        864 :                 free(device);
     926                 :            :         }
     927                 :            : 
     928         [ +  + ]:       1746 :         while ((dev_qp = TAILQ_FIRST(&g_comp_device_qp))) {
     929         [ +  + ]:       1728 :                 TAILQ_REMOVE(&g_comp_device_qp, dev_qp, link);
     930                 :       1728 :                 free(dev_qp);
     931                 :            :         }
     932                 :            : 
     933         [ -  + ]:         18 :         if (g_opts == COMPRESS_PMD_UADK_ONLY) {
     934                 :          0 :                 rte_vdev_uninit(UADK_PMD);
     935                 :            :         }
     936                 :            : 
     937         [ -  + ]:         18 :         pthread_mutex_destroy(&g_comp_device_qp_lock);
     938                 :            : 
     939                 :         18 :         rte_mempool_free(g_comp_op_mp);
     940                 :         18 :         rte_mempool_free(g_mbuf_mp);
     941                 :            : 
     942                 :         18 :         spdk_accel_module_finish();
     943                 :         18 : }
     944                 :            : 
     945                 :            : static void
     946                 :         18 : accel_compress_exit(void *ctx)
     947                 :            : {
     948   [ -  +  +  - ]:         18 :         if (g_compressdev_initialized) {
     949                 :         18 :                 spdk_io_device_unregister(&g_compress_module, _device_unregister_cb);
     950                 :         18 :                 g_compressdev_initialized = false;
     951                 :            :         } else {
     952                 :          0 :                 spdk_accel_module_finish();
     953                 :            :         }
     954                 :         18 : }

Generated by: LCOV version 1.15