1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2018 Intel Corporation. 3 * Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. 4 * All rights reserved. 5 */ 6 7 #include "accel_dpdk_cryptodev.h" 8 9 #include "spdk/accel.h" 10 #include "spdk_internal/accel_module.h" 11 #include "spdk/env.h" 12 #include "spdk/likely.h" 13 #include "spdk/thread.h" 14 #include "spdk/util.h" 15 #include "spdk/log.h" 16 #include "spdk/json.h" 17 #include "spdk_internal/sgl.h" 18 19 #include <rte_bus_vdev.h> 20 #include <rte_crypto.h> 21 #include <rte_cryptodev.h> 22 #include <rte_mbuf_dyn.h> 23 24 /* The VF spread is the number of queue pairs between virtual functions, we use this to 25 * load balance the QAT device. 26 */ 27 #define ACCEL_DPDK_CRYPTODEV_QAT_VF_SPREAD 32 28 29 /* Max length in byte of a crypto operation */ 30 #define ACCEL_DPDK_CRYPTODEV_CRYPTO_MAX_IO (64 * 1024) 31 32 /* This controls how many ops will be dequeued from the crypto driver in one run 33 * of the poller. It is mainly a performance knob as it effectively determines how 34 * much work the poller has to do. However even that can vary between crypto drivers 35 * as the ACCEL_DPDK_CRYPTODEV_AESNI_MB driver for example does all the crypto work on dequeue whereas the 36 * QAT driver just dequeues what has been completed already. 37 */ 38 #define ACCEL_DPDK_CRYPTODEV_MAX_DEQUEUE_BURST_SIZE 64 39 40 /* When enqueueing, we need to supply the crypto driver with an array of pointers to 41 * operation structs. As each of these can be max 512B, we can adjust the ACCEL_DPDK_CRYPTODEV_CRYPTO_MAX_IO 42 * value in conjunction with the other defines to make sure we're not using crazy amounts 43 * of memory. All of these numbers can and probably should be adjusted based on the 44 * workload. By default we'll use the worst case (smallest) block size for the 45 * minimum number of array entries. As an example, a ACCEL_DPDK_CRYPTODEV_CRYPTO_MAX_IO size of 64K with 512B 46 * blocks would give us an enqueue array size of 128. 47 */ 48 #define ACCEL_DPDK_CRYPTODEV_MAX_ENQUEUE_ARRAY_SIZE (ACCEL_DPDK_CRYPTODEV_CRYPTO_MAX_IO / 512) 49 50 /* The number of MBUFS we need must be a power of two and to support other small IOs 51 * in addition to the limits mentioned above, we go to the next power of two. It is 52 * big number because it is one mempool for source and destination mbufs. It may 53 * need to be bigger to support multiple crypto drivers at once. 54 */ 55 #define ACCEL_DPDK_CRYPTODEV_NUM_MBUFS 32768 56 #define ACCEL_DPDK_CRYPTODEV_POOL_CACHE_SIZE 256 57 #define ACCEL_DPDK_CRYPTODEV_MAX_CRYPTO_VOLUMES 128 58 #define ACCEL_DPDK_CRYPTODEV_NUM_SESSIONS (2 * ACCEL_DPDK_CRYPTODEV_MAX_CRYPTO_VOLUMES) 59 #define ACCEL_DPDK_CRYPTODEV_SESS_MEMPOOL_CACHE_SIZE 0 60 61 /* This is the max number of IOs we can supply to any crypto device QP at one time. 62 * It can vary between drivers. 63 */ 64 #define ACCEL_DPDK_CRYPTODEV_QP_DESCRIPTORS 2048 65 66 /* At this moment DPDK descriptors allocation for mlx5 has some issues. We use 512 67 * as a compromise value between performance and the time spent for initialization. */ 68 #define ACCEL_DPDK_CRYPTODEV_QP_DESCRIPTORS_MLX5 512 69 70 #define ACCEL_DPDK_CRYPTODEV_AESNI_MB_NUM_QP 64 71 72 /* Common for suported devices. */ 73 #define ACCEL_DPDK_CRYPTODEV_DEFAULT_NUM_XFORMS 2 74 #define ACCEL_DPDK_CRYPTODEV_IV_OFFSET (sizeof(struct rte_crypto_op) + \ 75 sizeof(struct rte_crypto_sym_op) + \ 76 (ACCEL_DPDK_CRYPTODEV_DEFAULT_NUM_XFORMS * \ 77 sizeof(struct rte_crypto_sym_xform))) 78 #define ACCEL_DPDK_CRYPTODEV_IV_LENGTH 16 79 #define ACCEL_DPDK_CRYPTODEV_QUEUED_OP_OFFSET (ACCEL_DPDK_CRYPTODEV_IV_OFFSET + ACCEL_DPDK_CRYPTODEV_IV_LENGTH) 80 81 /* Driver names */ 82 #define ACCEL_DPDK_CRYPTODEV_AESNI_MB "crypto_aesni_mb" 83 #define ACCEL_DPDK_CRYPTODEV_QAT "crypto_qat" 84 #define ACCEL_DPDK_CRYPTODEV_QAT_ASYM "crypto_qat_asym" 85 #define ACCEL_DPDK_CRYPTODEV_MLX5 "mlx5_pci" 86 87 /* Supported ciphers */ 88 #define ACCEL_DPDK_CRYPTODEV_AES_CBC "AES_CBC" /* QAT and ACCEL_DPDK_CRYPTODEV_AESNI_MB */ 89 #define ACCEL_DPDK_CRYPTODEV_AES_XTS "AES_XTS" /* QAT and MLX5 */ 90 91 /* Specific to AES_CBC. */ 92 #define ACCEL_DPDK_CRYPTODEV_AES_CBC_KEY_LENGTH 16 93 #define ACCEL_DPDK_CRYPTODEV_AES_XTS_128_BLOCK_KEY_LENGTH 16 /* AES-XTS-128 block key size. */ 94 #define ACCEL_DPDK_CRYPTODEV_AES_XTS_256_BLOCK_KEY_LENGTH 32 /* AES-XTS-256 block key size. */ 95 #define ACCEL_DPDK_CRYPTODEV_AES_XTS_512_BLOCK_KEY_LENGTH 64 /* AES-XTS-512 block key size. */ 96 97 #define ACCEL_DPDK_CRYPTODEV_AES_XTS_TWEAK_KEY_LENGTH 16 /* XTS part key size is always 128 bit. */ 98 99 /* Used to store IO context in mbuf */ 100 static const struct rte_mbuf_dynfield rte_mbuf_dynfield_io_context = { 101 .name = "context_accel_dpdk_cryptodev", 102 .size = sizeof(uint64_t), 103 .align = __alignof__(uint64_t), 104 .flags = 0, 105 }; 106 107 struct accel_dpdk_cryptodev_device; 108 109 enum accel_dpdk_cryptodev_driver_type { 110 ACCEL_DPDK_CRYPTODEV_DRIVER_AESNI_MB = 0, 111 ACCEL_DPDK_CRYPTODEV_DRIVER_QAT, 112 ACCEL_DPDK_CRYPTODEV_DRIVER_MLX5_PCI, 113 ACCEL_DPDK_CRYPTODEV_DRIVER_LAST 114 }; 115 116 enum accel_dpdk_crypto_dev_cipher_type { 117 ACCEL_DPDK_CRYPTODEV_CIPHER_AES_CBC, 118 ACCEL_DPDK_CRYPTODEV_CIPHER_AES_XTS 119 }; 120 121 struct accel_dpdk_cryptodev_qp { 122 struct accel_dpdk_cryptodev_device *device; /* ptr to crypto device */ 123 uint32_t num_enqueued_ops; /* Used to decide whether to poll the qp or not */ 124 uint8_t qp; /* queue identifier */ 125 bool in_use; /* whether this node is in use or not */ 126 uint8_t index; /* used by QAT to load balance placement of qpairs */ 127 TAILQ_ENTRY(accel_dpdk_cryptodev_qp) link; 128 }; 129 130 struct accel_dpdk_cryptodev_device { 131 enum accel_dpdk_cryptodev_driver_type type; 132 struct rte_cryptodev_info cdev_info; /* includes DPDK device friendly name */ 133 uint32_t qp_desc_nr; /* max number of qp descriptors to be enqueued in burst */ 134 uint8_t cdev_id; /* identifier for the device */ 135 TAILQ_HEAD(, accel_dpdk_cryptodev_qp) qpairs; 136 TAILQ_ENTRY(accel_dpdk_cryptodev_device) link; 137 }; 138 139 struct accel_dpdk_cryptodev_key_handle { 140 struct accel_dpdk_cryptodev_device *device; 141 TAILQ_ENTRY(accel_dpdk_cryptodev_key_handle) link; 142 struct rte_cryptodev_sym_session *session_encrypt; /* encryption session for this key */ 143 struct rte_cryptodev_sym_session *session_decrypt; /* decryption session for this key */ 144 struct rte_crypto_sym_xform cipher_xform; /* crypto control struct for this key */ 145 }; 146 147 struct accel_dpdk_cryptodev_key_priv { 148 enum accel_dpdk_cryptodev_driver_type driver; 149 enum accel_dpdk_crypto_dev_cipher_type cipher; 150 char *xts_key; 151 TAILQ_HEAD(, accel_dpdk_cryptodev_key_handle) dev_keys; 152 }; 153 154 /* For queueing up crypto operations that we can't submit for some reason */ 155 struct accel_dpdk_cryptodev_queued_op { 156 struct accel_dpdk_cryptodev_qp *qp; 157 struct rte_crypto_op *crypto_op; 158 struct accel_dpdk_cryptodev_task *task; 159 TAILQ_ENTRY(accel_dpdk_cryptodev_queued_op) link; 160 }; 161 #define ACCEL_DPDK_CRYPTODEV_QUEUED_OP_LENGTH (sizeof(struct accel_dpdk_cryptodev_queued_op)) 162 163 /* The crypto channel struct. It is allocated and freed on my behalf by the io channel code. 164 * We store things in here that are needed on per thread basis like the base_channel for this thread, 165 * and the poller for this thread. 166 */ 167 struct accel_dpdk_cryptodev_io_channel { 168 /* completion poller */ 169 struct spdk_poller *poller; 170 /* Array of qpairs for each available device. The specific device will be selected depending on the crypto key */ 171 struct accel_dpdk_cryptodev_qp *device_qp[ACCEL_DPDK_CRYPTODEV_DRIVER_LAST]; 172 /* queued for re-submission to CryptoDev */ 173 TAILQ_HEAD(, accel_dpdk_cryptodev_queued_op) queued_cry_ops; 174 }; 175 176 struct accel_dpdk_cryptodev_task { 177 struct spdk_accel_task base; 178 uint32_t cryop_cnt_remaining; 179 bool is_failed; 180 TAILQ_ENTRY(accel_dpdk_cryptodev_task) link; 181 }; 182 183 /* Shared mempools between all devices on this system */ 184 static struct rte_mempool *g_session_mp = NULL; 185 static struct rte_mempool *g_session_mp_priv = NULL; 186 static struct rte_mempool *g_mbuf_mp = NULL; /* mbuf mempool */ 187 static int g_mbuf_offset; 188 static struct rte_mempool *g_crypto_op_mp = NULL; /* crypto operations, must be rte* mempool */ 189 190 static struct rte_mbuf_ext_shared_info g_shinfo = {}; /* used by DPDK mbuf macro */ 191 192 static uint8_t g_qat_total_qp = 0; 193 static uint8_t g_next_qat_index; 194 195 static const char *g_driver_names[] = { 196 [ACCEL_DPDK_CRYPTODEV_DRIVER_AESNI_MB] = ACCEL_DPDK_CRYPTODEV_AESNI_MB, 197 [ACCEL_DPDK_CRYPTODEV_DRIVER_QAT] = ACCEL_DPDK_CRYPTODEV_QAT, 198 [ACCEL_DPDK_CRYPTODEV_DRIVER_MLX5_PCI] = ACCEL_DPDK_CRYPTODEV_MLX5 199 }; 200 static const char *g_cipher_names[] = { 201 [ACCEL_DPDK_CRYPTODEV_CIPHER_AES_CBC] = ACCEL_DPDK_CRYPTODEV_AES_CBC, 202 [ACCEL_DPDK_CRYPTODEV_CIPHER_AES_XTS] = ACCEL_DPDK_CRYPTODEV_AES_XTS, 203 }; 204 205 static enum accel_dpdk_cryptodev_driver_type g_dpdk_cryptodev_driver = 206 ACCEL_DPDK_CRYPTODEV_DRIVER_AESNI_MB; 207 208 /* Global list of all crypto devices */ 209 static TAILQ_HEAD(, accel_dpdk_cryptodev_device) g_crypto_devices = TAILQ_HEAD_INITIALIZER( 210 g_crypto_devices); 211 static pthread_mutex_t g_device_lock = PTHREAD_MUTEX_INITIALIZER; 212 213 static struct spdk_accel_module_if g_accel_dpdk_cryptodev_module; 214 215 void 216 accel_dpdk_cryptodev_enable(void) 217 { 218 spdk_accel_module_list_add(&g_accel_dpdk_cryptodev_module); 219 } 220 221 int 222 accel_dpdk_cryptodev_set_driver(const char *driver_name) 223 { 224 if (strcmp(driver_name, ACCEL_DPDK_CRYPTODEV_QAT) == 0) { 225 g_dpdk_cryptodev_driver = ACCEL_DPDK_CRYPTODEV_DRIVER_QAT; 226 } else if (strcmp(driver_name, ACCEL_DPDK_CRYPTODEV_AESNI_MB) == 0) { 227 g_dpdk_cryptodev_driver = ACCEL_DPDK_CRYPTODEV_DRIVER_AESNI_MB; 228 } else if (strcmp(driver_name, ACCEL_DPDK_CRYPTODEV_MLX5) == 0) { 229 g_dpdk_cryptodev_driver = ACCEL_DPDK_CRYPTODEV_DRIVER_MLX5_PCI; 230 } else { 231 SPDK_ERRLOG("Unsupported driver %s\n", driver_name); 232 return -EINVAL; 233 } 234 235 SPDK_NOTICELOG("Using driver %s\n", driver_name); 236 237 return 0; 238 } 239 240 const char * 241 accel_dpdk_cryptodev_get_driver(void) 242 { 243 return g_driver_names[g_dpdk_cryptodev_driver]; 244 } 245 246 static void 247 cancel_queued_crypto_ops(struct accel_dpdk_cryptodev_io_channel *crypto_ch, 248 struct accel_dpdk_cryptodev_task *task) 249 { 250 struct rte_mbuf *mbufs_to_free[2 * ACCEL_DPDK_CRYPTODEV_MAX_DEQUEUE_BURST_SIZE]; 251 struct rte_crypto_op *cancelled_ops[ACCEL_DPDK_CRYPTODEV_MAX_DEQUEUE_BURST_SIZE]; 252 struct accel_dpdk_cryptodev_queued_op *op_to_cancel, *tmp_op; 253 struct rte_crypto_op *crypto_op; 254 int num_mbufs = 0, num_dequeued_ops = 0; 255 256 /* Remove all ops from the failed IO. Since we don't know the 257 * order we have to check them all. */ 258 TAILQ_FOREACH_SAFE(op_to_cancel, &crypto_ch->queued_cry_ops, link, tmp_op) { 259 /* Checking if this is our op. One IO contains multiple ops. */ 260 if (task == op_to_cancel->task) { 261 crypto_op = op_to_cancel->crypto_op; 262 TAILQ_REMOVE(&crypto_ch->queued_cry_ops, op_to_cancel, link); 263 264 /* Populating lists for freeing mbufs and ops. */ 265 mbufs_to_free[num_mbufs++] = (void *)crypto_op->sym->m_src; 266 if (crypto_op->sym->m_dst) { 267 mbufs_to_free[num_mbufs++] = (void *)crypto_op->sym->m_dst; 268 } 269 cancelled_ops[num_dequeued_ops++] = crypto_op; 270 } 271 } 272 273 /* Now bulk free both mbufs and crypto operations. */ 274 if (num_dequeued_ops > 0) { 275 rte_mempool_put_bulk(g_crypto_op_mp, (void **)cancelled_ops, 276 num_dequeued_ops); 277 assert(num_mbufs > 0); 278 /* This also releases chained mbufs if any. */ 279 rte_pktmbuf_free_bulk(mbufs_to_free, num_mbufs); 280 } 281 } 282 283 static inline uint16_t 284 accel_dpdk_cryptodev_poll_qp(struct accel_dpdk_cryptodev_qp *qp) 285 { 286 struct rte_crypto_op *dequeued_ops[ACCEL_DPDK_CRYPTODEV_MAX_DEQUEUE_BURST_SIZE]; 287 struct rte_mbuf *mbufs_to_free[2 * ACCEL_DPDK_CRYPTODEV_MAX_DEQUEUE_BURST_SIZE]; 288 struct accel_dpdk_cryptodev_task *task; 289 uint32_t num_mbufs = 0; 290 int i; 291 uint16_t num_dequeued_ops; 292 293 /* Each run of the poller will get just what the device has available 294 * at the moment we call it, we don't check again after draining the 295 * first batch. 296 */ 297 num_dequeued_ops = rte_cryptodev_dequeue_burst(qp->device->cdev_id, qp->qp, 298 dequeued_ops, ACCEL_DPDK_CRYPTODEV_MAX_DEQUEUE_BURST_SIZE); 299 /* Check if operation was processed successfully */ 300 for (i = 0; i < num_dequeued_ops; i++) { 301 302 /* We don't know the order or association of the crypto ops wrt any 303 * particular task so need to look at each and determine if it's 304 * the last one for it's task or not. 305 */ 306 task = (struct accel_dpdk_cryptodev_task *)*RTE_MBUF_DYNFIELD(dequeued_ops[i]->sym->m_src, 307 g_mbuf_offset, uint64_t *); 308 assert(task != NULL); 309 310 if (dequeued_ops[i]->status != RTE_CRYPTO_OP_STATUS_SUCCESS) { 311 SPDK_ERRLOG("error with op %d status %u\n", i, dequeued_ops[i]->status); 312 /* Update the task status to error, we'll still process the 313 * rest of the crypto ops for this task though so they 314 * aren't left hanging. 315 */ 316 task->is_failed = true; 317 } 318 319 /* Return the associated src and dst mbufs by collecting them into 320 * an array that we can use the bulk API to free after the loop. 321 */ 322 *RTE_MBUF_DYNFIELD(dequeued_ops[i]->sym->m_src, g_mbuf_offset, uint64_t *) = 0; 323 mbufs_to_free[num_mbufs++] = (void *)dequeued_ops[i]->sym->m_src; 324 if (dequeued_ops[i]->sym->m_dst) { 325 mbufs_to_free[num_mbufs++] = (void *)dequeued_ops[i]->sym->m_dst; 326 } 327 328 assert(task->cryop_cnt_remaining > 0); 329 /* done encrypting, complete the task */ 330 if (--task->cryop_cnt_remaining == 0) { 331 /* Complete the IO */ 332 spdk_accel_task_complete(&task->base, task->is_failed ? -EINVAL : 0); 333 } 334 } 335 336 /* Now bulk free both mbufs and crypto operations. */ 337 if (num_dequeued_ops > 0) { 338 rte_mempool_put_bulk(g_crypto_op_mp, (void **)dequeued_ops, num_dequeued_ops); 339 assert(num_mbufs > 0); 340 /* This also releases chained mbufs if any. */ 341 rte_pktmbuf_free_bulk(mbufs_to_free, num_mbufs); 342 } 343 344 assert(qp->num_enqueued_ops >= num_dequeued_ops); 345 qp->num_enqueued_ops -= num_dequeued_ops; 346 347 return num_dequeued_ops; 348 } 349 350 /* This is the poller for the crypto module. It uses a single API to dequeue whatever is ready at 351 * the device. Then we need to decide if what we've got so far (including previous poller 352 * runs) totals up to one or more complete task */ 353 static int 354 accel_dpdk_cryptodev_poller(void *args) 355 { 356 struct accel_dpdk_cryptodev_io_channel *crypto_ch = args; 357 struct accel_dpdk_cryptodev_qp *qp; 358 struct accel_dpdk_cryptodev_task *task; 359 struct accel_dpdk_cryptodev_queued_op *op_to_resubmit; 360 uint32_t num_dequeued_ops = 0, num_enqueued_ops = 0; 361 uint16_t enqueued; 362 int i; 363 364 for (i = 0; i < ACCEL_DPDK_CRYPTODEV_DRIVER_LAST; i++) { 365 qp = crypto_ch->device_qp[i]; 366 /* Avoid polling "idle" qps since it may affect performance */ 367 if (qp && qp->num_enqueued_ops) { 368 num_dequeued_ops += accel_dpdk_cryptodev_poll_qp(qp); 369 } 370 } 371 372 /* Check if there are any queued crypto ops to process */ 373 while (!TAILQ_EMPTY(&crypto_ch->queued_cry_ops)) { 374 op_to_resubmit = TAILQ_FIRST(&crypto_ch->queued_cry_ops); 375 task = op_to_resubmit->task; 376 qp = op_to_resubmit->qp; 377 enqueued = rte_cryptodev_enqueue_burst(qp->device->cdev_id, 378 qp->qp, 379 &op_to_resubmit->crypto_op, 380 1); 381 if (enqueued == 1) { 382 TAILQ_REMOVE(&crypto_ch->queued_cry_ops, op_to_resubmit, link); 383 qp->num_enqueued_ops++; 384 num_enqueued_ops++; 385 } else { 386 if (op_to_resubmit->crypto_op->status == RTE_CRYPTO_OP_STATUS_NOT_PROCESSED) { 387 /* If we couldn't get one, just break and try again later. */ 388 break; 389 } else { 390 /* Something is really wrong with the op. Most probably the 391 * mbuf is broken or the HW is not able to process the request. 392 * Fail the IO and remove its ops from the queued ops list. */ 393 task->is_failed = true; 394 395 cancel_queued_crypto_ops(crypto_ch, task); 396 397 /* Fail the IO if there is nothing left on device. */ 398 if (--task->cryop_cnt_remaining == 0) { 399 spdk_accel_task_complete(&task->base, -EFAULT); 400 } 401 } 402 } 403 } 404 405 return !!(num_dequeued_ops + num_enqueued_ops); 406 } 407 408 /* Allocate the new mbuf of @remainder size with data pointed by @addr and attach 409 * it to the @orig_mbuf. */ 410 static inline int 411 accel_dpdk_cryptodev_mbuf_chain_remainder(struct accel_dpdk_cryptodev_task *task, 412 struct rte_mbuf *orig_mbuf, uint8_t *addr, uint64_t *_remainder) 413 { 414 uint64_t phys_addr, phys_len, remainder = *_remainder; 415 struct rte_mbuf *chain_mbuf; 416 int rc; 417 418 phys_len = remainder; 419 phys_addr = spdk_vtophys((void *)addr, &phys_len); 420 if (spdk_unlikely(phys_addr == SPDK_VTOPHYS_ERROR)) { 421 return -EFAULT; 422 } 423 remainder = spdk_min(remainder, phys_len); 424 rc = rte_pktmbuf_alloc_bulk(g_mbuf_mp, (struct rte_mbuf **)&chain_mbuf, 1); 425 if (spdk_unlikely(rc)) { 426 return -ENOMEM; 427 } 428 /* Store context in every mbuf as we don't know anything about completion order */ 429 *RTE_MBUF_DYNFIELD(chain_mbuf, g_mbuf_offset, uint64_t *) = (uint64_t)task; 430 rte_pktmbuf_attach_extbuf(chain_mbuf, addr, phys_addr, remainder, &g_shinfo); 431 rte_pktmbuf_append(chain_mbuf, remainder); 432 433 /* Chained buffer is released by rte_pktbuf_free_bulk() automagicaly. */ 434 rte_pktmbuf_chain(orig_mbuf, chain_mbuf); 435 *_remainder = remainder; 436 437 return 0; 438 } 439 440 /* Attach data buffer pointed by @addr to @mbuf. Return utilized len of the 441 * contiguous space that was physically available. */ 442 static inline uint64_t 443 accel_dpdk_cryptodev_mbuf_attach_buf(struct accel_dpdk_cryptodev_task *task, struct rte_mbuf *mbuf, 444 uint8_t *addr, uint32_t len) 445 { 446 uint64_t phys_addr, phys_len; 447 448 /* Store context in every mbuf as we don't know anything about completion order */ 449 *RTE_MBUF_DYNFIELD(mbuf, g_mbuf_offset, uint64_t *) = (uint64_t)task; 450 451 phys_len = len; 452 phys_addr = spdk_vtophys((void *)addr, &phys_len); 453 if (spdk_unlikely(phys_addr == SPDK_VTOPHYS_ERROR || phys_len == 0)) { 454 return 0; 455 } 456 assert(phys_len <= len); 457 458 /* Set the mbuf elements address and length. */ 459 rte_pktmbuf_attach_extbuf(mbuf, addr, phys_addr, phys_len, &g_shinfo); 460 rte_pktmbuf_append(mbuf, phys_len); 461 462 return phys_len; 463 } 464 465 static inline struct accel_dpdk_cryptodev_key_handle * 466 accel_dpdk_find_key_handle_in_channel(struct accel_dpdk_cryptodev_io_channel *crypto_ch, 467 struct accel_dpdk_cryptodev_key_priv *key) 468 { 469 struct accel_dpdk_cryptodev_key_handle *key_handle; 470 471 if (key->driver == ACCEL_DPDK_CRYPTODEV_DRIVER_MLX5_PCI) { 472 /* Crypto key is registered on all available devices while io_channel opens CQ/QP on a single device. 473 * We need to iterate a list of key entries to find a suitable device */ 474 TAILQ_FOREACH(key_handle, &key->dev_keys, link) { 475 if (key_handle->device->cdev_id == 476 crypto_ch->device_qp[ACCEL_DPDK_CRYPTODEV_DRIVER_MLX5_PCI]->device->cdev_id) { 477 return key_handle; 478 } 479 } 480 return NULL; 481 } else { 482 return TAILQ_FIRST(&key->dev_keys); 483 } 484 } 485 486 static inline int 487 accel_dpdk_cryptodev_task_alloc_resources(struct rte_mbuf **src_mbufs, struct rte_mbuf **dst_mbufs, 488 struct rte_crypto_op **crypto_ops, int count) 489 { 490 int rc; 491 492 /* Get the number of source mbufs that we need. These will always be 1:1 because we 493 * don't support chaining. The reason we don't is because of our decision to use 494 * LBA as IV, there can be no case where we'd need >1 mbuf per crypto op or the 495 * op would be > 1 LBA. 496 */ 497 rc = rte_pktmbuf_alloc_bulk(g_mbuf_mp, src_mbufs, count); 498 if (rc) { 499 SPDK_ERRLOG("Failed to get src_mbufs!\n"); 500 return -ENOMEM; 501 } 502 503 /* Get the same amount to describe destination. If crypto operation is inline then we don't just skip it */ 504 if (dst_mbufs) { 505 rc = rte_pktmbuf_alloc_bulk(g_mbuf_mp, dst_mbufs, count); 506 if (rc) { 507 SPDK_ERRLOG("Failed to get dst_mbufs!\n"); 508 goto err_free_src; 509 } 510 } 511 512 #ifdef __clang_analyzer__ 513 /* silence scan-build false positive */ 514 SPDK_CLANG_ANALYZER_PREINIT_PTR_ARRAY(crypto_ops, ACCEL_DPDK_CRYPTODEV_MAX_ENQUEUE_ARRAY_SIZE, 515 0x1000); 516 #endif 517 /* Allocate crypto operations. */ 518 rc = rte_crypto_op_bulk_alloc(g_crypto_op_mp, 519 RTE_CRYPTO_OP_TYPE_SYMMETRIC, 520 crypto_ops, count); 521 if (rc < count) { 522 SPDK_ERRLOG("Failed to allocate crypto ops!\n"); 523 goto err_free_ops; 524 } 525 526 return 0; 527 528 err_free_ops: 529 if (rc > 0) { 530 rte_mempool_put_bulk(g_crypto_op_mp, (void **)crypto_ops, rc); 531 } 532 if (dst_mbufs) { 533 /* This also releases chained mbufs if any. */ 534 rte_pktmbuf_free_bulk(dst_mbufs, count); 535 } 536 err_free_src: 537 /* This also releases chained mbufs if any. */ 538 rte_pktmbuf_free_bulk(src_mbufs, count); 539 540 return -ENOMEM; 541 } 542 543 static inline int 544 accel_dpdk_cryptodev_mbuf_add_single_block(struct spdk_iov_sgl *sgl, struct rte_mbuf *mbuf, 545 struct accel_dpdk_cryptodev_task *task) 546 { 547 int rc; 548 uint8_t *buf_addr; 549 uint64_t phys_len; 550 uint64_t remainder; 551 uint64_t buf_len = spdk_min(task->base.block_size, sgl->iov->iov_len - sgl->iov_offset); 552 553 buf_addr = sgl->iov->iov_base + sgl->iov_offset; 554 phys_len = accel_dpdk_cryptodev_mbuf_attach_buf(task, mbuf, buf_addr, buf_len); 555 if (spdk_unlikely(phys_len == 0)) { 556 return -EFAULT; 557 } 558 buf_len = spdk_min(buf_len, phys_len); 559 spdk_iov_sgl_advance(sgl, buf_len); 560 561 /* Handle the case of page boundary. */ 562 remainder = task->base.block_size - buf_len; 563 while (remainder) { 564 buf_len = spdk_min(remainder, sgl->iov->iov_len - sgl->iov_offset); 565 buf_addr = sgl->iov->iov_base + sgl->iov_offset; 566 rc = accel_dpdk_cryptodev_mbuf_chain_remainder(task, mbuf, buf_addr, &buf_len); 567 if (spdk_unlikely(rc)) { 568 return rc; 569 } 570 spdk_iov_sgl_advance(sgl, buf_len); 571 remainder -= buf_len; 572 } 573 574 return 0; 575 } 576 577 static inline void 578 accel_dpdk_cryptodev_op_set_iv(struct rte_crypto_op *crypto_op, uint64_t iv) 579 { 580 uint8_t *iv_ptr = rte_crypto_op_ctod_offset(crypto_op, uint8_t *, ACCEL_DPDK_CRYPTODEV_IV_OFFSET); 581 582 /* Set the IV - we use the LBA of the crypto_op */ 583 memset(iv_ptr, 0, ACCEL_DPDK_CRYPTODEV_IV_LENGTH); 584 rte_memcpy(iv_ptr, &iv, sizeof(uint64_t)); 585 } 586 587 static int 588 accel_dpdk_cryptodev_process_task(struct accel_dpdk_cryptodev_io_channel *crypto_ch, 589 struct accel_dpdk_cryptodev_task *task) 590 { 591 uint16_t num_enqueued_ops; 592 uint32_t cryop_cnt; 593 uint32_t crypto_len = task->base.block_size; 594 uint64_t dst_length, total_length; 595 uint64_t iv_start = task->base.iv; 596 struct accel_dpdk_cryptodev_queued_op *op_to_queue; 597 uint32_t i, crypto_index; 598 struct rte_crypto_op *crypto_ops[ACCEL_DPDK_CRYPTODEV_MAX_ENQUEUE_ARRAY_SIZE]; 599 struct rte_mbuf *src_mbufs[ACCEL_DPDK_CRYPTODEV_MAX_ENQUEUE_ARRAY_SIZE]; 600 struct rte_mbuf *dst_mbufs[ACCEL_DPDK_CRYPTODEV_MAX_ENQUEUE_ARRAY_SIZE]; 601 struct rte_cryptodev_sym_session *session; 602 struct accel_dpdk_cryptodev_key_priv *priv; 603 struct accel_dpdk_cryptodev_key_handle *key_handle; 604 struct accel_dpdk_cryptodev_qp *qp; 605 struct accel_dpdk_cryptodev_device *dev; 606 struct spdk_iov_sgl src, dst = {}; 607 bool inplace = true; 608 int rc; 609 610 if (spdk_unlikely(!task->base.crypto_key || 611 task->base.crypto_key->module_if != &g_accel_dpdk_cryptodev_module)) { 612 return -EINVAL; 613 } 614 615 total_length = 0; 616 for (i = 0; i < task->base.s.iovcnt; i++) { 617 total_length += task->base.s.iovs[i].iov_len; 618 } 619 dst_length = 0; 620 for (i = 0; i < task->base.d.iovcnt; i++) { 621 dst_length += task->base.d.iovs[i].iov_len; 622 } 623 624 if (spdk_unlikely(total_length != dst_length || !total_length)) { 625 return -ERANGE; 626 } 627 if (spdk_unlikely(total_length % task->base.block_size != 0)) { 628 return -EINVAL; 629 } 630 631 priv = task->base.crypto_key->priv; 632 assert(priv->driver < ACCEL_DPDK_CRYPTODEV_DRIVER_LAST); 633 634 if (total_length > ACCEL_DPDK_CRYPTODEV_CRYPTO_MAX_IO) { 635 return -E2BIG; 636 } 637 638 cryop_cnt = total_length / task->base.block_size; 639 qp = crypto_ch->device_qp[priv->driver]; 640 assert(qp); 641 dev = qp->device; 642 assert(dev); 643 644 key_handle = accel_dpdk_find_key_handle_in_channel(crypto_ch, priv); 645 if (spdk_unlikely(!key_handle)) { 646 SPDK_ERRLOG("Failed to find a key handle, driver %s, cipher %s\n", g_driver_names[priv->driver], 647 g_cipher_names[priv->cipher]); 648 return -EINVAL; 649 } 650 /* mlx5_pci binds keys to a specific device, we can't use a key with any device */ 651 assert(dev == key_handle->device || priv->driver != ACCEL_DPDK_CRYPTODEV_DRIVER_MLX5_PCI); 652 653 if (task->base.op_code == ACCEL_OPC_ENCRYPT) { 654 session = key_handle->session_encrypt; 655 } else if (task->base.op_code == ACCEL_OPC_DECRYPT) { 656 session = key_handle->session_decrypt; 657 } else { 658 return -EINVAL; 659 } 660 661 /* Check if crypto operation is inplace: no destination or source == destination */ 662 if (task->base.s.iovcnt == task->base.d.iovcnt) { 663 if (memcmp(task->base.s.iovs, task->base.d.iovs, sizeof(struct iovec) * task->base.s.iovcnt) != 0) { 664 inplace = false; 665 } 666 } else if (task->base.d.iovcnt != 0) { 667 inplace = false; 668 } 669 670 rc = accel_dpdk_cryptodev_task_alloc_resources(src_mbufs, inplace ? NULL : dst_mbufs, crypto_ops, 671 cryop_cnt); 672 if (rc) { 673 return rc; 674 } 675 /* This value is used in the completion callback to determine when the accel task is complete. 676 */ 677 task->cryop_cnt_remaining = cryop_cnt; 678 679 /* As we don't support chaining because of a decision to use LBA as IV, construction 680 * of crypto operations is straightforward. We build both the op, the mbuf and the 681 * dst_mbuf in our local arrays by looping through the length of the accel task and 682 * picking off LBA sized blocks of memory from the IOVs as we walk through them. Each 683 * LBA sized chunk of memory will correspond 1:1 to a crypto operation and a single 684 * mbuf per crypto operation. 685 */ 686 spdk_iov_sgl_init(&src, task->base.s.iovs, task->base.s.iovcnt, 0); 687 if (!inplace) { 688 spdk_iov_sgl_init(&dst, task->base.d.iovs, task->base.d.iovcnt, 0); 689 } 690 691 for (crypto_index = 0; crypto_index < cryop_cnt; crypto_index++) { 692 rc = accel_dpdk_cryptodev_mbuf_add_single_block(&src, src_mbufs[crypto_index], task); 693 if (spdk_unlikely(rc)) { 694 goto err_free_ops; 695 } 696 accel_dpdk_cryptodev_op_set_iv(crypto_ops[crypto_index], iv_start); 697 iv_start++; 698 699 /* Set the data to encrypt/decrypt length */ 700 crypto_ops[crypto_index]->sym->cipher.data.length = crypto_len; 701 crypto_ops[crypto_index]->sym->cipher.data.offset = 0; 702 rte_crypto_op_attach_sym_session(crypto_ops[crypto_index], session); 703 704 /* link the mbuf to the crypto op. */ 705 crypto_ops[crypto_index]->sym->m_src = src_mbufs[crypto_index]; 706 707 if (inplace) { 708 crypto_ops[crypto_index]->sym->m_dst = NULL; 709 } else { 710 rc = accel_dpdk_cryptodev_mbuf_add_single_block(&dst, dst_mbufs[crypto_index], task); 711 if (spdk_unlikely(rc)) { 712 goto err_free_ops; 713 } 714 crypto_ops[crypto_index]->sym->m_dst = dst_mbufs[crypto_index]; 715 } 716 } 717 718 /* Enqueue everything we've got but limit by the max number of descriptors we 719 * configured the crypto device for. 720 */ 721 num_enqueued_ops = rte_cryptodev_enqueue_burst(dev->cdev_id, qp->qp, crypto_ops, spdk_min(cryop_cnt, 722 dev->qp_desc_nr)); 723 724 qp->num_enqueued_ops += num_enqueued_ops; 725 /* We were unable to enqueue everything but did get some, so need to decide what 726 * to do based on the status of the last op. 727 */ 728 if (num_enqueued_ops < cryop_cnt) { 729 switch (crypto_ops[num_enqueued_ops]->status) { 730 case RTE_CRYPTO_OP_STATUS_NOT_PROCESSED: 731 /* Queue them up on a linked list to be resubmitted via the poller. */ 732 for (crypto_index = num_enqueued_ops; crypto_index < cryop_cnt; crypto_index++) { 733 op_to_queue = (struct accel_dpdk_cryptodev_queued_op *)rte_crypto_op_ctod_offset( 734 crypto_ops[crypto_index], 735 uint8_t *, ACCEL_DPDK_CRYPTODEV_QUEUED_OP_OFFSET); 736 op_to_queue->qp = qp; 737 op_to_queue->crypto_op = crypto_ops[crypto_index]; 738 op_to_queue->task = task; 739 TAILQ_INSERT_TAIL(&crypto_ch->queued_cry_ops, op_to_queue, link); 740 } 741 break; 742 default: 743 /* For all other statuses, mark task as failed so that the poller will pick 744 * the failure up for the overall task status. 745 */ 746 task->is_failed = true; 747 if (num_enqueued_ops == 0) { 748 /* If nothing was enqueued, but the last one wasn't because of 749 * busy, fail it now as the poller won't know anything about it. 750 */ 751 rc = -EINVAL; 752 goto err_free_ops; 753 } 754 break; 755 } 756 } 757 758 return 0; 759 760 /* Error cleanup paths. */ 761 err_free_ops: 762 if (!inplace) { 763 /* This also releases chained mbufs if any. */ 764 rte_pktmbuf_free_bulk(dst_mbufs, cryop_cnt); 765 } 766 rte_mempool_put_bulk(g_crypto_op_mp, (void **)crypto_ops, cryop_cnt); 767 /* This also releases chained mbufs if any. */ 768 rte_pktmbuf_free_bulk(src_mbufs, cryop_cnt); 769 return rc; 770 } 771 772 static inline struct accel_dpdk_cryptodev_qp * 773 accel_dpdk_cryptodev_get_next_device_qpair(enum accel_dpdk_cryptodev_driver_type type) 774 { 775 struct accel_dpdk_cryptodev_device *device, *device_tmp; 776 struct accel_dpdk_cryptodev_qp *qpair; 777 778 TAILQ_FOREACH_SAFE(device, &g_crypto_devices, link, device_tmp) { 779 if (device->type != type) { 780 continue; 781 } 782 TAILQ_FOREACH(qpair, &device->qpairs, link) { 783 if (!qpair->in_use) { 784 qpair->in_use = true; 785 return qpair; 786 } 787 } 788 } 789 790 return NULL; 791 } 792 793 /* Helper function for the channel creation callback. 794 * Returns the number of drivers assigned to the channel */ 795 static uint32_t 796 accel_dpdk_cryptodev_assign_device_qps(struct accel_dpdk_cryptodev_io_channel *crypto_ch) 797 { 798 struct accel_dpdk_cryptodev_device *device; 799 struct accel_dpdk_cryptodev_qp *device_qp; 800 uint32_t num_drivers = 0; 801 bool qat_found = false; 802 803 pthread_mutex_lock(&g_device_lock); 804 805 TAILQ_FOREACH(device, &g_crypto_devices, link) { 806 if (device->type == ACCEL_DPDK_CRYPTODEV_DRIVER_QAT && !qat_found) { 807 /* For some QAT devices, the optimal qp to use is every 32nd as this spreads the 808 * workload out over the multiple virtual functions in the device. For the devices 809 * where this isn't the case, it doesn't hurt. 810 */ 811 TAILQ_FOREACH(device_qp, &device->qpairs, link) { 812 if (device_qp->index != g_next_qat_index) { 813 continue; 814 } 815 if (device_qp->in_use == false) { 816 assert(crypto_ch->device_qp[ACCEL_DPDK_CRYPTODEV_DRIVER_QAT] == NULL); 817 crypto_ch->device_qp[ACCEL_DPDK_CRYPTODEV_DRIVER_QAT] = device_qp; 818 device_qp->in_use = true; 819 g_next_qat_index = (g_next_qat_index + ACCEL_DPDK_CRYPTODEV_QAT_VF_SPREAD) % g_qat_total_qp; 820 qat_found = true; 821 num_drivers++; 822 break; 823 } else { 824 /* if the preferred index is used, skip to the next one in this set. */ 825 g_next_qat_index = (g_next_qat_index + 1) % g_qat_total_qp; 826 } 827 } 828 } 829 } 830 831 /* For ACCEL_DPDK_CRYPTODEV_AESNI_MB and MLX5_PCI select devices in round-robin manner */ 832 device_qp = accel_dpdk_cryptodev_get_next_device_qpair(ACCEL_DPDK_CRYPTODEV_DRIVER_AESNI_MB); 833 if (device_qp) { 834 assert(crypto_ch->device_qp[ACCEL_DPDK_CRYPTODEV_DRIVER_AESNI_MB] == NULL); 835 crypto_ch->device_qp[ACCEL_DPDK_CRYPTODEV_DRIVER_AESNI_MB] = device_qp; 836 num_drivers++; 837 } 838 839 device_qp = accel_dpdk_cryptodev_get_next_device_qpair(ACCEL_DPDK_CRYPTODEV_DRIVER_MLX5_PCI); 840 if (device_qp) { 841 assert(crypto_ch->device_qp[ACCEL_DPDK_CRYPTODEV_DRIVER_MLX5_PCI] == NULL); 842 crypto_ch->device_qp[ACCEL_DPDK_CRYPTODEV_DRIVER_MLX5_PCI] = device_qp; 843 num_drivers++; 844 } 845 846 pthread_mutex_unlock(&g_device_lock); 847 848 return num_drivers; 849 } 850 851 static void 852 _accel_dpdk_cryptodev_destroy_cb(void *io_device, void *ctx_buf) 853 { 854 struct accel_dpdk_cryptodev_io_channel *crypto_ch = (struct accel_dpdk_cryptodev_io_channel *) 855 ctx_buf; 856 int i; 857 858 pthread_mutex_lock(&g_device_lock); 859 for (i = 0; i < ACCEL_DPDK_CRYPTODEV_DRIVER_LAST; i++) { 860 if (crypto_ch->device_qp[i]) { 861 crypto_ch->device_qp[i]->in_use = false; 862 } 863 } 864 pthread_mutex_unlock(&g_device_lock); 865 866 spdk_poller_unregister(&crypto_ch->poller); 867 } 868 869 static int 870 _accel_dpdk_cryptodev_create_cb(void *io_device, void *ctx_buf) 871 { 872 struct accel_dpdk_cryptodev_io_channel *crypto_ch = (struct accel_dpdk_cryptodev_io_channel *) 873 ctx_buf; 874 875 crypto_ch->poller = SPDK_POLLER_REGISTER(accel_dpdk_cryptodev_poller, crypto_ch, 0); 876 if (!accel_dpdk_cryptodev_assign_device_qps(crypto_ch)) { 877 SPDK_ERRLOG("No crypto drivers assigned\n"); 878 spdk_poller_unregister(&crypto_ch->poller); 879 return -EINVAL; 880 } 881 882 /* We use this to queue up crypto ops when the device is busy. */ 883 TAILQ_INIT(&crypto_ch->queued_cry_ops); 884 885 return 0; 886 } 887 888 static struct spdk_io_channel * 889 accel_dpdk_cryptodev_get_io_channel(void) 890 { 891 return spdk_get_io_channel(&g_accel_dpdk_cryptodev_module); 892 } 893 894 static size_t 895 accel_dpdk_cryptodev_ctx_size(void) 896 { 897 return sizeof(struct accel_dpdk_cryptodev_task); 898 } 899 900 static bool 901 accel_dpdk_cryptodev_supports_opcode(enum accel_opcode opc) 902 { 903 switch (opc) { 904 case ACCEL_OPC_ENCRYPT: 905 case ACCEL_OPC_DECRYPT: 906 return true; 907 default: 908 return false; 909 } 910 } 911 912 static int 913 accel_dpdk_cryptodev_submit_tasks(struct spdk_io_channel *_ch, struct spdk_accel_task *_task) 914 { 915 struct accel_dpdk_cryptodev_task *task = SPDK_CONTAINEROF(_task, struct accel_dpdk_cryptodev_task, 916 base); 917 struct accel_dpdk_cryptodev_io_channel *ch = spdk_io_channel_get_ctx(_ch); 918 919 return accel_dpdk_cryptodev_process_task(ch, task); 920 } 921 922 /* Dummy function used by DPDK to free ext attached buffers to mbufs, we free them ourselves but 923 * this callback has to be here. */ 924 static void 925 shinfo_free_cb(void *arg1, void *arg2) 926 { 927 } 928 929 static int 930 accel_dpdk_cryptodev_create(uint8_t index, uint16_t num_lcores) 931 { 932 struct rte_cryptodev_qp_conf qp_conf = { .mp_session = g_session_mp, .mp_session_private = g_session_mp_priv }; 933 /* Setup queue pairs. */ 934 struct rte_cryptodev_config conf = { .socket_id = SPDK_ENV_SOCKET_ID_ANY }; 935 struct accel_dpdk_cryptodev_device *device; 936 uint8_t j, cdev_id, cdrv_id; 937 struct accel_dpdk_cryptodev_qp *dev_qp; 938 int rc; 939 940 device = calloc(1, sizeof(*device)); 941 if (!device) { 942 return -ENOMEM; 943 } 944 945 /* Get details about this device. */ 946 rte_cryptodev_info_get(index, &device->cdev_info); 947 cdrv_id = device->cdev_info.driver_id; 948 cdev_id = device->cdev_id = index; 949 950 if (strcmp(device->cdev_info.driver_name, ACCEL_DPDK_CRYPTODEV_QAT) == 0) { 951 device->qp_desc_nr = ACCEL_DPDK_CRYPTODEV_QP_DESCRIPTORS; 952 device->type = ACCEL_DPDK_CRYPTODEV_DRIVER_QAT; 953 } else if (strcmp(device->cdev_info.driver_name, ACCEL_DPDK_CRYPTODEV_AESNI_MB) == 0) { 954 device->qp_desc_nr = ACCEL_DPDK_CRYPTODEV_QP_DESCRIPTORS; 955 device->type = ACCEL_DPDK_CRYPTODEV_DRIVER_AESNI_MB; 956 } else if (strcmp(device->cdev_info.driver_name, ACCEL_DPDK_CRYPTODEV_MLX5) == 0) { 957 device->qp_desc_nr = ACCEL_DPDK_CRYPTODEV_QP_DESCRIPTORS_MLX5; 958 device->type = ACCEL_DPDK_CRYPTODEV_DRIVER_MLX5_PCI; 959 } else if (strcmp(device->cdev_info.driver_name, ACCEL_DPDK_CRYPTODEV_QAT_ASYM) == 0) { 960 /* ACCEL_DPDK_CRYPTODEV_QAT_ASYM devices are not supported at this time. */ 961 rc = 0; 962 goto err; 963 } else { 964 SPDK_ERRLOG("Failed to start device %u. Invalid driver name \"%s\"\n", 965 cdev_id, device->cdev_info.driver_name); 966 rc = -EINVAL; 967 goto err; 968 } 969 970 /* Before going any further, make sure we have enough resources for this 971 * device type to function. We need a unique queue pair per core accross each 972 * device type to remain lockless.... 973 */ 974 if ((rte_cryptodev_device_count_by_driver(cdrv_id) * 975 device->cdev_info.max_nb_queue_pairs) < num_lcores) { 976 SPDK_ERRLOG("Insufficient unique queue pairs available for %s\n", 977 device->cdev_info.driver_name); 978 SPDK_ERRLOG("Either add more crypto devices or decrease core count\n"); 979 rc = -EINVAL; 980 goto err; 981 } 982 983 conf.nb_queue_pairs = device->cdev_info.max_nb_queue_pairs; 984 rc = rte_cryptodev_configure(cdev_id, &conf); 985 if (rc < 0) { 986 SPDK_ERRLOG("Failed to configure cryptodev %u: error %d\n", 987 cdev_id, rc); 988 rc = -EINVAL; 989 goto err; 990 } 991 992 /* Pre-setup all potential qpairs now and assign them in the channel 993 * callback. If we were to create them there, we'd have to stop the 994 * entire device affecting all other threads that might be using it 995 * even on other queue pairs. 996 */ 997 qp_conf.nb_descriptors = device->qp_desc_nr; 998 for (j = 0; j < device->cdev_info.max_nb_queue_pairs; j++) { 999 rc = rte_cryptodev_queue_pair_setup(cdev_id, j, &qp_conf, SOCKET_ID_ANY); 1000 if (rc < 0) { 1001 SPDK_ERRLOG("Failed to setup queue pair %u on " 1002 "cryptodev %u: error %d\n", j, cdev_id, rc); 1003 rc = -EINVAL; 1004 goto err_qp_setup; 1005 } 1006 } 1007 1008 rc = rte_cryptodev_start(cdev_id); 1009 if (rc < 0) { 1010 SPDK_ERRLOG("Failed to start device %u: error %d\n", cdev_id, rc); 1011 rc = -EINVAL; 1012 goto err_dev_start; 1013 } 1014 1015 TAILQ_INIT(&device->qpairs); 1016 /* Build up lists of device/qp combinations per PMD */ 1017 for (j = 0; j < device->cdev_info.max_nb_queue_pairs; j++) { 1018 dev_qp = calloc(1, sizeof(*dev_qp)); 1019 if (!dev_qp) { 1020 rc = -ENOMEM; 1021 goto err_qp_alloc; 1022 } 1023 dev_qp->device = device; 1024 dev_qp->qp = j; 1025 dev_qp->in_use = false; 1026 TAILQ_INSERT_TAIL(&device->qpairs, dev_qp, link); 1027 if (device->type == ACCEL_DPDK_CRYPTODEV_DRIVER_QAT) { 1028 dev_qp->index = g_qat_total_qp++; 1029 } 1030 } 1031 /* Add to our list of available crypto devices. */ 1032 TAILQ_INSERT_TAIL(&g_crypto_devices, device, link); 1033 1034 return 0; 1035 1036 err_qp_alloc: 1037 TAILQ_FOREACH(dev_qp, &device->qpairs, link) { 1038 if (dev_qp->device->cdev_id != device->cdev_id) { 1039 continue; 1040 } 1041 free(dev_qp); 1042 if (device->type == ACCEL_DPDK_CRYPTODEV_DRIVER_QAT) { 1043 assert(g_qat_total_qp); 1044 g_qat_total_qp--; 1045 } 1046 } 1047 rte_cryptodev_stop(cdev_id); 1048 err_dev_start: 1049 err_qp_setup: 1050 rte_cryptodev_close(cdev_id); 1051 err: 1052 free(device); 1053 1054 return rc; 1055 } 1056 1057 static void 1058 accel_dpdk_cryptodev_release(struct accel_dpdk_cryptodev_device *device) 1059 { 1060 struct accel_dpdk_cryptodev_qp *dev_qp, *tmp; 1061 1062 assert(device); 1063 1064 TAILQ_FOREACH_SAFE(dev_qp, &device->qpairs, link, tmp) { 1065 free(dev_qp); 1066 } 1067 if (device->type == ACCEL_DPDK_CRYPTODEV_DRIVER_QAT) { 1068 assert(g_qat_total_qp >= device->cdev_info.max_nb_queue_pairs); 1069 g_qat_total_qp -= device->cdev_info.max_nb_queue_pairs; 1070 } 1071 rte_cryptodev_stop(device->cdev_id); 1072 rte_cryptodev_close(device->cdev_id); 1073 free(device); 1074 } 1075 1076 static int 1077 accel_dpdk_cryptodev_init(void) 1078 { 1079 uint8_t cdev_count; 1080 uint8_t cdev_id; 1081 int i, rc; 1082 struct accel_dpdk_cryptodev_device *device, *tmp_dev; 1083 unsigned int max_sess_size = 0, sess_size; 1084 uint16_t num_lcores = rte_lcore_count(); 1085 char aesni_args[32]; 1086 1087 /* Only the first call via module init should init the crypto drivers. */ 1088 if (g_session_mp != NULL) { 1089 return 0; 1090 } 1091 1092 /* We always init ACCEL_DPDK_CRYPTODEV_AESNI_MB */ 1093 snprintf(aesni_args, sizeof(aesni_args), "max_nb_queue_pairs=%d", 1094 ACCEL_DPDK_CRYPTODEV_AESNI_MB_NUM_QP); 1095 rc = rte_vdev_init(ACCEL_DPDK_CRYPTODEV_AESNI_MB, aesni_args); 1096 if (rc) { 1097 SPDK_NOTICELOG("Failed to create virtual PMD %s: error %d. " 1098 "Possibly %s is not supported by DPDK library. " 1099 "Keep going...\n", ACCEL_DPDK_CRYPTODEV_AESNI_MB, rc, ACCEL_DPDK_CRYPTODEV_AESNI_MB); 1100 } 1101 1102 /* If we have no crypto devices, there's no reason to continue. */ 1103 cdev_count = rte_cryptodev_count(); 1104 SPDK_NOTICELOG("Found crypto devices: %d\n", (int)cdev_count); 1105 if (cdev_count == 0) { 1106 return 0; 1107 } 1108 1109 g_mbuf_offset = rte_mbuf_dynfield_register(&rte_mbuf_dynfield_io_context); 1110 if (g_mbuf_offset < 0) { 1111 SPDK_ERRLOG("error registering dynamic field with DPDK\n"); 1112 return -EINVAL; 1113 } 1114 1115 /* Create global mempools, shared by all devices regardless of type */ 1116 /* First determine max session size, most pools are shared by all the devices, 1117 * so we need to find the global max sessions size. */ 1118 for (cdev_id = 0; cdev_id < cdev_count; cdev_id++) { 1119 sess_size = rte_cryptodev_sym_get_private_session_size(cdev_id); 1120 if (sess_size > max_sess_size) { 1121 max_sess_size = sess_size; 1122 } 1123 } 1124 1125 g_session_mp_priv = rte_mempool_create("dpdk_crypto_ses_mp_priv", 1126 ACCEL_DPDK_CRYPTODEV_NUM_SESSIONS, max_sess_size, ACCEL_DPDK_CRYPTODEV_SESS_MEMPOOL_CACHE_SIZE, 0, 1127 NULL, NULL, NULL, NULL, SOCKET_ID_ANY, 0); 1128 if (g_session_mp_priv == NULL) { 1129 SPDK_ERRLOG("Cannot create private session pool max size 0x%x\n", max_sess_size); 1130 return -ENOMEM; 1131 } 1132 1133 g_session_mp = rte_cryptodev_sym_session_pool_create("dpdk_crypto_ses_mp", 1134 ACCEL_DPDK_CRYPTODEV_NUM_SESSIONS, 0, ACCEL_DPDK_CRYPTODEV_SESS_MEMPOOL_CACHE_SIZE, 0, 1135 SOCKET_ID_ANY); 1136 if (g_session_mp == NULL) { 1137 SPDK_ERRLOG("Cannot create session pool max size 0x%x\n", max_sess_size); 1138 rc = -ENOMEM; 1139 goto error_create_session_mp; 1140 } 1141 1142 g_mbuf_mp = rte_pktmbuf_pool_create("dpdk_crypto_mbuf_mp", ACCEL_DPDK_CRYPTODEV_NUM_MBUFS, 1143 ACCEL_DPDK_CRYPTODEV_POOL_CACHE_SIZE, 1144 0, 0, SPDK_ENV_SOCKET_ID_ANY); 1145 if (g_mbuf_mp == NULL) { 1146 SPDK_ERRLOG("Cannot create mbuf pool\n"); 1147 rc = -ENOMEM; 1148 goto error_create_mbuf; 1149 } 1150 1151 /* We use per op private data as suggested by DPDK and to store the IV and 1152 * our own struct for queueing ops. */ 1153 g_crypto_op_mp = rte_crypto_op_pool_create("dpdk_crypto_op_mp", 1154 RTE_CRYPTO_OP_TYPE_SYMMETRIC, ACCEL_DPDK_CRYPTODEV_NUM_MBUFS, ACCEL_DPDK_CRYPTODEV_POOL_CACHE_SIZE, 1155 (ACCEL_DPDK_CRYPTODEV_DEFAULT_NUM_XFORMS * sizeof(struct rte_crypto_sym_xform)) + 1156 ACCEL_DPDK_CRYPTODEV_IV_LENGTH + ACCEL_DPDK_CRYPTODEV_QUEUED_OP_LENGTH, rte_socket_id()); 1157 if (g_crypto_op_mp == NULL) { 1158 SPDK_ERRLOG("Cannot create op pool\n"); 1159 rc = -ENOMEM; 1160 goto error_create_op; 1161 } 1162 1163 /* Init all devices */ 1164 for (i = 0; i < cdev_count; i++) { 1165 rc = accel_dpdk_cryptodev_create(i, num_lcores); 1166 if (rc) { 1167 goto err; 1168 } 1169 } 1170 1171 g_shinfo.free_cb = shinfo_free_cb; 1172 1173 spdk_io_device_register(&g_accel_dpdk_cryptodev_module, _accel_dpdk_cryptodev_create_cb, 1174 _accel_dpdk_cryptodev_destroy_cb, sizeof(struct accel_dpdk_cryptodev_io_channel), 1175 "accel_dpdk_cryptodev"); 1176 1177 return 0; 1178 1179 /* Error cleanup paths. */ 1180 err: 1181 TAILQ_FOREACH_SAFE(device, &g_crypto_devices, link, tmp_dev) { 1182 TAILQ_REMOVE(&g_crypto_devices, device, link); 1183 accel_dpdk_cryptodev_release(device); 1184 } 1185 rte_mempool_free(g_crypto_op_mp); 1186 g_crypto_op_mp = NULL; 1187 error_create_op: 1188 rte_mempool_free(g_mbuf_mp); 1189 g_mbuf_mp = NULL; 1190 error_create_mbuf: 1191 rte_mempool_free(g_session_mp); 1192 g_session_mp = NULL; 1193 error_create_session_mp: 1194 if (g_session_mp_priv != NULL) { 1195 rte_mempool_free(g_session_mp_priv); 1196 g_session_mp_priv = NULL; 1197 } 1198 return rc; 1199 } 1200 1201 static void 1202 accel_dpdk_cryptodev_fini_cb(void *io_device) 1203 { 1204 struct accel_dpdk_cryptodev_device *device, *tmp; 1205 1206 TAILQ_FOREACH_SAFE(device, &g_crypto_devices, link, tmp) { 1207 TAILQ_REMOVE(&g_crypto_devices, device, link); 1208 accel_dpdk_cryptodev_release(device); 1209 } 1210 rte_vdev_uninit(ACCEL_DPDK_CRYPTODEV_AESNI_MB); 1211 1212 rte_mempool_free(g_crypto_op_mp); 1213 rte_mempool_free(g_mbuf_mp); 1214 rte_mempool_free(g_session_mp); 1215 if (g_session_mp_priv != NULL) { 1216 rte_mempool_free(g_session_mp_priv); 1217 } 1218 1219 spdk_accel_module_finish(); 1220 } 1221 1222 /* Called when the entire module is being torn down. */ 1223 static void 1224 accel_dpdk_cryptodev_fini(void *ctx) 1225 { 1226 spdk_io_device_unregister(&g_accel_dpdk_cryptodev_module, accel_dpdk_cryptodev_fini_cb); 1227 } 1228 1229 static int 1230 accel_dpdk_cryptodev_key_handle_configure(struct spdk_accel_crypto_key *key, 1231 struct accel_dpdk_cryptodev_key_handle *key_handle) 1232 { 1233 struct accel_dpdk_cryptodev_key_priv *priv = key->priv; 1234 int rc; 1235 1236 key_handle->session_encrypt = rte_cryptodev_sym_session_create(g_session_mp); 1237 if (!key_handle->session_encrypt) { 1238 SPDK_ERRLOG("Failed to create encrypt crypto session.\n"); 1239 return -EINVAL; 1240 } 1241 key_handle->session_decrypt = rte_cryptodev_sym_session_create(g_session_mp); 1242 if (!key_handle->session_decrypt) { 1243 SPDK_ERRLOG("Failed to create decrypt crypto session.\n"); 1244 rc = -EINVAL; 1245 goto err_ses_encrypt; 1246 } 1247 key_handle->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; 1248 key_handle->cipher_xform.cipher.iv.offset = ACCEL_DPDK_CRYPTODEV_IV_OFFSET; 1249 key_handle->cipher_xform.cipher.iv.length = ACCEL_DPDK_CRYPTODEV_IV_LENGTH; 1250 1251 switch (priv->cipher) { 1252 case ACCEL_DPDK_CRYPTODEV_CIPHER_AES_CBC: 1253 key_handle->cipher_xform.cipher.key.data = key->key; 1254 key_handle->cipher_xform.cipher.key.length = key->key_size; 1255 key_handle->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC; 1256 break; 1257 case ACCEL_DPDK_CRYPTODEV_CIPHER_AES_XTS: 1258 key_handle->cipher_xform.cipher.key.data = priv->xts_key; 1259 key_handle->cipher_xform.cipher.key.length = key->key_size + key->key2_size; 1260 key_handle->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_XTS; 1261 break; 1262 default: 1263 SPDK_ERRLOG("Invalid cipher name %s.\n", key->param.cipher); 1264 rc = -EINVAL; 1265 goto err_ses_decrypt; 1266 } 1267 1268 key_handle->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; 1269 rc = rte_cryptodev_sym_session_init(key_handle->device->cdev_id, key_handle->session_encrypt, 1270 &key_handle->cipher_xform, 1271 g_session_mp_priv ? g_session_mp_priv : g_session_mp); 1272 if (rc < 0) { 1273 SPDK_ERRLOG("Failed to init encrypt session: error %d\n", rc); 1274 rc = -EINVAL; 1275 goto err_ses_decrypt; 1276 } 1277 1278 key_handle->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT; 1279 rc = rte_cryptodev_sym_session_init(key_handle->device->cdev_id, key_handle->session_decrypt, 1280 &key_handle->cipher_xform, 1281 g_session_mp_priv ? g_session_mp_priv : g_session_mp); 1282 if (rc < 0) { 1283 SPDK_ERRLOG("Failed to init decrypt session: error %d\n", rc); 1284 rc = -EINVAL; 1285 goto err_ses_decrypt; 1286 } 1287 1288 return 0; 1289 1290 err_ses_decrypt: 1291 rte_cryptodev_sym_session_free(key_handle->session_decrypt); 1292 err_ses_encrypt: 1293 rte_cryptodev_sym_session_free(key_handle->session_encrypt); 1294 1295 return rc; 1296 } 1297 1298 static int 1299 accel_dpdk_cryptodev_validate_parameters(enum accel_dpdk_cryptodev_driver_type driver, 1300 enum accel_dpdk_crypto_dev_cipher_type cipher, struct spdk_accel_crypto_key *key) 1301 { 1302 /* Check that all required parameters exist */ 1303 switch (cipher) { 1304 case ACCEL_DPDK_CRYPTODEV_CIPHER_AES_CBC: 1305 if (!key->key || !key->key_size) { 1306 SPDK_ERRLOG("ACCEL_DPDK_CRYPTODEV_AES_CBC requires a key\n"); 1307 return -1; 1308 } 1309 if (key->key2 || key->key2_size) { 1310 SPDK_ERRLOG("ACCEL_DPDK_CRYPTODEV_AES_CBC doesn't use key2\n"); 1311 return -1; 1312 } 1313 break; 1314 case ACCEL_DPDK_CRYPTODEV_CIPHER_AES_XTS: 1315 if (!key->key || !key->key_size || !key->key2 || !key->key2_size) { 1316 SPDK_ERRLOG("ACCEL_DPDK_CRYPTODEV_AES_XTS requires both key and key2\n"); 1317 return -1; 1318 } 1319 break; 1320 default: 1321 return -1; 1322 } 1323 1324 /* Check driver/cipher combinations and key lengths */ 1325 switch (cipher) { 1326 case ACCEL_DPDK_CRYPTODEV_CIPHER_AES_CBC: 1327 if (driver == ACCEL_DPDK_CRYPTODEV_DRIVER_MLX5_PCI) { 1328 SPDK_ERRLOG("Driver %s only supports cipher %s\n", 1329 g_driver_names[ACCEL_DPDK_CRYPTODEV_DRIVER_MLX5_PCI], 1330 g_cipher_names[ACCEL_DPDK_CRYPTODEV_CIPHER_AES_XTS]); 1331 return -1; 1332 } 1333 if (key->key_size != ACCEL_DPDK_CRYPTODEV_AES_CBC_KEY_LENGTH) { 1334 SPDK_ERRLOG("Invalid key size %zu for cipher %s, should be %d\n", key->key_size, 1335 g_cipher_names[ACCEL_DPDK_CRYPTODEV_CIPHER_AES_CBC], ACCEL_DPDK_CRYPTODEV_AES_CBC_KEY_LENGTH); 1336 return -1; 1337 } 1338 break; 1339 case ACCEL_DPDK_CRYPTODEV_CIPHER_AES_XTS: 1340 switch (driver) { 1341 case ACCEL_DPDK_CRYPTODEV_DRIVER_MLX5_PCI: 1342 if (key->key_size != ACCEL_DPDK_CRYPTODEV_AES_XTS_256_BLOCK_KEY_LENGTH && 1343 key->key_size != ACCEL_DPDK_CRYPTODEV_AES_XTS_512_BLOCK_KEY_LENGTH) { 1344 SPDK_ERRLOG("Invalid key size %zu for driver %s, cipher %s, supported %d or %d\n", 1345 key->key_size, g_driver_names[ACCEL_DPDK_CRYPTODEV_DRIVER_MLX5_PCI], 1346 g_cipher_names[ACCEL_DPDK_CRYPTODEV_CIPHER_AES_XTS], 1347 ACCEL_DPDK_CRYPTODEV_AES_XTS_256_BLOCK_KEY_LENGTH, 1348 ACCEL_DPDK_CRYPTODEV_AES_XTS_512_BLOCK_KEY_LENGTH); 1349 return -1; 1350 } 1351 break; 1352 case ACCEL_DPDK_CRYPTODEV_DRIVER_QAT: 1353 case ACCEL_DPDK_CRYPTODEV_DRIVER_AESNI_MB: 1354 if (key->key_size != ACCEL_DPDK_CRYPTODEV_AES_XTS_128_BLOCK_KEY_LENGTH) { 1355 SPDK_ERRLOG("Invalid key size %zu, supported %d\n", key->key_size, 1356 ACCEL_DPDK_CRYPTODEV_AES_XTS_128_BLOCK_KEY_LENGTH); 1357 return -1; 1358 } 1359 break; 1360 default: 1361 SPDK_ERRLOG("Incorrect driver type %d\n", driver); 1362 assert(0); 1363 return -1; 1364 } 1365 if (key->key2_size != ACCEL_DPDK_CRYPTODEV_AES_XTS_TWEAK_KEY_LENGTH) { 1366 SPDK_ERRLOG("Cipher %s requires key2 size %d\n", 1367 g_cipher_names[ACCEL_DPDK_CRYPTODEV_CIPHER_AES_CBC], ACCEL_DPDK_CRYPTODEV_AES_XTS_TWEAK_KEY_LENGTH); 1368 return -1; 1369 } 1370 break; 1371 } 1372 1373 return 0; 1374 } 1375 1376 static void 1377 accel_dpdk_cryptodev_key_deinit(struct spdk_accel_crypto_key *key) 1378 { 1379 struct accel_dpdk_cryptodev_key_handle *key_handle, *key_handle_tmp; 1380 struct accel_dpdk_cryptodev_key_priv *priv = key->priv; 1381 1382 TAILQ_FOREACH_SAFE(key_handle, &priv->dev_keys, link, key_handle_tmp) { 1383 rte_cryptodev_sym_session_free(key_handle->session_encrypt); 1384 rte_cryptodev_sym_session_free(key_handle->session_decrypt); 1385 TAILQ_REMOVE(&priv->dev_keys, key_handle, link); 1386 spdk_memset_s(key_handle, sizeof(*key_handle), 0, sizeof(*key_handle)); 1387 free(key_handle); 1388 } 1389 1390 if (priv->xts_key) { 1391 spdk_memset_s(priv->xts_key, key->key_size + key->key2_size, 0, key->key_size + key->key2_size); 1392 } 1393 free(priv->xts_key); 1394 free(priv); 1395 } 1396 1397 static int 1398 accel_dpdk_cryptodev_key_init(struct spdk_accel_crypto_key *key) 1399 { 1400 struct accel_dpdk_cryptodev_device *device; 1401 struct accel_dpdk_cryptodev_key_priv *priv; 1402 struct accel_dpdk_cryptodev_key_handle *key_handle; 1403 enum accel_dpdk_cryptodev_driver_type driver; 1404 enum accel_dpdk_crypto_dev_cipher_type cipher; 1405 1406 if (!key->param.cipher) { 1407 SPDK_ERRLOG("Cipher is missing\n"); 1408 return -EINVAL; 1409 } 1410 1411 if (strcmp(key->param.cipher, ACCEL_DPDK_CRYPTODEV_AES_CBC) == 0) { 1412 cipher = ACCEL_DPDK_CRYPTODEV_CIPHER_AES_CBC; 1413 } else if (strcmp(key->param.cipher, ACCEL_DPDK_CRYPTODEV_AES_XTS) == 0) { 1414 cipher = ACCEL_DPDK_CRYPTODEV_CIPHER_AES_XTS; 1415 } else { 1416 SPDK_ERRLOG("Unsupported cipher name %s.\n", key->param.cipher); 1417 return -EINVAL; 1418 } 1419 1420 driver = g_dpdk_cryptodev_driver; 1421 1422 if (accel_dpdk_cryptodev_validate_parameters(driver, cipher, key)) { 1423 return -EINVAL; 1424 } 1425 1426 priv = calloc(1, sizeof(*priv)); 1427 if (!priv) { 1428 SPDK_ERRLOG("Memory allocation failed\n"); 1429 return -ENOMEM; 1430 } 1431 key->priv = priv; 1432 priv->driver = driver; 1433 priv->cipher = cipher; 1434 TAILQ_INIT(&priv->dev_keys); 1435 1436 if (cipher == ACCEL_DPDK_CRYPTODEV_CIPHER_AES_XTS) { 1437 /* DPDK expects the keys to be concatenated together. */ 1438 priv->xts_key = calloc(key->key_size + key->key2_size + 1, sizeof(char)); 1439 if (!priv->xts_key) { 1440 SPDK_ERRLOG("Memory allocation failed\n"); 1441 accel_dpdk_cryptodev_key_deinit(key); 1442 return -ENOMEM; 1443 } 1444 memcpy(priv->xts_key, key->key, key->key_size); 1445 memcpy(priv->xts_key + key->key_size, key->key2, key->key2_size); 1446 } 1447 1448 pthread_mutex_lock(&g_device_lock); 1449 TAILQ_FOREACH(device, &g_crypto_devices, link) { 1450 if (device->type != driver) { 1451 continue; 1452 } 1453 key_handle = calloc(1, sizeof(*key_handle)); 1454 if (!key_handle) { 1455 pthread_mutex_unlock(&g_device_lock); 1456 accel_dpdk_cryptodev_key_deinit(key); 1457 return -ENOMEM; 1458 } 1459 key_handle->device = device; 1460 TAILQ_INSERT_TAIL(&priv->dev_keys, key_handle, link); 1461 if (accel_dpdk_cryptodev_key_handle_configure(key, key_handle)) { 1462 pthread_mutex_unlock(&g_device_lock); 1463 accel_dpdk_cryptodev_key_deinit(key); 1464 return -ENOMEM; 1465 } 1466 if (driver != ACCEL_DPDK_CRYPTODEV_DRIVER_MLX5_PCI) { 1467 /* For MLX5_PCI we need to register a key on each device since 1468 * the key is bound to a specific Protection Domain, 1469 * so don't break the loop */ 1470 break; 1471 } 1472 } 1473 pthread_mutex_unlock(&g_device_lock); 1474 1475 if (TAILQ_EMPTY(&priv->dev_keys)) { 1476 free(priv); 1477 return -ENODEV; 1478 } 1479 1480 return 0; 1481 } 1482 1483 static void 1484 accel_dpdk_cryptodev_write_config_json(struct spdk_json_write_ctx *w) 1485 { 1486 spdk_json_write_object_begin(w); 1487 spdk_json_write_named_string(w, "method", "dpdk_cryptodev_scan_accel_module"); 1488 spdk_json_write_object_end(w); 1489 1490 spdk_json_write_object_begin(w); 1491 spdk_json_write_named_string(w, "method", "dpdk_cryptodev_set_driver"); 1492 spdk_json_write_named_object_begin(w, "params"); 1493 spdk_json_write_named_string(w, "driver_name", g_driver_names[g_dpdk_cryptodev_driver]); 1494 spdk_json_write_object_end(w); 1495 spdk_json_write_object_end(w); 1496 } 1497 1498 static struct spdk_accel_module_if g_accel_dpdk_cryptodev_module = { 1499 .module_init = accel_dpdk_cryptodev_init, 1500 .module_fini = accel_dpdk_cryptodev_fini, 1501 .write_config_json = accel_dpdk_cryptodev_write_config_json, 1502 .get_ctx_size = accel_dpdk_cryptodev_ctx_size, 1503 .name = "dpdk_cryptodev", 1504 .supports_opcode = accel_dpdk_cryptodev_supports_opcode, 1505 .get_io_channel = accel_dpdk_cryptodev_get_io_channel, 1506 .submit_tasks = accel_dpdk_cryptodev_submit_tasks, 1507 .crypto_key_init = accel_dpdk_cryptodev_key_init, 1508 .crypto_key_deinit = accel_dpdk_cryptodev_key_deinit, 1509 }; 1510