LCOV - code coverage report
Current view: top level - spdk/lib/accel - accel_sw.c (source / functions) Hit Total Coverage
Test: Combined Lines: 390 560 69.6 %
Date: 2024-11-20 17:20:58 Functions: 38 40 95.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 279 1964 14.2 %

           Branch data     Line data    Source code
       1                 :            : /*   SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *   Copyright (C) 2022 Intel Corporation.
       3                 :            :  *   Copyright (c) 2022, 2023 NVIDIA CORPORATION & AFFILIATES
       4                 :            :  *   All rights reserved.
       5                 :            :  */
       6                 :            : 
       7                 :            : #include "spdk/stdinc.h"
       8                 :            : 
       9                 :            : #include "spdk/accel_module.h"
      10                 :            : #include "accel_internal.h"
      11                 :            : 
      12                 :            : #include "spdk/env.h"
      13                 :            : #include "spdk/likely.h"
      14                 :            : #include "spdk/log.h"
      15                 :            : #include "spdk/thread.h"
      16                 :            : #include "spdk/json.h"
      17                 :            : #include "spdk/crc32.h"
      18                 :            : #include "spdk/util.h"
      19                 :            : #include "spdk/xor.h"
      20                 :            : #include "spdk/dif.h"
      21                 :            : 
      22                 :            : #ifdef SPDK_CONFIG_HAVE_LZ4
      23                 :            : #include <lz4.h>
      24                 :            : #endif
      25                 :            : 
      26                 :            : #ifdef SPDK_CONFIG_ISAL
      27                 :            : #include "../isa-l/include/igzip_lib.h"
      28                 :            : #ifdef SPDK_CONFIG_ISAL_CRYPTO
      29                 :            : #include "../isa-l-crypto/include/aes_xts.h"
      30                 :            : #include "../isa-l-crypto/include/isal_crypto_api.h"
      31                 :            : #endif
      32                 :            : #endif
      33                 :            : 
      34                 :            : /* Per the AES-XTS spec, the size of data unit cannot be bigger than 2^20 blocks, 128b each block */
      35                 :            : #define ACCEL_AES_XTS_MAX_BLOCK_SIZE (1 << 24)
      36                 :            : 
      37                 :            : #ifdef SPDK_CONFIG_ISAL
      38                 :            : #define COMP_DEFLATE_MIN_LEVEL ISAL_DEF_MIN_LEVEL
      39                 :            : #define COMP_DEFLATE_MAX_LEVEL ISAL_DEF_MAX_LEVEL
      40                 :            : #else
      41                 :            : #define COMP_DEFLATE_MIN_LEVEL 0
      42                 :            : #define COMP_DEFLATE_MAX_LEVEL 0
      43                 :            : #endif
      44                 :            : 
      45                 :            : #define COMP_DEFLATE_LEVEL_NUM (COMP_DEFLATE_MAX_LEVEL + 1)
      46                 :            : 
      47                 :            : struct comp_deflate_level_buf {
      48                 :            :         uint32_t size;
      49                 :            :         uint8_t  *buf;
      50                 :            : };
      51                 :            : 
      52                 :            : struct sw_accel_io_channel {
      53                 :            :         /* for ISAL */
      54                 :            : #ifdef SPDK_CONFIG_ISAL
      55                 :            :         struct isal_zstream             stream;
      56                 :            :         struct inflate_state            state;
      57                 :            :         /* The array index corresponds to the algorithm level */
      58                 :            :         struct comp_deflate_level_buf   deflate_level_bufs[COMP_DEFLATE_LEVEL_NUM];
      59                 :            :         uint8_t                         level_buf_mem[ISAL_DEF_LVL0_DEFAULT + ISAL_DEF_LVL1_DEFAULT +
      60                 :            :                                               ISAL_DEF_LVL2_DEFAULT + ISAL_DEF_LVL3_DEFAULT];
      61                 :            : #endif
      62                 :            : #ifdef SPDK_CONFIG_HAVE_LZ4
      63                 :            :         /* for lz4 */
      64                 :            :         LZ4_stream_t                    *lz4_stream;
      65                 :            :         LZ4_streamDecode_t              *lz4_stream_decode;
      66                 :            : #endif
      67                 :            :         struct spdk_poller              *completion_poller;
      68                 :            :         STAILQ_HEAD(, spdk_accel_task)  tasks_to_complete;
      69                 :            : };
      70                 :            : 
      71                 :            : typedef int (*sw_accel_crypto_op)(const uint8_t *k2, const uint8_t *k1,
      72                 :            :                                   const uint8_t *initial_tweak, const uint64_t len_bytes,
      73                 :            :                                   const void *in, void *out);
      74                 :            : 
      75                 :            : struct sw_accel_crypto_key_data {
      76                 :            :         sw_accel_crypto_op encrypt;
      77                 :            :         sw_accel_crypto_op decrypt;
      78                 :            : };
      79                 :            : 
      80                 :            : static struct spdk_accel_module_if g_sw_module;
      81                 :            : 
      82                 :            : static void sw_accel_crypto_key_deinit(struct spdk_accel_crypto_key *_key);
      83                 :            : static int sw_accel_crypto_key_init(struct spdk_accel_crypto_key *key);
      84                 :            : static bool sw_accel_crypto_supports_tweak_mode(enum spdk_accel_crypto_tweak_mode tweak_mode);
      85                 :            : static bool sw_accel_crypto_supports_cipher(enum spdk_accel_cipher cipher, size_t key_size);
      86                 :            : 
      87                 :            : /* Post SW completions to a list; processed by ->completion_poller. */
      88                 :            : inline static void
      89                 :  130659461 : _add_to_comp_list(struct sw_accel_io_channel *sw_ch, struct spdk_accel_task *accel_task, int status)
      90                 :            : {
      91   [ +  -  +  - ]:  130659461 :         accel_task->status = status;
      92   [ +  -  +  -  :  130659461 :         STAILQ_INSERT_TAIL(&sw_ch->tasks_to_complete, accel_task, link);
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  +  
                      - ]
      93                 :  130659461 : }
      94                 :            : 
      95                 :            : static bool
      96                 :      36366 : sw_accel_supports_opcode(enum spdk_accel_opcode opc)
      97                 :            : {
      98         [ +  + ]:      36366 :         switch (opc) {
      99                 :      34734 :         case SPDK_ACCEL_OPC_COPY:
     100                 :            :         case SPDK_ACCEL_OPC_FILL:
     101                 :            :         case SPDK_ACCEL_OPC_DUALCAST:
     102                 :            :         case SPDK_ACCEL_OPC_COMPARE:
     103                 :            :         case SPDK_ACCEL_OPC_CRC32C:
     104                 :            :         case SPDK_ACCEL_OPC_COPY_CRC32C:
     105                 :            :         case SPDK_ACCEL_OPC_COMPRESS:
     106                 :            :         case SPDK_ACCEL_OPC_DECOMPRESS:
     107                 :            :         case SPDK_ACCEL_OPC_ENCRYPT:
     108                 :            :         case SPDK_ACCEL_OPC_DECRYPT:
     109                 :            :         case SPDK_ACCEL_OPC_XOR:
     110                 :            :         case SPDK_ACCEL_OPC_DIF_VERIFY:
     111                 :            :         case SPDK_ACCEL_OPC_DIF_GENERATE:
     112                 :            :         case SPDK_ACCEL_OPC_DIF_GENERATE_COPY:
     113                 :            :         case SPDK_ACCEL_OPC_DIF_VERIFY_COPY:
     114                 :            :         case SPDK_ACCEL_OPC_DIX_GENERATE:
     115                 :            :         case SPDK_ACCEL_OPC_DIX_VERIFY:
     116                 :      36366 :                 return true;
     117                 :          0 :         default:
     118                 :          0 :                 return false;
     119                 :            :         }
     120                 :       1632 : }
     121                 :            : 
     122                 :            : static int
     123                 :    1055492 : _sw_accel_dualcast_iovs(struct iovec *dst_iovs, uint32_t dst_iovcnt,
     124                 :            :                         struct iovec *dst2_iovs, uint32_t dst2_iovcnt,
     125                 :            :                         struct iovec *src_iovs, uint32_t src_iovcnt)
     126                 :            : {
     127   [ +  -  -  +  :    1055492 :         if (spdk_unlikely(dst_iovcnt != 1 || dst2_iovcnt != 1 || src_iovcnt != 1)) {
             +  +  -  + ]
     128                 :          0 :                 return -EINVAL;
     129                 :            :         }
     130                 :            : 
     131   [ +  +  +  +  :    1055492 :         if (spdk_unlikely(dst_iovs[0].iov_len != src_iovs[0].iov_len ||
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     132                 :            :                           dst_iovs[0].iov_len != dst2_iovs[0].iov_len)) {
     133                 :          0 :                 return -EINVAL;
     134                 :            :         }
     135                 :            : 
     136   [ -  +  -  +  :    1055492 :         memcpy(dst_iovs[0].iov_base, src_iovs[0].iov_base, dst_iovs[0].iov_len);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     137   [ -  +  -  +  :    1055492 :         memcpy(dst2_iovs[0].iov_base, src_iovs[0].iov_base, dst_iovs[0].iov_len);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     138                 :            : 
     139                 :    1055492 :         return 0;
     140                 :          1 : }
     141                 :            : 
     142                 :            : static void
     143                 :   98470038 : _sw_accel_copy_iovs(struct iovec *dst_iovs, uint32_t dst_iovcnt,
     144                 :            :                     struct iovec *src_iovs, uint32_t src_iovcnt)
     145                 :            : {
     146                 :   39260476 :         struct spdk_ioviter iter;
     147                 :   39260476 :         void *src, *dst;
     148                 :            :         size_t len;
     149                 :            : 
     150         [ +  + ]:  157880060 :         for (len = spdk_ioviter_first(&iter, src_iovs, src_iovcnt,
     151                 :   29508490 :                                       dst_iovs, dst_iovcnt, &src, &dst);
     152         [ +  + ]:  204810757 :              len != 0;
     153                 :  106340719 :              len = spdk_ioviter_next(&iter, &src, &dst)) {
     154   [ -  +  -  + ]:  106340719 :                 memcpy(dst, src, len);
     155                 :   29901532 :         }
     156                 :   98470038 : }
     157                 :            : 
     158                 :            : static int
     159                 :    1307556 : _sw_accel_compare(struct iovec *src_iovs, uint32_t src_iovcnt,
     160                 :            :                   struct iovec *src2_iovs, uint32_t src2_iovcnt)
     161                 :            : {
     162   [ +  +  -  + ]:    1307556 :         if (spdk_unlikely(src_iovcnt != 1 || src2_iovcnt != 1)) {
     163                 :          0 :                 return -EINVAL;
     164                 :            :         }
     165                 :            : 
     166   [ +  +  #  #  :    1307556 :         if (spdk_unlikely(src_iovs[0].iov_len != src2_iovs[0].iov_len)) {
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     167                 :          0 :                 return -EINVAL;
     168                 :            :         }
     169                 :            : 
     170   [ -  +  -  +  :    1307556 :         return memcmp(src_iovs[0].iov_base, src2_iovs[0].iov_base, src_iovs[0].iov_len);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     171                 :          1 : }
     172                 :            : 
     173                 :            : static int
     174                 :   16503734 : _sw_accel_fill(struct iovec *iovs, uint32_t iovcnt, uint8_t fill)
     175                 :            : {
     176                 :            :         void *dst;
     177                 :            :         size_t nbytes;
     178                 :            : 
     179         [ -  + ]:   16503734 :         if (spdk_unlikely(iovcnt != 1)) {
     180                 :          0 :                 return -EINVAL;
     181                 :            :         }
     182                 :            : 
     183   [ #  #  #  #  :   16503734 :         dst = iovs[0].iov_base;
                   #  # ]
     184   [ #  #  #  #  :   16503734 :         nbytes = iovs[0].iov_len;
                   #  # ]
     185                 :            : 
     186         [ -  + ]:   16503734 :         memset(dst, fill, nbytes);
     187                 :            : 
     188                 :   16503734 :         return 0;
     189                 :    5081446 : }
     190                 :            : 
     191                 :            : static void
     192                 :    5666780 : _sw_accel_crc32cv(uint32_t *crc_dst, struct iovec *iov, uint32_t iovcnt, uint32_t seed)
     193                 :            : {
     194         [ #  # ]:    5666780 :         *crc_dst = spdk_crc32c_iov_update(iov, iovcnt, ~seed);
     195                 :    5666780 : }
     196                 :            : 
     197                 :            : static int
     198                 :          0 : _sw_accel_compress_lz4(struct sw_accel_io_channel *sw_ch, struct spdk_accel_task *accel_task)
     199                 :            : {
     200                 :            : #ifdef SPDK_CONFIG_HAVE_LZ4
     201                 :          0 :         LZ4_stream_t *stream = sw_ch->lz4_stream;
     202                 :          0 :         struct iovec *siov = accel_task->s.iovs;
     203                 :          0 :         struct iovec *diov = accel_task->d.iovs;
     204                 :          0 :         size_t dst_segoffset = 0;
     205                 :          0 :         int32_t comp_size = 0;
     206                 :          0 :         uint32_t output_size = 0;
     207                 :          0 :         uint32_t i, d = 0;
     208                 :          0 :         int rc = 0;
     209                 :            : 
     210                 :          0 :         LZ4_resetStream(stream);
     211         [ #  # ]:          0 :         for (i = 0; i < accel_task->s.iovcnt; i++) {
     212         [ #  # ]:          0 :                 if ((diov[d].iov_len - dst_segoffset) == 0) {
     213         [ #  # ]:          0 :                         if (++d < accel_task->d.iovcnt) {
     214                 :          0 :                                 dst_segoffset = 0;
     215                 :          0 :                         } else {
     216                 :          0 :                                 SPDK_ERRLOG("Not enough destination buffer provided.\n");
     217                 :          0 :                                 rc = -ENOMEM;
     218                 :          0 :                                 break;
     219                 :            :                         }
     220                 :          0 :                 }
     221                 :            : 
     222                 :          0 :                 comp_size = LZ4_compress_fast_continue(stream, siov[i].iov_base, diov[d].iov_base + dst_segoffset,
     223                 :          0 :                                                        siov[i].iov_len, diov[d].iov_len - dst_segoffset,
     224                 :          0 :                                                        accel_task->comp.level);
     225         [ #  # ]:          0 :                 if (comp_size <= 0) {
     226                 :          0 :                         SPDK_ERRLOG("LZ4_compress_fast_continue was incorrectly executed.\n");
     227                 :          0 :                         rc = -EIO;
     228                 :          0 :                         break;
     229                 :            :                 }
     230                 :            : 
     231                 :          0 :                 dst_segoffset += comp_size;
     232                 :          0 :                 output_size += comp_size;
     233                 :          0 :         }
     234                 :            : 
     235                 :            :         /* Get our total output size */
     236         [ #  # ]:          0 :         if (accel_task->output_size != NULL) {
     237                 :          0 :                 *accel_task->output_size = output_size;
     238                 :          0 :         }
     239                 :            : 
     240                 :          0 :         return rc;
     241                 :            : #else
     242                 :          0 :         SPDK_ERRLOG("LZ4 library is required to use software compression.\n");
     243                 :          0 :         return -EINVAL;
     244                 :            : #endif
     245                 :            : }
     246                 :            : 
     247                 :            : static int
     248                 :          0 : _sw_accel_decompress_lz4(struct sw_accel_io_channel *sw_ch, struct spdk_accel_task *accel_task)
     249                 :            : {
     250                 :            : #ifdef SPDK_CONFIG_HAVE_LZ4
     251                 :          0 :         LZ4_streamDecode_t *stream = sw_ch->lz4_stream_decode;
     252                 :          0 :         struct iovec *siov = accel_task->s.iovs;
     253                 :          0 :         struct iovec *diov = accel_task->d.iovs;
     254                 :          0 :         size_t dst_segoffset = 0;
     255                 :          0 :         int32_t decomp_size = 0;
     256                 :          0 :         uint32_t output_size = 0;
     257                 :          0 :         uint32_t i, d = 0;
     258                 :          0 :         int rc = 0;
     259                 :            : 
     260                 :          0 :         LZ4_setStreamDecode(stream, NULL, 0);
     261         [ #  # ]:          0 :         for (i = 0; i < accel_task->s.iovcnt; ++i) {
     262         [ #  # ]:          0 :                 if ((diov[d].iov_len - dst_segoffset) == 0) {
     263         [ #  # ]:          0 :                         if (++d < accel_task->d.iovcnt) {
     264                 :          0 :                                 dst_segoffset = 0;
     265                 :          0 :                         } else {
     266                 :          0 :                                 SPDK_ERRLOG("Not enough destination buffer provided.\n");
     267                 :          0 :                                 rc = -ENOMEM;
     268                 :          0 :                                 break;
     269                 :            :                         }
     270                 :          0 :                 }
     271                 :          0 :                 decomp_size = LZ4_decompress_safe_continue(stream, siov[i].iov_base,
     272                 :          0 :                                 diov[d].iov_base + dst_segoffset, siov[i].iov_len,
     273                 :          0 :                                 diov[d].iov_len - dst_segoffset);
     274         [ #  # ]:          0 :                 if (decomp_size < 0) {
     275                 :          0 :                         SPDK_ERRLOG("LZ4_compress_fast_continue was incorrectly executed.\n");
     276                 :          0 :                         rc = -EIO;
     277                 :          0 :                         break;
     278                 :            :                 }
     279                 :          0 :                 dst_segoffset += decomp_size;
     280                 :          0 :                 output_size += decomp_size;
     281                 :          0 :         }
     282                 :            : 
     283                 :            :         /* Get our total output size */
     284         [ #  # ]:          0 :         if (accel_task->output_size != NULL) {
     285                 :          0 :                 *accel_task->output_size = output_size;
     286                 :          0 :         }
     287                 :            : 
     288                 :          0 :         return rc;
     289                 :            : #else
     290                 :          0 :         SPDK_ERRLOG("LZ4 library is required to use software compression.\n");
     291                 :          0 :         return -EINVAL;
     292                 :            : #endif
     293                 :            : }
     294                 :            : 
     295                 :            : static int
     296                 :     309782 : _sw_accel_compress_deflate(struct sw_accel_io_channel *sw_ch, struct spdk_accel_task *accel_task)
     297                 :            : {
     298                 :            : #ifdef SPDK_CONFIG_ISAL
     299   [ #  #  #  #  :     309782 :         size_t last_seglen = accel_task->s.iovs[accel_task->s.iovcnt - 1].iov_len;
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     300   [ #  #  #  #  :     309782 :         struct iovec *siov = accel_task->s.iovs;
             #  #  #  # ]
     301   [ #  #  #  #  :     309782 :         struct iovec *diov = accel_task->d.iovs;
             #  #  #  # ]
     302                 :            :         size_t remaining;
     303                 :     309782 :         uint32_t i, s = 0, d = 0;
     304                 :     309782 :         int rc = 0;
     305                 :            : 
     306   [ -  +  #  #  :     309782 :         if (accel_task->comp.level > COMP_DEFLATE_MAX_LEVEL) {
          #  #  #  #  #  
                      # ]
     307   [ #  #  #  #  :          0 :                 SPDK_ERRLOG("isal_deflate doesn't support this algorithm level(%u)\n", accel_task->comp.level);
             #  #  #  # ]
     308                 :          0 :                 return -EINVAL;
     309                 :            :         }
     310                 :            : 
     311                 :     309782 :         remaining = 0;
     312   [ +  +  #  #  :     619564 :         for (i = 0; i < accel_task->s.iovcnt; ++i) {
          #  #  #  #  #  
                      # ]
     313   [ #  #  #  #  :     309782 :                 remaining += accel_task->s.iovs[i].iov_len;
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     314                 :          2 :         }
     315                 :            : 
     316         [ #  # ]:     309782 :         isal_deflate_reset(&sw_ch->stream);
     317   [ #  #  #  #  :     309782 :         sw_ch->stream.end_of_stream = 0;
                   #  # ]
     318   [ #  #  #  #  :     309782 :         sw_ch->stream.next_out = diov[d].iov_base;
          #  #  #  #  #  
                #  #  # ]
     319   [ #  #  #  #  :     309782 :         sw_ch->stream.avail_out = diov[d].iov_len;
          #  #  #  #  #  
                #  #  # ]
     320   [ #  #  #  #  :     309782 :         sw_ch->stream.next_in = siov[s].iov_base;
          #  #  #  #  #  
                #  #  # ]
     321   [ #  #  #  #  :     309782 :         sw_ch->stream.avail_in = siov[s].iov_len;
          #  #  #  #  #  
                #  #  # ]
     322   [ #  #  #  #  :     309782 :         sw_ch->stream.level = accel_task->comp.level;
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     323   [ #  #  #  #  :     309782 :         sw_ch->stream.level_buf = sw_ch->deflate_level_bufs[accel_task->comp.level].buf;
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     324   [ #  #  #  #  :     309782 :         sw_ch->stream.level_buf_size = sw_ch->deflate_level_bufs[accel_task->comp.level].size;
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     325                 :            : 
     326                 :          2 :         do {
     327                 :            :                 /* if isal has exhausted the current dst iovec, move to the next
     328                 :            :                  * one if there is one */
     329   [ +  +  #  #  :     309782 :                 if (sw_ch->stream.avail_out == 0) {
             #  #  #  # ]
     330   [ #  #  #  #  :          0 :                         if (++d < accel_task->d.iovcnt) {
          #  #  #  #  #  
                      # ]
     331   [ #  #  #  #  :          0 :                                 sw_ch->stream.next_out = diov[d].iov_base;
          #  #  #  #  #  
                #  #  # ]
     332   [ #  #  #  #  :          0 :                                 sw_ch->stream.avail_out = diov[d].iov_len;
          #  #  #  #  #  
                #  #  # ]
     333   [ #  #  #  #  :          0 :                                 assert(sw_ch->stream.avail_out > 0);
          #  #  #  #  #  
                      # ]
     334                 :          0 :                         } else {
     335                 :            :                                 /* we have no avail_out but also no more iovecs left so this is
     336                 :            :                                 * the case where either the output buffer was a perfect fit
     337                 :            :                                 * or not enough was provided.  Check the ISAL state to determine
     338                 :            :                                 * which. */
     339   [ #  #  #  #  :          0 :                                 if (sw_ch->stream.internal_state.state != ZSTATE_END) {
          #  #  #  #  #  
                      # ]
     340                 :          0 :                                         SPDK_ERRLOG("Not enough destination buffer provided.\n");
     341                 :          0 :                                         rc = -ENOMEM;
     342                 :          0 :                                 }
     343                 :          0 :                                 break;
     344                 :            :                         }
     345                 :          0 :                 }
     346                 :            : 
     347                 :            :                 /* if isal has exhausted the current src iovec, move to the next
     348                 :            :                  * one if there is one */
     349   [ -  +  -  -  :     309782 :                 if (sw_ch->stream.avail_in == 0 && ((s + 1) < accel_task->s.iovcnt)) {
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     350                 :          0 :                         s++;
     351   [ #  #  #  #  :          0 :                         sw_ch->stream.next_in = siov[s].iov_base;
          #  #  #  #  #  
                #  #  # ]
     352   [ #  #  #  #  :          0 :                         sw_ch->stream.avail_in = siov[s].iov_len;
          #  #  #  #  #  
                #  #  # ]
     353   [ #  #  #  #  :          0 :                         assert(sw_ch->stream.avail_in > 0);
          #  #  #  #  #  
                      # ]
     354                 :          0 :                 }
     355                 :            : 
     356         [ +  + ]:     309782 :                 if (remaining <= last_seglen) {
     357                 :            :                         /* Need to set end of stream on last block */
     358   [ #  #  #  #  :     309782 :                         sw_ch->stream.end_of_stream = 1;
                   #  # ]
     359                 :          2 :                 }
     360                 :            : 
     361         [ #  # ]:     309782 :                 rc = isal_deflate(&sw_ch->stream);
     362         [ +  + ]:     309782 :                 if (rc) {
     363                 :          0 :                         SPDK_ERRLOG("isal_deflate returned error %d.\n", rc);
     364                 :          0 :                 }
     365                 :            : 
     366         [ +  + ]:     309782 :                 if (remaining > 0) {
     367   [ +  +  #  #  :     309782 :                         assert(siov[s].iov_len > sw_ch->stream.avail_in);
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     368   [ #  #  #  #  :     309782 :                         remaining -= (siov[s].iov_len - sw_ch->stream.avail_in);
          #  #  #  #  #  
                #  #  # ]
     369                 :          2 :                 }
     370                 :            : 
     371   [ -  +  -  +  :     309782 :         } while (remaining > 0 || sw_ch->stream.avail_out == 0);
          #  #  #  #  #  
                      # ]
     372   [ +  +  #  #  :     309782 :         assert(sw_ch->stream.avail_in  == 0);
          #  #  #  #  #  
                      # ]
     373                 :            : 
     374                 :            :         /* Get our total output size */
     375   [ +  +  #  #  :     309782 :         if (accel_task->output_size != NULL) {
             #  #  #  # ]
     376   [ +  +  #  #  :     309782 :                 assert(sw_ch->stream.total_out > 0);
          #  #  #  #  #  
                      # ]
     377   [ #  #  #  #  :     309782 :                 *accel_task->output_size = sw_ch->stream.total_out;
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     378                 :          2 :         }
     379                 :            : 
     380                 :     309782 :         return rc;
     381                 :            : #else
     382                 :            :         SPDK_ERRLOG("ISAL option is required to use software compression.\n");
     383                 :            :         return -EINVAL;
     384                 :            : #endif
     385                 :          2 : }
     386                 :            : 
     387                 :            : static int
     388                 :    1385630 : _sw_accel_decompress_deflate(struct sw_accel_io_channel *sw_ch, struct spdk_accel_task *accel_task)
     389                 :            : {
     390                 :            : #ifdef SPDK_CONFIG_ISAL
     391   [ #  #  #  #  :    1385630 :         struct iovec *siov = accel_task->s.iovs;
             #  #  #  # ]
     392   [ #  #  #  #  :    1385630 :         struct iovec *diov = accel_task->d.iovs;
             #  #  #  # ]
     393                 :    1385630 :         uint32_t s = 0, d = 0;
     394                 :    1385630 :         int rc = 0;
     395                 :            : 
     396         [ #  # ]:    1385630 :         isal_inflate_reset(&sw_ch->state);
     397   [ #  #  #  #  :    1385630 :         sw_ch->state.next_out = diov[d].iov_base;
          #  #  #  #  #  
                #  #  # ]
     398   [ #  #  #  #  :    1385630 :         sw_ch->state.avail_out = diov[d].iov_len;
          #  #  #  #  #  
                #  #  # ]
     399   [ #  #  #  #  :    1385630 :         sw_ch->state.next_in = siov[s].iov_base;
          #  #  #  #  #  
                #  #  # ]
     400   [ #  #  #  #  :    1385630 :         sw_ch->state.avail_in = siov[s].iov_len;
          #  #  #  #  #  
                #  #  # ]
     401                 :            : 
     402                 :          7 :         do {
     403                 :            :                 /* if isal has exhausted the current dst iovec, move to the next
     404                 :            :                  * one if there is one */
     405   [ -  +  -  -  :    1385630 :                 if (sw_ch->state.avail_out == 0 && ((d + 1) < accel_task->d.iovcnt)) {
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     406                 :          0 :                         d++;
     407   [ #  #  #  #  :          0 :                         sw_ch->state.next_out = diov[d].iov_base;
          #  #  #  #  #  
                #  #  # ]
     408   [ #  #  #  #  :          0 :                         sw_ch->state.avail_out = diov[d].iov_len;
          #  #  #  #  #  
                #  #  # ]
     409   [ #  #  #  #  :          0 :                         assert(sw_ch->state.avail_out > 0);
          #  #  #  #  #  
                      # ]
     410                 :          0 :                 }
     411                 :            : 
     412                 :            :                 /* if isal has exhausted the current src iovec, move to the next
     413                 :            :                  * one if there is one */
     414   [ -  +  -  -  :    1385630 :                 if (sw_ch->state.avail_in == 0 && ((s + 1) < accel_task->s.iovcnt)) {
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     415                 :          0 :                         s++;
     416   [ #  #  #  #  :          0 :                         sw_ch->state.next_in = siov[s].iov_base;
          #  #  #  #  #  
                #  #  # ]
     417   [ #  #  #  #  :          0 :                         sw_ch->state.avail_in = siov[s].iov_len;
          #  #  #  #  #  
                #  #  # ]
     418   [ #  #  #  #  :          0 :                         assert(sw_ch->state.avail_in > 0);
          #  #  #  #  #  
                      # ]
     419                 :          0 :                 }
     420                 :            : 
     421         [ #  # ]:    1385630 :                 rc = isal_inflate(&sw_ch->state);
     422         [ -  + ]:    1385630 :                 if (rc) {
     423                 :          0 :                         SPDK_ERRLOG("isal_inflate returned error %d.\n", rc);
     424                 :          0 :                 }
     425                 :            : 
     426   [ -  +  #  #  :    1385630 :         } while (sw_ch->state.block_state < ISAL_BLOCK_FINISH);
             #  #  #  # ]
     427   [ +  +  #  #  :    1385630 :         assert(sw_ch->state.avail_in == 0);
          #  #  #  #  #  
                      # ]
     428                 :            : 
     429                 :            :         /* Get our total output size */
     430   [ +  +  #  #  :    1385630 :         if (accel_task->output_size != NULL) {
             #  #  #  # ]
     431   [ -  +  #  #  :     192866 :                 assert(sw_ch->state.total_out > 0);
          #  #  #  #  #  
                      # ]
     432   [ #  #  #  #  :     192866 :                 *accel_task->output_size = sw_ch->state.total_out;
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     433                 :          0 :         }
     434                 :            : 
     435                 :    1385630 :         return rc;
     436                 :            : #else
     437                 :            :         SPDK_ERRLOG("ISAL option is required to use software decompression.\n");
     438                 :            :         return -EINVAL;
     439                 :            : #endif
     440                 :            : }
     441                 :            : 
     442                 :            : static int
     443                 :     309782 : _sw_accel_compress(struct sw_accel_io_channel *sw_ch, struct spdk_accel_task *accel_task)
     444                 :            : {
     445   [ +  -  +  #  :     309782 :         switch (accel_task->comp.algo) {
          #  #  #  #  #  
                   #  # ]
     446                 :     309780 :         case SPDK_ACCEL_COMP_ALGO_DEFLATE:
     447                 :     309782 :                 return _sw_accel_compress_deflate(sw_ch, accel_task);
     448                 :          0 :         case SPDK_ACCEL_COMP_ALGO_LZ4:
     449                 :          0 :                 return _sw_accel_compress_lz4(sw_ch, accel_task);
     450                 :          0 :         default:
     451         [ #  # ]:          0 :                 assert(0);
     452                 :            :                 return -EINVAL;
     453                 :            :         }
     454                 :          2 : }
     455                 :            : 
     456                 :            : static int
     457                 :    1385630 : _sw_accel_decompress(struct sw_accel_io_channel *sw_ch, struct spdk_accel_task *accel_task)
     458                 :            : {
     459   [ +  -  +  #  :    1385630 :         switch (accel_task->comp.algo) {
          #  #  #  #  #  
                   #  # ]
     460                 :    1385623 :         case SPDK_ACCEL_COMP_ALGO_DEFLATE:
     461                 :    1385630 :                 return _sw_accel_decompress_deflate(sw_ch, accel_task);
     462                 :          0 :         case SPDK_ACCEL_COMP_ALGO_LZ4:
     463                 :          0 :                 return _sw_accel_decompress_lz4(sw_ch, accel_task);
     464                 :          0 :         default:
     465         [ #  # ]:          0 :                 assert(0);
     466                 :            :                 return -EINVAL;
     467                 :            :         }
     468                 :          7 : }
     469                 :            : 
     470                 :            : static int
     471                 :    2329473 : _sw_accel_crypto_operation(struct spdk_accel_task *accel_task, struct spdk_accel_crypto_key *key,
     472                 :            :                            sw_accel_crypto_op op)
     473                 :            : {
     474                 :            : #ifdef SPDK_CONFIG_ISAL_CRYPTO
     475                 :         15 :         uint64_t iv[2];
     476                 :            :         size_t remaining_len, dst_len;
     477                 :    2329473 :         uint64_t src_offset = 0, dst_offset = 0;
     478                 :    2329473 :         uint32_t src_iovpos = 0, dst_iovpos = 0, src_iovcnt, dst_iovcnt;
     479                 :    2329473 :         uint32_t i, block_size, crypto_len, crypto_accum_len = 0;
     480                 :            :         struct iovec *src_iov, *dst_iov;
     481                 :            :         uint8_t *src, *dst;
     482                 :            :         int rc;
     483                 :            : 
     484                 :            :         /* iv is 128 bits, since we are using logical block address (64 bits) as iv, fill first 8 bytes with zeroes */
     485   [ #  #  #  # ]:    2329473 :         iv[0] = 0;
     486   [ #  #  #  #  :    2329473 :         iv[1] = accel_task->iv;
          #  #  #  #  #  
                      # ]
     487   [ #  #  #  #  :    2329473 :         src_iov = accel_task->s.iovs;
             #  #  #  # ]
     488   [ #  #  #  #  :    2329473 :         src_iovcnt = accel_task->s.iovcnt;
             #  #  #  # ]
     489   [ +  -  #  #  :    2329473 :         if (accel_task->d.iovcnt) {
          #  #  #  #  #  
                      # ]
     490   [ #  #  #  #  :    2329473 :                 dst_iov = accel_task->d.iovs;
             #  #  #  # ]
     491   [ #  #  #  #  :    2329473 :                 dst_iovcnt = accel_task->d.iovcnt;
             #  #  #  # ]
     492                 :          5 :         } else {
     493                 :            :                 /* inplace operation */
     494   [ #  #  #  #  :          0 :                 dst_iov = accel_task->s.iovs;
             #  #  #  # ]
     495   [ #  #  #  #  :          0 :                 dst_iovcnt = accel_task->s.iovcnt;
             #  #  #  # ]
     496                 :            :         }
     497   [ #  #  #  #  :    2329473 :         block_size = accel_task->block_size;
                   #  # ]
     498                 :            : 
     499   [ +  -  +  -  :    2329473 :         if (!src_iovcnt || !dst_iovcnt || !block_size || !op) {
             +  -  -  + ]
     500                 :          0 :                 SPDK_ERRLOG("src_iovcnt %d, dst_iovcnt %d, block_size %d, op %p\n", src_iovcnt, dst_iovcnt,
     501                 :            :                             block_size, op);
     502                 :          0 :                 return -EINVAL;
     503                 :            :         }
     504                 :            : 
     505                 :    2329473 :         remaining_len = 0;
     506         [ +  + ]:    4659051 :         for (i = 0; i < src_iovcnt; i++) {
     507   [ #  #  #  #  :    2329578 :                 remaining_len += src_iov[i].iov_len;
                   #  # ]
     508                 :          5 :         }
     509                 :    2329473 :         dst_len = 0;
     510         [ +  + ]:    4659074 :         for (i = 0; i < dst_iovcnt; i++) {
     511   [ #  #  #  #  :    2329601 :                 dst_len += dst_iov[i].iov_len;
                   #  # ]
     512                 :          5 :         }
     513                 :            : 
     514   [ +  +  -  + ]:    2329473 :         if (spdk_unlikely(remaining_len != dst_len || !remaining_len)) {
     515                 :          0 :                 return -ERANGE;
     516                 :            :         }
     517   [ -  +  -  +  :    2329473 :         if (spdk_unlikely(remaining_len % accel_task->block_size != 0)) {
          #  #  #  #  #  
                      # ]
     518                 :          0 :                 return -EINVAL;
     519                 :            :         }
     520                 :            : 
     521         [ +  + ]:   10160393 :         while (remaining_len) {
     522   [ -  +  #  #  :   10160393 :                 crypto_len = spdk_min(block_size - crypto_accum_len, src_iov->iov_len - src_offset);
          #  #  #  #  #  
                      # ]
     523   [ -  +  #  #  :   10160393 :                 crypto_len = spdk_min(crypto_len, dst_iov->iov_len - dst_offset);
          #  #  #  #  #  
                      # ]
     524   [ #  #  #  #  :   10160393 :                 src = (uint8_t *)src_iov->iov_base + src_offset;
                   #  # ]
     525   [ #  #  #  #  :   10160393 :                 dst = (uint8_t *)dst_iov->iov_base + dst_offset;
                   #  # ]
     526                 :            : 
     527   [ #  #  #  #  :   10160393 :                 rc = op((uint8_t *)key->key2, (uint8_t *)key->key, (uint8_t *)iv, crypto_len, src, dst);
          #  #  #  #  #  
                #  #  # ]
     528         [ +  + ]:   10160393 :                 if (rc != ISAL_CRYPTO_ERR_NONE) {
     529                 :          0 :                         break;
     530                 :            :                 }
     531                 :            : 
     532                 :   10160393 :                 src_offset += crypto_len;
     533                 :   10160393 :                 dst_offset += crypto_len;
     534                 :   10160393 :                 crypto_accum_len += crypto_len;
     535                 :   10160393 :                 remaining_len -= crypto_len;
     536                 :            : 
     537         [ +  + ]:   10160393 :                 if (crypto_accum_len == block_size) {
     538                 :            :                         /* we can process part of logical block. Once the whole block is processed, increment iv */
     539                 :   10160393 :                         crypto_accum_len = 0;
     540   [ #  #  #  # ]:   10160393 :                         iv[1]++;
     541                 :          5 :                 }
     542   [ +  +  #  #  :   10160393 :                 if (src_offset == src_iov->iov_len) {
                   #  # ]
     543         [ #  # ]:    2329578 :                         src_iov++;
     544                 :    2329578 :                         src_iovpos++;
     545                 :    2329578 :                         src_offset = 0;
     546                 :          5 :                 }
     547         [ +  + ]:   10160393 :                 if (src_iovpos == src_iovcnt) {
     548                 :    2329473 :                         break;
     549                 :            :                 }
     550   [ +  +  #  #  :    7830920 :                 if (dst_offset == dst_iov->iov_len) {
                   #  # ]
     551         [ #  # ]:        128 :                         dst_iov++;
     552                 :        128 :                         dst_iovpos++;
     553                 :        128 :                         dst_offset = 0;
     554                 :          0 :                 }
     555         [ -  + ]:    7830920 :                 if (dst_iovpos == dst_iovcnt) {
     556                 :          0 :                         break;
     557                 :            :                 }
     558                 :            :         }
     559                 :            : 
     560         [ -  + ]:    2329473 :         if (remaining_len) {
     561                 :          0 :                 SPDK_ERRLOG("remaining len %zu\n", remaining_len);
     562                 :          0 :                 return -EINVAL;
     563                 :            :         }
     564                 :            : 
     565                 :    2329473 :         return 0;
     566                 :            : #else
     567                 :            :         return -ENOTSUP;
     568                 :            : #endif
     569                 :          5 : }
     570                 :            : 
     571                 :            : static int
     572                 :    1605854 : _sw_accel_encrypt(struct sw_accel_io_channel *sw_ch, struct spdk_accel_task *accel_task)
     573                 :            : {
     574                 :            :         struct spdk_accel_crypto_key *key;
     575                 :            :         struct sw_accel_crypto_key_data *key_data;
     576                 :            : 
     577   [ #  #  #  #  :    1605854 :         key = accel_task->crypto_key;
                   #  # ]
     578   [ +  +  -  +  :    1605854 :         if (spdk_unlikely(key->module_if != &g_sw_module || !key->priv)) {
          #  #  #  #  #  
                #  #  # ]
     579                 :          0 :                 return -EINVAL;
     580                 :            :         }
     581   [ +  +  #  #  :    1605854 :         if (spdk_unlikely(accel_task->block_size > ACCEL_AES_XTS_MAX_BLOCK_SIZE)) {
          #  #  #  #  #  
                #  #  # ]
     582   [ #  #  #  #  :          0 :                 SPDK_WARNLOG("Max block size for AES_XTS is limited to %u, current size %u\n",
          #  #  #  #  #  
                      # ]
     583                 :            :                              ACCEL_AES_XTS_MAX_BLOCK_SIZE, accel_task->block_size);
     584                 :          0 :                 return -ERANGE;
     585                 :            :         }
     586   [ #  #  #  # ]:    1605854 :         key_data = key->priv;
     587   [ #  #  #  # ]:    1605854 :         return _sw_accel_crypto_operation(accel_task, key, key_data->encrypt);
     588                 :          3 : }
     589                 :            : 
     590                 :            : static int
     591                 :     723619 : _sw_accel_decrypt(struct sw_accel_io_channel *sw_ch, struct spdk_accel_task *accel_task)
     592                 :            : {
     593                 :            :         struct spdk_accel_crypto_key *key;
     594                 :            :         struct sw_accel_crypto_key_data *key_data;
     595                 :            : 
     596   [ #  #  #  #  :     723619 :         key = accel_task->crypto_key;
                   #  # ]
     597   [ +  +  -  +  :     723619 :         if (spdk_unlikely(key->module_if != &g_sw_module || !key->priv)) {
          #  #  #  #  #  
                #  #  # ]
     598                 :          0 :                 return -EINVAL;
     599                 :            :         }
     600   [ +  +  #  #  :     723619 :         if (spdk_unlikely(accel_task->block_size > ACCEL_AES_XTS_MAX_BLOCK_SIZE)) {
          #  #  #  #  #  
                #  #  # ]
     601   [ #  #  #  #  :          0 :                 SPDK_WARNLOG("Max block size for AES_XTS is limited to %u, current size %u\n",
          #  #  #  #  #  
                      # ]
     602                 :            :                              ACCEL_AES_XTS_MAX_BLOCK_SIZE, accel_task->block_size);
     603                 :          0 :                 return -ERANGE;
     604                 :            :         }
     605   [ #  #  #  # ]:     723619 :         key_data = key->priv;
     606   [ #  #  #  # ]:     723619 :         return _sw_accel_crypto_operation(accel_task, key, key_data->decrypt);
     607                 :          2 : }
     608                 :            : 
     609                 :            : static int
     610                 :    1901346 : _sw_accel_xor(struct sw_accel_io_channel *sw_ch, struct spdk_accel_task *accel_task)
     611                 :            : {
     612   [ #  #  #  #  :    1901348 :         return spdk_xor_gen(accel_task->d.iovs[0].iov_base,
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     613   [ #  #  #  #  :          1 :                             accel_task->nsrcs.srcs,
             #  #  #  # ]
     614   [ #  #  #  #  :          1 :                             accel_task->nsrcs.cnt,
             #  #  #  # ]
     615   [ #  #  #  #  :    1901346 :                             accel_task->d.iovs[0].iov_len);
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     616                 :            : }
     617                 :            : 
     618                 :            : static int
     619                 :     289924 : _sw_accel_dif_verify(struct sw_accel_io_channel *sw_ch, struct spdk_accel_task *accel_task)
     620                 :            : {
     621   [ #  #  #  #  :     579848 :         return spdk_dif_verify(accel_task->s.iovs,
             #  #  #  # ]
     622   [ #  #  #  #  :     289924 :                                accel_task->s.iovcnt,
             #  #  #  # ]
     623   [ #  #  #  #  :          0 :                                accel_task->dif.num_blocks,
             #  #  #  # ]
     624   [ #  #  #  #  :          0 :                                accel_task->dif.ctx,
             #  #  #  # ]
     625   [ #  #  #  #  :          0 :                                accel_task->dif.err);
             #  #  #  # ]
     626                 :            : }
     627                 :            : 
     628                 :            : static int
     629                 :    1188344 : _sw_accel_dif_verify_copy(struct sw_accel_io_channel *sw_ch, struct spdk_accel_task *accel_task)
     630                 :            : {
     631   [ #  #  #  #  :    2770402 :         return spdk_dif_verify_copy(accel_task->d.iovs,
             #  #  #  # ]
     632   [ #  #  #  #  :    1188344 :                                     accel_task->d.iovcnt,
             #  #  #  # ]
     633   [ #  #  #  #  :     524985 :                                     accel_task->s.iovs,
             #  #  #  # ]
     634   [ #  #  #  #  :    1188344 :                                     accel_task->s.iovcnt,
             #  #  #  # ]
     635   [ #  #  #  #  :     524985 :                                     accel_task->dif.num_blocks,
             #  #  #  # ]
     636   [ #  #  #  #  :     524985 :                                     accel_task->dif.ctx,
             #  #  #  # ]
     637   [ #  #  #  #  :     524985 :                                     accel_task->dif.err);
             #  #  #  # ]
     638                 :            : }
     639                 :            : 
     640                 :            : static int
     641                 :     727008 : _sw_accel_dif_generate(struct sw_accel_io_channel *sw_ch, struct spdk_accel_task *accel_task)
     642                 :            : {
     643   [ #  #  #  #  :    1454016 :         return spdk_dif_generate(accel_task->s.iovs,
             #  #  #  # ]
     644   [ #  #  #  #  :     727008 :                                  accel_task->s.iovcnt,
             #  #  #  # ]
     645   [ #  #  #  #  :          0 :                                  accel_task->dif.num_blocks,
             #  #  #  # ]
     646   [ #  #  #  #  :          0 :                                  accel_task->dif.ctx);
             #  #  #  # ]
     647                 :            : }
     648                 :            : 
     649                 :            : static int
     650                 :    1452509 : _sw_accel_dif_generate_copy(struct sw_accel_io_channel *sw_ch, struct spdk_accel_task *accel_task)
     651                 :            : {
     652   [ #  #  #  #  :    3562852 :         return spdk_dif_generate_copy(accel_task->s.iovs,
             #  #  #  # ]
     653   [ #  #  #  #  :    1452509 :                                       accel_task->s.iovcnt,
             #  #  #  # ]
     654   [ #  #  #  #  :     524672 :                                       accel_task->d.iovs,
             #  #  #  # ]
     655   [ #  #  #  #  :    1452509 :                                       accel_task->d.iovcnt,
             #  #  #  # ]
     656   [ #  #  #  #  :     524672 :                                       accel_task->dif.num_blocks,
             #  #  #  # ]
     657   [ #  #  #  #  :     524672 :                                       accel_task->dif.ctx);
             #  #  #  # ]
     658                 :            : }
     659                 :            : 
     660                 :            : static int
     661                 :         21 : _sw_accel_dix_generate(struct sw_accel_io_channel *sw_ch, struct spdk_accel_task *accel_task)
     662                 :            : {
     663   [ #  #  #  #  :         42 :         return spdk_dix_generate(accel_task->s.iovs,
             #  #  #  # ]
     664   [ #  #  #  #  :         21 :                                  accel_task->s.iovcnt,
             #  #  #  # ]
     665   [ #  #  #  #  :          3 :                                  accel_task->d.iovs,
             #  #  #  # ]
     666   [ #  #  #  #  :          3 :                                  accel_task->dif.num_blocks,
             #  #  #  # ]
     667   [ #  #  #  #  :          3 :                                  accel_task->dif.ctx);
             #  #  #  # ]
     668                 :            : }
     669                 :            : 
     670                 :            : static int
     671                 :     240319 : _sw_accel_dix_verify(struct sw_accel_io_channel *sw_ch, struct spdk_accel_task *accel_task)
     672                 :            : {
     673   [ #  #  #  #  :     480638 :         return spdk_dix_verify(accel_task->s.iovs,
             #  #  #  # ]
     674   [ #  #  #  #  :     240319 :                                accel_task->s.iovcnt,
             #  #  #  # ]
     675   [ #  #  #  #  :          3 :                                accel_task->d.iovs,
             #  #  #  # ]
     676   [ #  #  #  #  :          3 :                                accel_task->dif.num_blocks,
             #  #  #  # ]
     677   [ #  #  #  #  :          3 :                                accel_task->dif.ctx,
             #  #  #  # ]
     678   [ #  #  #  #  :          3 :                                accel_task->dif.err);
             #  #  #  # ]
     679                 :            : }
     680                 :            : 
     681                 :            : static int
     682                 :  768729634 : accel_comp_poll(void *arg)
     683                 :            : {
     684                 :  768729634 :         struct sw_accel_io_channel      *sw_ch = arg;
     685                 :  277144255 :         STAILQ_HEAD(, spdk_accel_task)  tasks_to_complete;
     686                 :            :         struct spdk_accel_task          *accel_task;
     687                 :            : 
     688   [ +  +  +  -  :  768729634 :         if (STAILQ_EMPTY(&sw_ch->tasks_to_complete)) {
             +  -  +  + ]
     689                 :  754914639 :                 return SPDK_POLLER_IDLE;
     690                 :            :         }
     691                 :            : 
     692         [ +  - ]:   13814995 :         STAILQ_INIT(&tasks_to_complete);
     693   [ +  +  +  +  :   13814995 :         STAILQ_SWAP(&tasks_to_complete, &sw_ch->tasks_to_complete, spdk_accel_task);
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          +  #  #  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     694                 :            : 
     695         [ +  + ]:  144065404 :         while ((accel_task = STAILQ_FIRST(&tasks_to_complete))) {
     696   [ +  +  +  -  :  130356517 :                 STAILQ_REMOVE_HEAD(&tasks_to_complete, link);
          +  -  +  +  +  
                      - ]
     697   [ +  -  +  - ]:  130356517 :                 spdk_accel_task_complete(accel_task, accel_task->status);
     698                 :            :         }
     699                 :            : 
     700                 :   13708887 :         return SPDK_POLLER_BUSY;
     701                 :   46544922 : }
     702                 :            : 
     703                 :            : static int
     704                 :  130966419 : sw_accel_submit_tasks(struct spdk_io_channel *ch, struct spdk_accel_task *accel_task)
     705                 :            : {
     706                 :  130966419 :         struct sw_accel_io_channel *sw_ch = spdk_io_channel_get_ctx(ch);
     707                 :            :         struct spdk_accel_task *tmp;
     708                 :  130966419 :         int rc = 0;
     709                 :            : 
     710                 :            :         /*
     711                 :            :          * Lazily initialize our completion poller. We don't want to complete
     712                 :            :          * them inline as they'll likely submit another.
     713                 :            :          */
     714   [ +  +  +  -  :  130966419 :         if (spdk_unlikely(sw_ch->completion_poller == NULL)) {
                   +  + ]
     715   [ +  -  +  - ]:       3863 :                 sw_ch->completion_poller = SPDK_POLLER_REGISTER(accel_comp_poll, sw_ch, 0);
     716                 :        323 :         }
     717                 :            : 
     718                 :   35053643 :         do {
     719   [ +  +  +  +  :  131606841 :                 switch (accel_task->op_code) {
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  -  
                -  -  - ]
     720                 :   67685993 :                 case SPDK_ACCEL_OPC_COPY:
     721   [ +  -  +  -  :  126773995 :                         _sw_accel_copy_iovs(accel_task->d.iovs, accel_task->d.iovcnt,
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     722   [ +  -  +  -  :   29544001 :                                             accel_task->s.iovs, accel_task->s.iovcnt);
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     723                 :   97229994 :                         break;
     724                 :   11422288 :                 case SPDK_ACCEL_OPC_FILL:
     725   [ #  #  #  #  :   21622698 :                         rc = _sw_accel_fill(accel_task->d.iovs, accel_task->d.iovcnt,
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     726   [ #  #  #  #  :   16522493 :                                             accel_task->fill_pattern);
                   #  # ]
     727                 :   16522493 :                         break;
     728                 :    1055491 :                 case SPDK_ACCEL_OPC_DUALCAST:
     729   [ #  #  #  #  :    1055493 :                         rc = _sw_accel_dualcast_iovs(accel_task->d.iovs, accel_task->d.iovcnt,
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     730   [ #  #  #  #  :          1 :                                                      accel_task->d2.iovs, accel_task->d2.iovcnt,
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     731   [ #  #  #  #  :          1 :                                                      accel_task->s.iovs, accel_task->s.iovcnt);
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     732                 :    1055492 :                         break;
     733                 :    1307555 :                 case SPDK_ACCEL_OPC_COMPARE:
     734   [ #  #  #  #  :    1307557 :                         rc = _sw_accel_compare(accel_task->s.iovs, accel_task->s.iovcnt,
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     735   [ #  #  #  #  :          1 :                                                accel_task->s2.iovs, accel_task->s2.iovcnt);
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     736                 :    1307556 :                         break;
     737                 :    4391216 :                 case SPDK_ACCEL_OPC_CRC32C:
     738   [ #  #  #  #  :    4391224 :                         _sw_accel_crc32cv(accel_task->crc_dst, accel_task->s.iovs, accel_task->s.iovcnt, accel_task->seed);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     739                 :    4391224 :                         break;
     740                 :    1275555 :                 case SPDK_ACCEL_OPC_COPY_CRC32C:
     741   [ #  #  #  #  :    1275557 :                         _sw_accel_copy_iovs(accel_task->d.iovs, accel_task->d.iovcnt,
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     742   [ #  #  #  #  :          1 :                                             accel_task->s.iovs, accel_task->s.iovcnt);
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     743   [ #  #  #  #  :    1275557 :                         _sw_accel_crc32cv(accel_task->crc_dst, accel_task->s.iovs,
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     744   [ #  #  #  #  :          1 :                                           accel_task->s.iovcnt, accel_task->seed);
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     745                 :    1275556 :                         break;
     746                 :     309780 :                 case SPDK_ACCEL_OPC_COMPRESS:
     747                 :     309782 :                         rc = _sw_accel_compress(sw_ch, accel_task);
     748                 :     309782 :                         break;
     749                 :    1385623 :                 case SPDK_ACCEL_OPC_DECOMPRESS:
     750                 :    1385630 :                         rc = _sw_accel_decompress(sw_ch, accel_task);
     751                 :    1385630 :                         break;
     752                 :    1901345 :                 case SPDK_ACCEL_OPC_XOR:
     753                 :    1901346 :                         rc = _sw_accel_xor(sw_ch, accel_task);
     754                 :    1901346 :                         break;
     755                 :    1605851 :                 case SPDK_ACCEL_OPC_ENCRYPT:
     756                 :    1605854 :                         rc = _sw_accel_encrypt(sw_ch, accel_task);
     757                 :    1605854 :                         break;
     758                 :     723617 :                 case SPDK_ACCEL_OPC_DECRYPT:
     759                 :     723619 :                         rc = _sw_accel_decrypt(sw_ch, accel_task);
     760                 :     723619 :                         break;
     761                 :     289924 :                 case SPDK_ACCEL_OPC_DIF_VERIFY:
     762                 :     289924 :                         rc = _sw_accel_dif_verify(sw_ch, accel_task);
     763                 :     289924 :                         break;
     764                 :     663359 :                 case SPDK_ACCEL_OPC_DIF_VERIFY_COPY:
     765                 :    1188447 :                         rc = _sw_accel_dif_verify_copy(sw_ch, accel_task);
     766                 :    1188447 :                         break;
     767                 :     727008 :                 case SPDK_ACCEL_OPC_DIF_GENERATE:
     768                 :     727008 :                         rc = _sw_accel_dif_generate(sw_ch, accel_task);
     769                 :     727008 :                         break;
     770                 :     927837 :                 case SPDK_ACCEL_OPC_DIF_GENERATE_COPY:
     771                 :    1452576 :                         rc = _sw_accel_dif_generate_copy(sw_ch, accel_task);
     772                 :    1452576 :                         break;
     773                 :         18 :                 case SPDK_ACCEL_OPC_DIX_GENERATE:
     774                 :         21 :                         rc = _sw_accel_dix_generate(sw_ch, accel_task);
     775                 :         21 :                         break;
     776                 :     240316 :                 case SPDK_ACCEL_OPC_DIX_VERIFY:
     777                 :     240319 :                         rc = _sw_accel_dix_verify(sw_ch, accel_task);
     778                 :     240319 :                         break;
     779                 :          0 :                 default:
     780         [ #  # ]:          0 :                         assert(false);
     781                 :            :                         break;
     782                 :            :                 }
     783                 :            : 
     784   [ +  -  +  -  :  131606841 :                 tmp = STAILQ_NEXT(accel_task, link);
                   +  - ]
     785                 :            : 
     786                 :  131606841 :                 _add_to_comp_list(sw_ch, accel_task, rc);
     787                 :            : 
     788                 :  131606841 :                 accel_task = tmp;
     789         [ +  + ]:  131606841 :         } while (accel_task);
     790                 :            : 
     791                 :  130966419 :         return 0;
     792                 :            : }
     793                 :            : 
     794                 :            : static int
     795                 :       9161 : sw_accel_create_cb(void *io_device, void *ctx_buf)
     796                 :            : {
     797                 :       9161 :         struct sw_accel_io_channel *sw_ch = ctx_buf;
     798                 :            : #ifdef SPDK_CONFIG_ISAL
     799                 :            :         struct comp_deflate_level_buf *deflate_level_bufs;
     800                 :            :         int i;
     801                 :            : #endif
     802                 :            : 
     803   [ +  -  +  -  :       9161 :         STAILQ_INIT(&sw_ch->tasks_to_complete);
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     804   [ +  -  +  - ]:       9161 :         sw_ch->completion_poller = NULL;
     805                 :            : 
     806                 :            : #ifdef SPDK_CONFIG_HAVE_LZ4
     807                 :        306 :         sw_ch->lz4_stream = LZ4_createStream();
     808         [ +  - ]:        306 :         if (sw_ch->lz4_stream == NULL) {
     809                 :          0 :                 SPDK_ERRLOG("Failed to create the lz4 stream for compression\n");
     810                 :          0 :                 return -ENOMEM;
     811                 :            :         }
     812                 :        306 :         sw_ch->lz4_stream_decode = LZ4_createStreamDecode();
     813         [ +  - ]:        306 :         if (sw_ch->lz4_stream_decode == NULL) {
     814                 :          0 :                 SPDK_ERRLOG("Failed to create the lz4 stream for decompression\n");
     815                 :          0 :                 LZ4_freeStream(sw_ch->lz4_stream);
     816                 :          0 :                 return -ENOMEM;
     817                 :            :         }
     818                 :            : #endif
     819                 :            : #ifdef SPDK_CONFIG_ISAL
     820   [ +  -  +  -  :       9161 :         sw_ch->deflate_level_bufs[0].buf = sw_ch->level_buf_mem;
          +  -  +  -  +  
                -  +  - ]
     821         [ +  - ]:       9161 :         deflate_level_bufs = sw_ch->deflate_level_bufs;
     822   [ +  -  +  -  :       9161 :         deflate_level_bufs[0].size = ISAL_DEF_LVL0_DEFAULT;
                   +  - ]
     823   [ +  +  +  - ]:      36644 :         for (i = 1; i < COMP_DEFLATE_LEVEL_NUM; i++) {
     824   [ +  -  +  -  :      53283 :                 deflate_level_bufs[i].buf = deflate_level_bufs[i - 1].buf +
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     825   [ +  -  +  -  :      27483 :                                             deflate_level_bufs[i - 1].size;
             +  -  +  - ]
     826   [ +  +  +  + ]:      27483 :                 switch (i) {
     827                 :       8772 :                 case 1:
     828   [ +  -  +  -  :       9161 :                         deflate_level_bufs[i].size = ISAL_DEF_LVL1_DEFAULT;
                   +  - ]
     829                 :       9161 :                         break;
     830                 :       8772 :                 case 2:
     831   [ +  -  +  -  :       9161 :                         deflate_level_bufs[i].size = ISAL_DEF_LVL2_DEFAULT;
                   +  - ]
     832                 :       9161 :                         break;
     833                 :       8772 :                 case 3:
     834   [ +  -  +  -  :       9161 :                         deflate_level_bufs[i].size = ISAL_DEF_LVL3_DEFAULT;
                   +  - ]
     835                 :       9161 :                         break;
     836                 :          0 :                 default:
     837         [ #  # ]:          0 :                         assert(false);
     838                 :            :                 }
     839                 :       1167 :         }
     840                 :            : 
     841         [ +  - ]:       9161 :         isal_deflate_init(&sw_ch->stream);
     842   [ +  -  +  -  :       9161 :         sw_ch->stream.flush = NO_FLUSH;
                   +  - ]
     843         [ +  - ]:       9161 :         isal_inflate_init(&sw_ch->state);
     844                 :            : #endif
     845                 :            : 
     846                 :       9161 :         return 0;
     847                 :        306 : }
     848                 :            : 
     849                 :            : static void
     850                 :       9161 : sw_accel_destroy_cb(void *io_device, void *ctx_buf)
     851                 :            : {
     852                 :       9161 :         struct sw_accel_io_channel *sw_ch = ctx_buf;
     853                 :            : 
     854                 :            : #ifdef SPDK_CONFIG_HAVE_LZ4
     855                 :        306 :         LZ4_freeStream(sw_ch->lz4_stream);
     856                 :        306 :         LZ4_freeStreamDecode(sw_ch->lz4_stream_decode);
     857                 :            : #endif
     858         [ +  - ]:       9161 :         spdk_poller_unregister(&sw_ch->completion_poller);
     859                 :       9161 : }
     860                 :            : 
     861                 :            : static struct spdk_io_channel *
     862                 :     155189 : sw_accel_get_io_channel(void)
     863                 :            : {
     864                 :     155189 :         return spdk_get_io_channel(&g_sw_module);
     865                 :            : }
     866                 :            : 
     867                 :            : static size_t
     868                 :       4278 : sw_accel_module_get_ctx_size(void)
     869                 :            : {
     870                 :       4278 :         return sizeof(struct spdk_accel_task);
     871                 :            : }
     872                 :            : 
     873                 :            : static int
     874                 :       2139 : sw_accel_module_init(void)
     875                 :            : {
     876                 :       2139 :         spdk_io_device_register(&g_sw_module, sw_accel_create_cb, sw_accel_destroy_cb,
     877                 :            :                                 sizeof(struct sw_accel_io_channel), "sw_accel_module");
     878                 :            : 
     879                 :       2139 :         return 0;
     880                 :            : }
     881                 :            : 
     882                 :            : static void
     883                 :       2139 : sw_accel_module_fini(void *ctxt)
     884                 :            : {
     885                 :       2139 :         spdk_io_device_unregister(&g_sw_module, NULL);
     886                 :       2139 :         spdk_accel_module_finish();
     887                 :       2139 : }
     888                 :            : 
     889                 :            : static int
     890                 :         44 : sw_accel_create_aes_xts(struct spdk_accel_crypto_key *key)
     891                 :            : {
     892                 :            : #ifdef SPDK_CONFIG_ISAL_CRYPTO
     893                 :            :         struct sw_accel_crypto_key_data *key_data;
     894                 :            : 
     895                 :         44 :         key_data = calloc(1, sizeof(*key_data));
     896         [ +  + ]:         44 :         if (!key_data) {
     897                 :          0 :                 return -ENOMEM;
     898                 :            :         }
     899                 :            : 
     900   [ +  +  -  #  :         44 :         switch (key->key_size) {
                #  #  # ]
     901                 :         42 :         case SPDK_ACCEL_AES_XTS_128_KEY_SIZE:
     902   [ #  #  #  # ]:         44 :                 key_data->encrypt = isal_aes_xts_enc_128;
     903   [ #  #  #  # ]:         44 :                 key_data->decrypt = isal_aes_xts_dec_128;
     904                 :         44 :                 break;
     905                 :          0 :         case SPDK_ACCEL_AES_XTS_256_KEY_SIZE:
     906   [ #  #  #  # ]:          0 :                 key_data->encrypt = isal_aes_xts_enc_256;
     907   [ #  #  #  # ]:          0 :                 key_data->decrypt = isal_aes_xts_dec_256;
     908                 :          0 :                 break;
     909                 :          0 :         default:
     910         [ #  # ]:          0 :                 assert(0);
     911                 :            :                 free(key_data);
     912                 :            :                 return -EINVAL;
     913                 :            :         }
     914                 :            : 
     915   [ #  #  #  # ]:         44 :         key->priv = key_data;
     916                 :            : 
     917                 :         44 :         return 0;
     918                 :            : #else
     919                 :            :         return -ENOTSUP;
     920                 :            : #endif
     921                 :          2 : }
     922                 :            : 
     923                 :            : static int
     924                 :         44 : sw_accel_crypto_key_init(struct spdk_accel_crypto_key *key)
     925                 :            : {
     926                 :         44 :         return sw_accel_create_aes_xts(key);
     927                 :            : }
     928                 :            : 
     929                 :            : static void
     930                 :         44 : sw_accel_crypto_key_deinit(struct spdk_accel_crypto_key *key)
     931                 :            : {
     932   [ +  -  +  -  :         44 :         if (!key || key->module_if != &g_sw_module || !key->priv) {
          +  +  #  #  #  
             #  #  #  #  
                      # ]
     933                 :          0 :                 return;
     934                 :            :         }
     935                 :            : 
     936   [ #  #  #  # ]:         44 :         free(key->priv);
     937                 :          2 : }
     938                 :            : 
     939                 :            : static bool
     940                 :         44 : sw_accel_crypto_supports_tweak_mode(enum spdk_accel_crypto_tweak_mode tweak_mode)
     941                 :            : {
     942                 :         44 :         return tweak_mode == SPDK_ACCEL_CRYPTO_TWEAK_MODE_SIMPLE_LBA;
     943                 :            : }
     944                 :            : 
     945                 :            : static bool
     946                 :         44 : sw_accel_crypto_supports_cipher(enum spdk_accel_cipher cipher, size_t key_size)
     947                 :            : {
     948         [ +  - ]:         44 :         switch (cipher) {
     949                 :         42 :         case SPDK_ACCEL_CIPHER_AES_XTS:
     950   [ +  +  -  - ]:         44 :                 return key_size == SPDK_ACCEL_AES_XTS_128_KEY_SIZE || key_size == SPDK_ACCEL_AES_XTS_256_KEY_SIZE;
     951                 :          0 :         default:
     952                 :          0 :                 return false;
     953                 :            :         }
     954                 :          2 : }
     955                 :            : 
     956                 :            : static bool
     957                 :    1695420 : sw_accel_compress_supports_algo(enum spdk_accel_comp_algo algo)
     958                 :            : {
     959         [ +  + ]:    1695420 :         switch (algo) {
     960                 :    1695409 :         case SPDK_ACCEL_COMP_ALGO_DEFLATE:
     961                 :            : #ifdef SPDK_CONFIG_HAVE_LZ4
     962                 :            :         case SPDK_ACCEL_COMP_ALGO_LZ4:
     963                 :            : #endif
     964                 :    1695420 :                 return true;
     965                 :          0 :         default:
     966                 :          0 :                 return false;
     967                 :            :         }
     968                 :         11 : }
     969                 :            : 
     970                 :            : static int
     971                 :         10 : sw_accel_get_compress_level_range(enum spdk_accel_comp_algo algo,
     972                 :            :                                   uint32_t *min_level, uint32_t *max_level)
     973                 :            : {
     974      [ +  -  - ]:         10 :         switch (algo) {
     975                 :         10 :         case SPDK_ACCEL_COMP_ALGO_DEFLATE:
     976                 :            : #ifdef SPDK_CONFIG_ISAL
     977         [ #  # ]:         10 :                 *min_level = COMP_DEFLATE_MIN_LEVEL;
     978         [ #  # ]:         10 :                 *max_level = COMP_DEFLATE_MAX_LEVEL;
     979                 :         10 :                 return 0;
     980                 :            : #else
     981                 :            :                 SPDK_ERRLOG("ISAL option is required to use software compression.\n");
     982                 :            :                 return -EINVAL;
     983                 :            : #endif
     984                 :          0 :         case SPDK_ACCEL_COMP_ALGO_LZ4:
     985                 :            : #ifdef SPDK_CONFIG_HAVE_LZ4
     986                 :          0 :                 *min_level = 1;
     987                 :          0 :                 *max_level = 65537;
     988                 :          0 :                 return 0;
     989                 :            : #else
     990                 :          0 :                 SPDK_ERRLOG("LZ4 library is required to use software compression.\n");
     991                 :          0 :                 return -EINVAL;
     992                 :            : #endif
     993                 :          0 :         default:
     994                 :          0 :                 return -EINVAL;
     995                 :            :         }
     996                 :          0 : }
     997                 :            : 
     998                 :            : static int
     999                 :        216 : sw_accel_get_operation_info(enum spdk_accel_opcode opcode,
    1000                 :            :                             const struct spdk_accel_operation_exec_ctx *ctx,
    1001                 :            :                             struct spdk_accel_opcode_info *info)
    1002                 :            : {
    1003   [ #  #  #  # ]:        216 :         info->required_alignment = 0;
    1004                 :            : 
    1005                 :        216 :         return 0;
    1006                 :            : }
    1007                 :            : 
    1008                 :            : static struct spdk_accel_module_if g_sw_module = {
    1009                 :            :         .module_init                    = sw_accel_module_init,
    1010                 :            :         .module_fini                    = sw_accel_module_fini,
    1011                 :            :         .write_config_json              = NULL,
    1012                 :            :         .get_ctx_size                   = sw_accel_module_get_ctx_size,
    1013                 :            :         .name                           = "software",
    1014                 :            :         .priority                       = SPDK_ACCEL_SW_PRIORITY,
    1015                 :            :         .supports_opcode                = sw_accel_supports_opcode,
    1016                 :            :         .get_io_channel                 = sw_accel_get_io_channel,
    1017                 :            :         .submit_tasks                   = sw_accel_submit_tasks,
    1018                 :            :         .crypto_key_init                = sw_accel_crypto_key_init,
    1019                 :            :         .crypto_key_deinit              = sw_accel_crypto_key_deinit,
    1020                 :            :         .crypto_supports_tweak_mode     = sw_accel_crypto_supports_tweak_mode,
    1021                 :            :         .crypto_supports_cipher         = sw_accel_crypto_supports_cipher,
    1022                 :            :         .compress_supports_algo         = sw_accel_compress_supports_algo,
    1023                 :            :         .get_compress_level_range       = sw_accel_get_compress_level_range,
    1024                 :            :         .get_operation_info             = sw_accel_get_operation_info,
    1025                 :            : };
    1026                 :            : 
    1027                 :       2272 : SPDK_ACCEL_MODULE_REGISTER(sw, &g_sw_module)

Generated by: LCOV version 1.15