1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2023 Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include "spdk/stdinc.h" 7 8 #include "spdk/accel.h" 9 #include "spdk/env.h" 10 #include "spdk/log.h" 11 #include "spdk/thread.h" 12 #include "spdk/event.h" 13 #include "spdk/rpc.h" 14 #include "spdk/util.h" 15 #include "spdk/string.h" 16 #include "spdk_internal/cunit.h" 17 18 #include "CUnit/Basic.h" 19 20 pthread_mutex_t g_test_mutex; 21 pthread_cond_t g_test_cond; 22 23 #define WORKER_COUNT 2 24 #define WORKER_IO 0 25 #define WORKER_UT 1 26 27 static struct spdk_thread *g_thread[WORKER_COUNT]; 28 static int g_num_failures = 0; 29 static bool g_shutdown = false; 30 static bool g_completion_success; 31 struct spdk_io_channel *g_channel = NULL; 32 33 struct dif_task { 34 struct iovec *dst_iovs; 35 uint32_t dst_iovcnt; 36 struct iovec *src_iovs; 37 uint32_t src_iovcnt; 38 struct iovec *aux_iovs; 39 uint32_t aux_iovcnt; 40 struct iovec md_iov; 41 uint32_t num_blocks; /* used for the DIF related operations */ 42 struct spdk_dif_ctx dif_ctx; 43 struct spdk_dif_error dif_err; 44 }; 45 46 static void 47 execute_spdk_function(spdk_msg_fn fn, void *arg) 48 { 49 pthread_mutex_lock(&g_test_mutex); 50 spdk_thread_send_msg(g_thread[WORKER_IO], fn, arg); 51 pthread_cond_wait(&g_test_cond, &g_test_mutex); 52 pthread_mutex_unlock(&g_test_mutex); 53 } 54 55 static void 56 wake_ut_thread(void) 57 { 58 pthread_mutex_lock(&g_test_mutex); 59 pthread_cond_signal(&g_test_cond); 60 pthread_mutex_unlock(&g_test_mutex); 61 } 62 63 static void 64 exit_io_thread(void *arg) 65 { 66 assert(spdk_get_thread() == g_thread[WORKER_IO]); 67 spdk_thread_exit(g_thread[WORKER_IO]); 68 wake_ut_thread(); 69 } 70 71 #define DATA_PATTERN 0x5A 72 73 static int g_xfer_size_bytes = 4096; 74 static int g_block_size_bytes = 512; 75 static int g_md_size_bytes = 8; 76 struct dif_task g_dif_task; 77 78 struct accel_dif_request { 79 struct spdk_accel_sequence *sequence; 80 struct spdk_io_channel *channel; 81 struct iovec *dst_iovs; 82 size_t dst_iovcnt; 83 struct iovec *src_iovs; 84 size_t src_iovcnt; 85 struct iovec *aux_iovs; 86 size_t aux_iovcnt; 87 struct iovec *md_iov; 88 uint32_t num_blocks; 89 const struct spdk_dif_ctx *ctx; 90 struct spdk_dif_error *err; 91 spdk_accel_completion_cb cb_fn; 92 void *cb_arg; 93 }; 94 95 static void 96 accel_dif_oper_done(void *arg1, int status) 97 { 98 if (status == 0) { 99 g_completion_success = true; 100 } 101 wake_ut_thread(); 102 } 103 104 static bool 105 accel_dif_error_validate(const uint32_t dif_flags, 106 const struct spdk_dif_error *err) 107 { 108 if (dif_flags & SPDK_DIF_FLAGS_GUARD_CHECK) { 109 return err->err_type == SPDK_DIF_GUARD_ERROR; 110 } else if (dif_flags & SPDK_DIF_FLAGS_APPTAG_CHECK) { 111 return err->err_type == SPDK_DIF_APPTAG_ERROR; 112 } else if (dif_flags & SPDK_DIF_FLAGS_REFTAG_CHECK) { 113 return err->err_type == SPDK_DIF_REFTAG_ERROR; 114 } 115 116 return false; 117 } 118 119 static int 120 alloc_dif_verify_bufs(struct dif_task *task, uint32_t chained_count) 121 { 122 int src_buff_len = g_xfer_size_bytes; 123 uint32_t i = 0; 124 125 assert(chained_count > 0); 126 task->src_iovcnt = chained_count; 127 task->src_iovs = calloc(task->src_iovcnt, sizeof(struct iovec)); 128 if (spdk_unlikely(task->src_iovs == NULL)) { 129 return -ENOMEM; 130 } 131 132 src_buff_len += (g_xfer_size_bytes / g_block_size_bytes) * g_md_size_bytes; 133 134 for (i = 0; i < task->src_iovcnt; i++) { 135 task->src_iovs[i].iov_base = spdk_dma_zmalloc(src_buff_len, 0, NULL); 136 if (spdk_unlikely(task->src_iovs[i].iov_base == NULL)) { 137 return -ENOMEM; 138 } 139 140 memset(task->src_iovs[i].iov_base, DATA_PATTERN, src_buff_len); 141 task->src_iovs[i].iov_len = src_buff_len; 142 } 143 144 task->num_blocks = (g_xfer_size_bytes * chained_count) / g_block_size_bytes; 145 146 return 0; 147 } 148 149 static int 150 alloc_dix_bufs(struct dif_task *task, uint32_t chained_count) 151 { 152 int src_buff_len = g_xfer_size_bytes, md_buff_len; 153 uint32_t i = 0; 154 155 assert(chained_count > 0); 156 task->src_iovcnt = chained_count; 157 task->src_iovs = calloc(task->src_iovcnt, sizeof(struct iovec)); 158 if (spdk_unlikely(task->src_iovs == NULL)) { 159 return -ENOMEM; 160 } 161 162 md_buff_len = (g_xfer_size_bytes / g_block_size_bytes) * g_md_size_bytes * chained_count; 163 164 for (i = 0; i < task->src_iovcnt; i++) { 165 task->src_iovs[i].iov_base = spdk_dma_zmalloc(src_buff_len, 0, NULL); 166 if (spdk_unlikely(task->src_iovs[i].iov_base == NULL)) { 167 return -ENOMEM; 168 } 169 170 memset(task->src_iovs[i].iov_base, DATA_PATTERN, src_buff_len); 171 task->src_iovs[i].iov_len = src_buff_len; 172 } 173 174 task->md_iov.iov_base = spdk_dma_zmalloc(md_buff_len, 0, NULL); 175 if (spdk_unlikely(task->md_iov.iov_base == NULL)) { 176 return -ENOMEM; 177 } 178 179 task->md_iov.iov_len = md_buff_len; 180 task->num_blocks = (g_xfer_size_bytes * chained_count) / g_block_size_bytes; 181 182 return 0; 183 } 184 185 static void 186 free_dif_verify_bufs(struct dif_task *task) 187 { 188 uint32_t i = 0; 189 190 if (task->src_iovs != NULL) { 191 for (i = 0; i < task->src_iovcnt; i++) { 192 if (task->src_iovs[i].iov_base != NULL) { 193 spdk_dma_free(task->src_iovs[i].iov_base); 194 } 195 } 196 free(task->src_iovs); 197 } 198 } 199 200 static void 201 free_dix_bufs(struct dif_task *task) 202 { 203 uint32_t i = 0; 204 205 if (task->src_iovs != NULL) { 206 for (i = 0; i < task->src_iovcnt; i++) { 207 if (task->src_iovs[i].iov_base != NULL) { 208 spdk_dma_free(task->src_iovs[i].iov_base); 209 } 210 } 211 free(task->src_iovs); 212 } 213 214 if (task->md_iov.iov_base != NULL) { 215 spdk_dma_free(task->md_iov.iov_base); 216 } 217 } 218 219 static int 220 alloc_dif_verify_copy_bufs(struct dif_task *task, uint32_t chained_count) 221 { 222 int dst_buff_len = g_xfer_size_bytes; 223 uint32_t data_size_with_md; 224 uint32_t i = 0; 225 226 assert(chained_count > 0); 227 task->src_iovcnt = chained_count; 228 task->src_iovs = calloc(task->src_iovcnt, sizeof(struct iovec)); 229 if (spdk_unlikely(task->src_iovs == NULL)) { 230 return -ENOMEM; 231 } 232 233 task->num_blocks = g_xfer_size_bytes / g_block_size_bytes; 234 235 /* Add bytes for each block for metadata */ 236 data_size_with_md = g_xfer_size_bytes + (task->num_blocks * g_md_size_bytes); 237 238 for (i = 0; i < task->src_iovcnt; i++) { 239 task->src_iovs[i].iov_base = spdk_dma_zmalloc(data_size_with_md, 0, NULL); 240 if (spdk_unlikely(task->src_iovs[i].iov_base == NULL)) { 241 return -ENOMEM; 242 } 243 244 memset(task->src_iovs[i].iov_base, DATA_PATTERN, data_size_with_md); 245 task->src_iovs[i].iov_len = data_size_with_md; 246 } 247 248 task->dst_iovcnt = chained_count; 249 task->dst_iovs = calloc(task->dst_iovcnt, sizeof(struct iovec)); 250 if (spdk_unlikely(task->dst_iovs == NULL)) { 251 return -ENOMEM; 252 } 253 254 for (i = 0; i < task->dst_iovcnt; i++) { 255 task->dst_iovs[i].iov_base = spdk_dma_zmalloc(dst_buff_len, 0, NULL); 256 if (spdk_unlikely(task->dst_iovs[i].iov_base == NULL)) { 257 return -ENOMEM; 258 } 259 260 memset(task->dst_iovs[i].iov_base, 0, dst_buff_len); 261 task->dst_iovs[i].iov_len = dst_buff_len; 262 } 263 264 return 0; 265 } 266 267 static void 268 free_dif_verify_copy_bufs(struct dif_task *task) 269 { 270 uint32_t i = 0; 271 272 if (task->dst_iovs != NULL) { 273 for (i = 0; i < task->dst_iovcnt; i++) { 274 if (task->dst_iovs[i].iov_base != NULL) { 275 spdk_dma_free(task->dst_iovs[i].iov_base); 276 } 277 } 278 free(task->dst_iovs); 279 } 280 281 if (task->src_iovs != NULL) { 282 for (i = 0; i < task->src_iovcnt; i++) { 283 if (task->src_iovs[i].iov_base != NULL) { 284 spdk_dma_free(task->src_iovs[i].iov_base); 285 } 286 } 287 free(task->src_iovs); 288 } 289 } 290 291 static int 292 alloc_dif_generate_copy_bufs(struct dif_task *task, uint32_t chained_count) 293 { 294 int src_buff_len = g_xfer_size_bytes; 295 uint32_t transfer_size_with_md; 296 uint32_t i = 0; 297 298 assert(chained_count > 0); 299 task->dst_iovcnt = chained_count; 300 task->dst_iovs = calloc(task->dst_iovcnt, sizeof(struct iovec)); 301 if (spdk_unlikely(task->dst_iovs == NULL)) { 302 return -ENOMEM; 303 } 304 305 task->num_blocks = g_xfer_size_bytes / g_block_size_bytes; 306 307 /* Add bytes for each block for metadata */ 308 transfer_size_with_md = g_xfer_size_bytes + (task->num_blocks * g_md_size_bytes); 309 310 for (i = 0; i < task->dst_iovcnt; i++) { 311 task->dst_iovs[i].iov_base = spdk_dma_zmalloc(transfer_size_with_md, 0, NULL); 312 if (spdk_unlikely(task->dst_iovs[i].iov_base == NULL)) { 313 return -ENOMEM; 314 } 315 316 memset(task->dst_iovs[i].iov_base, 0, transfer_size_with_md); 317 task->dst_iovs[i].iov_len = transfer_size_with_md; 318 } 319 320 task->src_iovcnt = chained_count; 321 task->src_iovs = calloc(task->src_iovcnt, sizeof(struct iovec)); 322 if (spdk_unlikely(task->src_iovs == NULL)) { 323 return -ENOMEM; 324 } 325 326 for (i = 0; i < task->src_iovcnt; i++) { 327 task->src_iovs[i].iov_base = spdk_dma_zmalloc(src_buff_len, 0, NULL); 328 if (spdk_unlikely(task->src_iovs[i].iov_base == NULL)) { 329 return -ENOMEM; 330 } 331 332 memset(task->src_iovs[i].iov_base, DATA_PATTERN, src_buff_len); 333 task->src_iovs[i].iov_len = src_buff_len; 334 } 335 336 return 0; 337 } 338 339 static void 340 free_dif_generate_copy_bufs(struct dif_task *task) 341 { 342 uint32_t i = 0; 343 344 if (task->dst_iovs != NULL) { 345 for (i = 0; i < task->dst_iovcnt; i++) { 346 if (task->dst_iovs[i].iov_base != NULL) { 347 spdk_dma_free(task->dst_iovs[i].iov_base); 348 } 349 } 350 free(task->dst_iovs); 351 } 352 353 if (task->src_iovs != NULL) { 354 for (i = 0; i < task->src_iovcnt; i++) { 355 if (task->src_iovs[i].iov_base != NULL) { 356 spdk_dma_free(task->src_iovs[i].iov_base); 357 } 358 } 359 free(task->src_iovs); 360 } 361 } 362 363 static int 364 alloc_dif_generate_copy_sequence_bufs(struct dif_task *task, uint32_t chained_count) 365 { 366 int src_buff_len = g_xfer_size_bytes; 367 uint32_t transfer_size_with_md; 368 uint32_t i = 0; 369 370 assert(chained_count > 0); 371 task->dst_iovcnt = chained_count; 372 task->dst_iovs = calloc(task->dst_iovcnt, sizeof(struct iovec)); 373 if (spdk_unlikely(task->dst_iovs == NULL)) { 374 return -ENOMEM; 375 } 376 377 task->num_blocks = g_xfer_size_bytes / g_block_size_bytes; 378 379 /* Add bytes for each block for metadata */ 380 transfer_size_with_md = g_xfer_size_bytes + (task->num_blocks * g_md_size_bytes); 381 382 for (i = 0; i < task->dst_iovcnt; i++) { 383 task->dst_iovs[i].iov_base = spdk_dma_zmalloc(transfer_size_with_md, 0, NULL); 384 if (spdk_unlikely(task->dst_iovs[i].iov_base == NULL)) { 385 return -ENOMEM; 386 } 387 388 memset(task->dst_iovs[i].iov_base, 0, transfer_size_with_md); 389 task->dst_iovs[i].iov_len = transfer_size_with_md; 390 } 391 392 task->src_iovcnt = chained_count; 393 task->src_iovs = calloc(task->src_iovcnt, sizeof(struct iovec)); 394 if (spdk_unlikely(task->src_iovs == NULL)) { 395 return -ENOMEM; 396 } 397 398 for (i = 0; i < task->src_iovcnt; i++) { 399 task->src_iovs[i].iov_base = spdk_dma_zmalloc(src_buff_len, 0, NULL); 400 if (spdk_unlikely(task->src_iovs[i].iov_base == NULL)) { 401 return -ENOMEM; 402 } 403 404 memset(task->src_iovs[i].iov_base, DATA_PATTERN, src_buff_len); 405 task->src_iovs[i].iov_len = src_buff_len; 406 } 407 408 /* 409 * For write, we do not want to insert DIF in place because host does not expect 410 * write buffer to be updated. We allocate auxiliary buffer to simulate such case. 411 */ 412 task->aux_iovcnt = chained_count; 413 task->aux_iovs = calloc(task->aux_iovcnt, sizeof(struct iovec)); 414 if (spdk_unlikely(task->aux_iovs == NULL)) { 415 return -ENOMEM; 416 } 417 418 for (i = 0; i < task->aux_iovcnt; i++) { 419 task->aux_iovs[i].iov_base = spdk_dma_zmalloc(transfer_size_with_md, 0, NULL); 420 if (spdk_unlikely(task->aux_iovs[i].iov_base == NULL)) { 421 return -ENOMEM; 422 } 423 424 memset(task->aux_iovs[i].iov_base, 0, transfer_size_with_md); 425 task->aux_iovs[i].iov_len = transfer_size_with_md; 426 } 427 428 return 0; 429 } 430 431 static void 432 free_dif_generate_copy_sequence_bufs(struct dif_task *task) 433 { 434 uint32_t i = 0; 435 436 if (task->dst_iovs != NULL) { 437 for (i = 0; i < task->dst_iovcnt; i++) { 438 if (task->dst_iovs[i].iov_base != NULL) { 439 spdk_dma_free(task->dst_iovs[i].iov_base); 440 } 441 } 442 free(task->dst_iovs); 443 } 444 445 if (task->src_iovs != NULL) { 446 for (i = 0; i < task->src_iovcnt; i++) { 447 if (task->src_iovs[i].iov_base != NULL) { 448 spdk_dma_free(task->src_iovs[i].iov_base); 449 } 450 } 451 free(task->src_iovs); 452 } 453 454 if (task->aux_iovs != NULL) { 455 for (i = 0; i < task->aux_iovcnt; i++) { 456 if (task->aux_iovs[i].iov_base != NULL) { 457 spdk_dma_free(task->aux_iovs[i].iov_base); 458 } 459 } 460 free(task->aux_iovs); 461 } 462 } 463 464 static void 465 accel_dif_verify_test(void *arg) 466 { 467 int rc; 468 struct accel_dif_request *req = arg; 469 470 g_completion_success = false; 471 rc = spdk_accel_submit_dif_verify(req->channel, req->src_iovs, req->src_iovcnt, 472 req->num_blocks, req->ctx, req->err, 473 req->cb_fn, req->cb_arg); 474 if (rc) { 475 wake_ut_thread(); 476 } 477 } 478 479 static void 480 accel_dix_verify_test(void *arg) 481 { 482 int rc; 483 struct accel_dif_request *req = arg; 484 485 g_completion_success = false; 486 rc = spdk_accel_submit_dix_verify(req->channel, req->src_iovs, req->src_iovcnt, req->md_iov, 487 req->num_blocks, req->ctx, req->err, req->cb_fn, 488 req->cb_arg); 489 if (rc) { 490 wake_ut_thread(); 491 } 492 } 493 494 static void 495 accel_dix_generate_test(void *arg) 496 { 497 int rc; 498 struct accel_dif_request *req = arg; 499 500 g_completion_success = false; 501 rc = spdk_accel_submit_dix_generate(req->channel, req->src_iovs, req->src_iovcnt, 502 req->md_iov, req->num_blocks, req->ctx, req->cb_fn, req->cb_arg); 503 if (rc) { 504 wake_ut_thread(); 505 } 506 } 507 508 static void 509 accel_dif_verify_copy_test(void *arg) 510 { 511 int rc; 512 struct accel_dif_request *req = arg; 513 514 g_completion_success = false; 515 rc = spdk_accel_submit_dif_verify_copy(req->channel, req->dst_iovs, req->dst_iovcnt, 516 req->src_iovs, req->src_iovcnt, 517 req->num_blocks, req->ctx, req->err, 518 req->cb_fn, req->cb_arg); 519 if (rc) { 520 wake_ut_thread(); 521 } 522 } 523 524 static void 525 accel_dif_generate_copy_test(void *arg) 526 { 527 int rc; 528 struct accel_dif_request *req = arg; 529 530 g_completion_success = false; 531 rc = spdk_accel_submit_dif_generate_copy(req->channel, req->dst_iovs, req->dst_iovcnt, 532 req->src_iovs, req->src_iovcnt, req->num_blocks, req->ctx, 533 req->cb_fn, req->cb_arg); 534 if (rc) { 535 wake_ut_thread(); 536 } 537 } 538 539 static void 540 accel_dif_generate_copy_sequence_test(void *arg) 541 { 542 int rc; 543 struct accel_dif_request *req = arg; 544 545 g_completion_success = false; 546 req->sequence = NULL; 547 548 rc = spdk_accel_append_dif_generate_copy(&req->sequence, req->channel, 549 req->aux_iovs, req->aux_iovcnt, NULL, NULL, 550 req->src_iovs, req->src_iovcnt, NULL, NULL, 551 req->num_blocks, req->ctx, NULL, NULL); 552 if (rc) { 553 wake_ut_thread(); 554 return; 555 } 556 557 rc = spdk_accel_append_copy(&req->sequence, req->channel, 558 req->dst_iovs, req->dst_iovcnt, NULL, NULL, 559 req->aux_iovs, req->aux_iovcnt, NULL, NULL, 560 NULL, NULL); 561 if (rc) { 562 spdk_accel_sequence_abort(req->sequence); 563 wake_ut_thread(); 564 return; 565 } 566 567 spdk_accel_sequence_finish(req->sequence, req->cb_fn, req->cb_arg); 568 } 569 570 static void 571 accel_dif_verify_copy_sequence_test(void *arg) 572 { 573 int rc; 574 struct accel_dif_request *req = arg; 575 576 g_completion_success = false; 577 req->sequence = NULL; 578 579 rc = spdk_accel_append_dif_verify_copy(&req->sequence, req->channel, 580 req->dst_iovs, req->dst_iovcnt, NULL, NULL, 581 req->dst_iovs, req->dst_iovcnt, NULL, NULL, 582 req->num_blocks, req->ctx, req->err, 583 NULL, NULL); 584 if (rc) { 585 wake_ut_thread(); 586 return; 587 } 588 589 rc = spdk_accel_append_copy(&req->sequence, req->channel, 590 req->dst_iovs, req->dst_iovcnt, NULL, NULL, 591 req->src_iovs, req->src_iovcnt, NULL, NULL, 592 NULL, NULL); 593 if (rc) { 594 spdk_accel_sequence_abort(req->sequence); 595 wake_ut_thread(); 596 return; 597 } 598 599 spdk_accel_sequence_reverse(req->sequence); 600 spdk_accel_sequence_finish(req->sequence, req->cb_fn, req->cb_arg); 601 } 602 603 static void 604 accel_dif_verify_op_dif_generated_do_check(uint32_t dif_flags) 605 { 606 struct spdk_dif_ctx_init_ext_opts dif_opts; 607 struct accel_dif_request req; 608 struct dif_task *task = &g_dif_task; 609 int rc; 610 611 rc = alloc_dif_verify_bufs(task, 1); 612 SPDK_CU_ASSERT_FATAL(rc == 0); 613 614 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 615 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 616 617 rc = spdk_dif_ctx_init(&task->dif_ctx, 618 g_block_size_bytes + g_md_size_bytes, 619 g_md_size_bytes, true, true, 620 SPDK_DIF_TYPE1, 621 SPDK_DIF_FLAGS_GUARD_CHECK | 622 SPDK_DIF_FLAGS_APPTAG_CHECK | 623 SPDK_DIF_FLAGS_REFTAG_CHECK, 624 10, 0xFFFF, 20, 0, 0, &dif_opts); 625 SPDK_CU_ASSERT_FATAL(rc == 0); 626 627 rc = spdk_dif_generate(task->src_iovs, task->src_iovcnt, task->num_blocks, &task->dif_ctx); 628 SPDK_CU_ASSERT_FATAL(rc == 0); 629 630 rc = spdk_dif_ctx_init(&task->dif_ctx, 631 g_block_size_bytes + g_md_size_bytes, 632 g_md_size_bytes, true, true, 633 SPDK_DIF_TYPE1, 634 dif_flags, 635 10, 0xFFFF, 20, 0, 0, &dif_opts); 636 SPDK_CU_ASSERT_FATAL(rc == 0); 637 638 req.channel = g_channel; 639 req.src_iovs = task->src_iovs; 640 req.src_iovcnt = task->src_iovcnt; 641 req.num_blocks = task->num_blocks; 642 req.ctx = &task->dif_ctx; 643 req.err = &task->dif_err; 644 req.cb_fn = accel_dif_oper_done; 645 req.cb_arg = task; 646 647 execute_spdk_function(accel_dif_verify_test, &req); 648 CU_ASSERT_EQUAL(g_completion_success, true); 649 650 free_dif_verify_bufs(task); 651 } 652 653 static void 654 accel_dix_generate_verify(struct accel_dif_request *req, 655 uint32_t dif_flags_generate, uint32_t dif_flags_verify) 656 { 657 struct spdk_dif_ctx_init_ext_opts dif_opts; 658 struct dif_task *task = &g_dif_task; 659 int rc; 660 661 rc = alloc_dix_bufs(task, 1); 662 SPDK_CU_ASSERT_FATAL(rc == 0); 663 664 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 665 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 666 667 rc = spdk_dif_ctx_init(&task->dif_ctx, 668 g_block_size_bytes, 669 g_md_size_bytes, false, true, 670 SPDK_DIF_TYPE1, 671 dif_flags_generate, 672 10, 0xFFFF, 20, 0, 0, &dif_opts); 673 SPDK_CU_ASSERT_FATAL(rc == 0); 674 675 rc = spdk_dix_generate(task->src_iovs, task->src_iovcnt, &task->md_iov, task->num_blocks, 676 &task->dif_ctx); 677 SPDK_CU_ASSERT_FATAL(rc == 0); 678 679 rc = spdk_dif_ctx_init(&task->dif_ctx, 680 g_block_size_bytes, 681 g_md_size_bytes, false, true, 682 SPDK_DIF_TYPE1, 683 dif_flags_verify, 684 10, 0xFFFF, 20, 0, 0, &dif_opts); 685 SPDK_CU_ASSERT_FATAL(rc == 0); 686 687 req->channel = g_channel; 688 req->src_iovs = task->src_iovs; 689 req->src_iovcnt = task->src_iovcnt; 690 req->md_iov = &task->md_iov; 691 req->num_blocks = task->num_blocks; 692 req->ctx = &task->dif_ctx; 693 req->err = &task->dif_err; 694 req->cb_fn = accel_dif_oper_done; 695 req->cb_arg = task; 696 697 execute_spdk_function(accel_dix_verify_test, req); 698 699 free_dix_bufs(task); 700 } 701 702 static void 703 accel_dif_verify_op_dif_generated_guard_check(void) 704 { 705 accel_dif_verify_op_dif_generated_do_check(SPDK_DIF_FLAGS_GUARD_CHECK); 706 } 707 708 static void 709 accel_dif_verify_op_dif_generated_apptag_check(void) 710 { 711 accel_dif_verify_op_dif_generated_do_check(SPDK_DIF_FLAGS_APPTAG_CHECK); 712 } 713 714 static void 715 accel_dif_verify_op_dif_generated_reftag_check(void) 716 { 717 accel_dif_verify_op_dif_generated_do_check(SPDK_DIF_FLAGS_REFTAG_CHECK); 718 } 719 720 static void 721 accel_dix_verify_op_dix_generated_guard_check(void) 722 { 723 struct accel_dif_request req; 724 const char *module_name = NULL; 725 int rc; 726 727 rc = spdk_accel_get_opc_module_name(SPDK_ACCEL_OPC_DIX_VERIFY, &module_name); 728 SPDK_CU_ASSERT_FATAL(rc == 0); 729 730 /* Intel DSA does not allow for selective DIF fields verification for DIX */ 731 if (!strcmp(module_name, "dsa")) { 732 return; 733 } 734 735 accel_dix_generate_verify(&req, SPDK_DIF_FLAGS_GUARD_CHECK | 736 SPDK_DIF_FLAGS_APPTAG_CHECK | 737 SPDK_DIF_FLAGS_REFTAG_CHECK, SPDK_DIF_FLAGS_GUARD_CHECK); 738 739 CU_ASSERT_EQUAL(g_completion_success, true); 740 } 741 742 static void 743 accel_dix_verify_op_dix_generated_apptag_check(void) 744 { 745 struct accel_dif_request req; 746 const char *module_name = NULL; 747 int rc; 748 749 rc = spdk_accel_get_opc_module_name(SPDK_ACCEL_OPC_DIX_VERIFY, &module_name); 750 SPDK_CU_ASSERT_FATAL(rc == 0); 751 752 /* Intel DSA does not allow for selective DIF fields verification for DIX */ 753 if (!strcmp(module_name, "dsa")) { 754 return; 755 } 756 757 accel_dix_generate_verify(&req, SPDK_DIF_FLAGS_GUARD_CHECK | 758 SPDK_DIF_FLAGS_APPTAG_CHECK | 759 SPDK_DIF_FLAGS_REFTAG_CHECK, SPDK_DIF_FLAGS_APPTAG_CHECK); 760 761 CU_ASSERT_EQUAL(g_completion_success, true); 762 } 763 764 static void 765 accel_dix_verify_op_dix_generated_reftag_check(void) 766 { 767 struct accel_dif_request req; 768 const char *module_name = NULL; 769 int rc; 770 771 rc = spdk_accel_get_opc_module_name(SPDK_ACCEL_OPC_DIX_VERIFY, &module_name); 772 SPDK_CU_ASSERT_FATAL(rc == 0); 773 774 /* Intel DSA does not allow for selective DIF fields verification for DIX */ 775 if (!strcmp(module_name, "dsa")) { 776 return; 777 } 778 779 accel_dix_generate_verify(&req, SPDK_DIF_FLAGS_GUARD_CHECK | 780 SPDK_DIF_FLAGS_APPTAG_CHECK | 781 SPDK_DIF_FLAGS_REFTAG_CHECK, SPDK_DIF_FLAGS_REFTAG_CHECK); 782 783 CU_ASSERT_EQUAL(g_completion_success, true); 784 } 785 786 static void 787 accel_dix_verify_op_dix_generated_all_flags_check(void) 788 { 789 struct accel_dif_request req; 790 accel_dix_generate_verify(&req, SPDK_DIF_FLAGS_GUARD_CHECK | 791 SPDK_DIF_FLAGS_APPTAG_CHECK | 792 SPDK_DIF_FLAGS_REFTAG_CHECK, 793 SPDK_DIF_FLAGS_GUARD_CHECK | 794 SPDK_DIF_FLAGS_APPTAG_CHECK | 795 SPDK_DIF_FLAGS_REFTAG_CHECK); 796 797 CU_ASSERT_EQUAL(g_completion_success, true); 798 } 799 800 static void 801 accel_dix_verify_op_dix_not_generated_all_flags_check(void) 802 { 803 struct accel_dif_request req; 804 accel_dix_generate_verify(&req, 0, 805 SPDK_DIF_FLAGS_GUARD_CHECK | 806 SPDK_DIF_FLAGS_APPTAG_CHECK | 807 SPDK_DIF_FLAGS_REFTAG_CHECK); 808 809 CU_ASSERT_EQUAL(g_completion_success, false); 810 } 811 812 static void 813 accel_dif_verify_op_dif_not_generated_do_check(uint32_t dif_flags) 814 { 815 struct spdk_dif_ctx_init_ext_opts dif_opts; 816 struct accel_dif_request req; 817 struct dif_task *task = &g_dif_task; 818 int rc; 819 820 rc = alloc_dif_verify_bufs(task, 1); 821 SPDK_CU_ASSERT_FATAL(rc == 0); 822 823 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 824 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 825 826 rc = spdk_dif_ctx_init(&task->dif_ctx, 827 g_block_size_bytes + g_md_size_bytes, 828 g_md_size_bytes, true, true, 829 SPDK_DIF_TYPE1, 830 dif_flags, 831 10, 0xFFFF, 20, 0, 0, &dif_opts); 832 SPDK_CU_ASSERT_FATAL(rc == 0); 833 834 req.channel = g_channel; 835 req.src_iovs = task->src_iovs; 836 req.src_iovcnt = task->src_iovcnt; 837 req.num_blocks = task->num_blocks; 838 req.ctx = &task->dif_ctx; 839 req.err = &task->dif_err; 840 req.cb_fn = accel_dif_oper_done; 841 req.cb_arg = task; 842 843 execute_spdk_function(accel_dif_verify_test, &req); 844 CU_ASSERT_EQUAL(g_completion_success, false); 845 CU_ASSERT_EQUAL(accel_dif_error_validate(dif_flags, req.err), true); 846 847 free_dif_verify_bufs(task); 848 } 849 850 static void 851 accel_dif_verify_op_dif_not_generated_guard_check(void) 852 { 853 accel_dif_verify_op_dif_not_generated_do_check(SPDK_DIF_FLAGS_GUARD_CHECK); 854 } 855 856 static void 857 accel_dix_verify_op_dix_not_generated_guard_check(void) 858 { 859 const char *module_name = NULL; 860 uint32_t dif_flags_verify = SPDK_DIF_FLAGS_GUARD_CHECK; 861 struct accel_dif_request req; 862 int rc; 863 864 rc = spdk_accel_get_opc_module_name(SPDK_ACCEL_OPC_DIX_VERIFY, &module_name); 865 SPDK_CU_ASSERT_FATAL(rc == 0); 866 867 /* Intel DSA does not allow for selective DIF fields verification for DIX */ 868 if (!strcmp(module_name, "dsa")) { 869 return; 870 } 871 872 accel_dix_generate_verify(&req, 0, dif_flags_verify); 873 874 CU_ASSERT_EQUAL(g_completion_success, false); 875 CU_ASSERT_EQUAL(accel_dif_error_validate(dif_flags_verify, req.err), true); 876 } 877 878 static void 879 accel_dif_verify_op_dif_not_generated_apptag_check(void) 880 { 881 accel_dif_verify_op_dif_not_generated_do_check(SPDK_DIF_FLAGS_APPTAG_CHECK); 882 } 883 884 static void 885 accel_dix_verify_op_dix_not_generated_apptag_check(void) 886 { 887 const char *module_name = NULL; 888 uint32_t dif_flags_verify = SPDK_DIF_FLAGS_APPTAG_CHECK; 889 struct accel_dif_request req; 890 int rc; 891 892 rc = spdk_accel_get_opc_module_name(SPDK_ACCEL_OPC_DIX_VERIFY, &module_name); 893 SPDK_CU_ASSERT_FATAL(rc == 0); 894 895 /* Intel DSA does not allow for selective DIF fields verification for DIX */ 896 if (!strcmp(module_name, "dsa")) { 897 return; 898 } 899 900 accel_dix_generate_verify(&req, 0, dif_flags_verify); 901 902 CU_ASSERT_EQUAL(g_completion_success, false); 903 CU_ASSERT_EQUAL(accel_dif_error_validate(dif_flags_verify, req.err), true); 904 } 905 906 static void 907 accel_dif_verify_op_dif_not_generated_reftag_check(void) 908 { 909 accel_dif_verify_op_dif_not_generated_do_check(SPDK_DIF_FLAGS_REFTAG_CHECK); 910 } 911 912 static void 913 accel_dix_verify_op_dix_not_generated_reftag_check(void) 914 { 915 const char *module_name = NULL; 916 uint32_t dif_flags_verify = SPDK_DIF_FLAGS_REFTAG_CHECK; 917 struct accel_dif_request req; 918 int rc; 919 920 rc = spdk_accel_get_opc_module_name(SPDK_ACCEL_OPC_DIX_VERIFY, &module_name); 921 SPDK_CU_ASSERT_FATAL(rc == 0); 922 923 /* Intel DSA does not allow for selective DIF fields verification for DIX */ 924 if (!strcmp(module_name, "dsa")) { 925 return; 926 } 927 928 accel_dix_generate_verify(&req, 0, dif_flags_verify); 929 930 CU_ASSERT_EQUAL(g_completion_success, false); 931 CU_ASSERT_EQUAL(accel_dif_error_validate(dif_flags_verify, req.err), true); 932 } 933 934 static void 935 accel_dix_verify_op_dix_guard_not_generated_all_flags_check(void) 936 { 937 struct accel_dif_request req; 938 accel_dix_generate_verify(&req, 939 SPDK_DIF_FLAGS_APPTAG_CHECK | 940 SPDK_DIF_FLAGS_REFTAG_CHECK, 941 SPDK_DIF_FLAGS_GUARD_CHECK | 942 SPDK_DIF_FLAGS_APPTAG_CHECK | 943 SPDK_DIF_FLAGS_REFTAG_CHECK); 944 945 CU_ASSERT_EQUAL(g_completion_success, false); 946 CU_ASSERT_EQUAL(accel_dif_error_validate(SPDK_DIF_FLAGS_GUARD_CHECK, req.err), true); 947 } 948 949 static void 950 accel_dix_verify_op_dix_apptag_not_generated_all_flags_check(void) 951 { 952 struct accel_dif_request req; 953 accel_dix_generate_verify(&req, 954 SPDK_DIF_FLAGS_GUARD_CHECK | 955 SPDK_DIF_FLAGS_REFTAG_CHECK, 956 SPDK_DIF_FLAGS_GUARD_CHECK | 957 SPDK_DIF_FLAGS_APPTAG_CHECK | 958 SPDK_DIF_FLAGS_REFTAG_CHECK); 959 960 CU_ASSERT_EQUAL(g_completion_success, false); 961 CU_ASSERT_EQUAL(accel_dif_error_validate(SPDK_DIF_FLAGS_APPTAG_CHECK, req.err), true); 962 } 963 964 static void 965 accel_dix_verify_op_dix_reftag_not_generated_all_flags_check(void) 966 { 967 struct accel_dif_request req; 968 accel_dix_generate_verify(&req, 969 SPDK_DIF_FLAGS_GUARD_CHECK | 970 SPDK_DIF_FLAGS_APPTAG_CHECK, 971 SPDK_DIF_FLAGS_GUARD_CHECK | 972 SPDK_DIF_FLAGS_APPTAG_CHECK | 973 SPDK_DIF_FLAGS_REFTAG_CHECK); 974 975 CU_ASSERT_EQUAL(g_completion_success, false); 976 CU_ASSERT_EQUAL(accel_dif_error_validate(SPDK_DIF_FLAGS_REFTAG_CHECK, req.err), true); 977 } 978 979 static void 980 accel_dif_verify_op_apptag_correct_apptag_check(void) 981 { 982 struct spdk_dif_ctx_init_ext_opts dif_opts; 983 struct accel_dif_request req; 984 struct dif_task *task = &g_dif_task; 985 int rc; 986 987 rc = alloc_dif_verify_bufs(task, 1); 988 SPDK_CU_ASSERT_FATAL(rc == 0); 989 990 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 991 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 992 993 rc = spdk_dif_ctx_init(&task->dif_ctx, 994 g_block_size_bytes + g_md_size_bytes, 995 g_md_size_bytes, true, true, 996 SPDK_DIF_TYPE1, 997 SPDK_DIF_FLAGS_APPTAG_CHECK, 998 10, 0xFFFF, 20, 0, 0, &dif_opts); 999 SPDK_CU_ASSERT_FATAL(rc == 0); 1000 1001 rc = spdk_dif_generate(task->src_iovs, task->src_iovcnt, task->num_blocks, &task->dif_ctx); 1002 SPDK_CU_ASSERT_FATAL(rc == 0); 1003 1004 req.channel = g_channel; 1005 req.src_iovs = task->src_iovs; 1006 req.src_iovcnt = task->src_iovcnt; 1007 req.num_blocks = task->num_blocks; 1008 req.ctx = &task->dif_ctx; 1009 req.err = &task->dif_err; 1010 req.cb_fn = accel_dif_oper_done; 1011 req.cb_arg = task; 1012 1013 execute_spdk_function(accel_dif_verify_test, &req); 1014 CU_ASSERT_EQUAL(g_completion_success, true); 1015 1016 free_dif_verify_bufs(task); 1017 } 1018 1019 static void 1020 accel_dix_verify_op_apptag_correct_apptag_check(void) 1021 { 1022 const char *module_name = NULL; 1023 struct spdk_dif_ctx_init_ext_opts dif_opts; 1024 struct accel_dif_request req; 1025 struct dif_task *task = &g_dif_task; 1026 int rc; 1027 1028 rc = spdk_accel_get_opc_module_name(SPDK_ACCEL_OPC_DIX_VERIFY, &module_name); 1029 SPDK_CU_ASSERT_FATAL(rc == 0); 1030 1031 /* Intel DSA does not allow for selective DIF fields verification for DIX */ 1032 if (!strcmp(module_name, "dsa")) { 1033 return; 1034 } 1035 1036 rc = alloc_dix_bufs(task, 1); 1037 SPDK_CU_ASSERT_FATAL(rc == 0); 1038 1039 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 1040 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 1041 1042 rc = spdk_dif_ctx_init(&task->dif_ctx, 1043 g_block_size_bytes, 1044 g_md_size_bytes, false, true, 1045 SPDK_DIF_TYPE1, 1046 SPDK_DIF_FLAGS_APPTAG_CHECK, 1047 10, 0xFFFF, 20, 0, 0, &dif_opts); 1048 SPDK_CU_ASSERT_FATAL(rc == 0); 1049 1050 rc = spdk_dix_generate(task->src_iovs, task->src_iovcnt, &task->md_iov, task->num_blocks, 1051 &task->dif_ctx); 1052 SPDK_CU_ASSERT_FATAL(rc == 0); 1053 1054 req.channel = g_channel; 1055 req.src_iovs = task->src_iovs; 1056 req.src_iovcnt = task->src_iovcnt; 1057 req.md_iov = &task->md_iov; 1058 req.num_blocks = task->num_blocks; 1059 req.ctx = &task->dif_ctx; 1060 req.err = &task->dif_err; 1061 req.cb_fn = accel_dif_oper_done; 1062 req.cb_arg = task; 1063 1064 execute_spdk_function(accel_dix_verify_test, &req); 1065 1066 CU_ASSERT_EQUAL(g_completion_success, true); 1067 1068 free_dix_bufs(task); 1069 } 1070 1071 static void 1072 accel_dif_verify_op_apptag_incorrect_apptag_check(void) 1073 { 1074 struct spdk_dif_ctx_init_ext_opts dif_opts; 1075 struct accel_dif_request req; 1076 struct dif_task *task = &g_dif_task; 1077 int rc; 1078 1079 rc = alloc_dif_verify_bufs(task, 1); 1080 SPDK_CU_ASSERT_FATAL(rc == 0); 1081 1082 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 1083 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 1084 1085 rc = spdk_dif_ctx_init(&task->dif_ctx, 1086 g_block_size_bytes + g_md_size_bytes, 1087 g_md_size_bytes, true, true, 1088 SPDK_DIF_TYPE1, 1089 SPDK_DIF_FLAGS_APPTAG_CHECK, 1090 10, 0xFFFF, 20, 0, 0, &dif_opts); 1091 SPDK_CU_ASSERT_FATAL(rc == 0); 1092 1093 rc = spdk_dif_generate(task->src_iovs, task->src_iovcnt, task->num_blocks, &task->dif_ctx); 1094 SPDK_CU_ASSERT_FATAL(rc == 0); 1095 1096 rc = spdk_dif_ctx_init(&task->dif_ctx, 1097 g_block_size_bytes + g_md_size_bytes, 1098 g_md_size_bytes, true, true, 1099 SPDK_DIF_TYPE1, 1100 SPDK_DIF_FLAGS_APPTAG_CHECK, 1101 30, 0xFFFF, 40, 0, 0, &dif_opts); 1102 SPDK_CU_ASSERT_FATAL(rc == 0); 1103 1104 req.channel = g_channel; 1105 req.src_iovs = task->src_iovs; 1106 req.src_iovcnt = task->src_iovcnt; 1107 req.num_blocks = task->num_blocks; 1108 req.ctx = &task->dif_ctx; 1109 req.err = &task->dif_err; 1110 req.cb_fn = accel_dif_oper_done; 1111 req.cb_arg = task; 1112 1113 execute_spdk_function(accel_dif_verify_test, &req); 1114 CU_ASSERT_EQUAL(g_completion_success, false); 1115 1116 free_dif_verify_bufs(task); 1117 } 1118 1119 static void 1120 accel_dix_verify_op_apptag_incorrect_apptag_check(void) 1121 { 1122 struct spdk_dif_ctx_init_ext_opts dif_opts; 1123 struct accel_dif_request req; 1124 struct dif_task *task = &g_dif_task; 1125 int rc; 1126 1127 rc = alloc_dix_bufs(task, 1); 1128 SPDK_CU_ASSERT_FATAL(rc == 0); 1129 1130 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 1131 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 1132 1133 rc = spdk_dif_ctx_init(&task->dif_ctx, 1134 g_block_size_bytes, 1135 g_md_size_bytes, false, true, 1136 SPDK_DIF_TYPE1, 1137 SPDK_DIF_FLAGS_APPTAG_CHECK, 1138 10, 0xFFFF, 20, 0, 0, &dif_opts); 1139 SPDK_CU_ASSERT_FATAL(rc == 0); 1140 1141 rc = spdk_dix_generate(task->src_iovs, task->src_iovcnt, &task->md_iov, task->num_blocks, 1142 &task->dif_ctx); 1143 SPDK_CU_ASSERT_FATAL(rc == 0); 1144 1145 rc = spdk_dif_ctx_init(&task->dif_ctx, 1146 g_block_size_bytes, 1147 g_md_size_bytes, false, true, 1148 SPDK_DIF_TYPE1, 1149 SPDK_DIF_FLAGS_APPTAG_CHECK, 1150 30, 0xFFFF, 40, 0, 0, &dif_opts); 1151 SPDK_CU_ASSERT_FATAL(rc == 0); 1152 1153 req.channel = g_channel; 1154 req.src_iovs = task->src_iovs; 1155 req.src_iovcnt = task->src_iovcnt; 1156 req.md_iov = &task->md_iov; 1157 req.num_blocks = task->num_blocks; 1158 req.ctx = &task->dif_ctx; 1159 req.err = &task->dif_err; 1160 req.cb_fn = accel_dif_oper_done; 1161 req.cb_arg = task; 1162 1163 execute_spdk_function(accel_dix_verify_test, &req); 1164 CU_ASSERT_EQUAL(g_completion_success, false); 1165 1166 free_dix_bufs(task); 1167 } 1168 1169 static void 1170 accel_dif_verify_op_tag_incorrect_no_check_or_ignore(uint32_t dif_flags) 1171 { 1172 struct spdk_dif_ctx_init_ext_opts dif_opts; 1173 struct accel_dif_request req; 1174 struct dif_task *task = &g_dif_task; 1175 int rc; 1176 1177 rc = alloc_dif_verify_bufs(task, 1); 1178 SPDK_CU_ASSERT_FATAL(rc == 0); 1179 1180 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 1181 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 1182 1183 /* For set 'Application Tag F Detect' (Source DIF Flags) 1184 * When all bits of the Application Tag field of the source Data Integrity Field 1185 * are equal to 1, the Application Tag check is not done and the Guard field and 1186 * Reference Tag field are ignored. */ 1187 rc = spdk_dif_ctx_init(&task->dif_ctx, 1188 g_block_size_bytes + g_md_size_bytes, 1189 g_md_size_bytes, true, true, 1190 SPDK_DIF_TYPE1, 1191 SPDK_DIF_FLAGS_GUARD_CHECK | 1192 SPDK_DIF_FLAGS_APPTAG_CHECK | 1193 SPDK_DIF_FLAGS_REFTAG_CHECK, 1194 10, 0xFFFF, 0xFFFF, 0, 0, &dif_opts); 1195 SPDK_CU_ASSERT_FATAL(rc == 0); 1196 1197 rc = spdk_dif_generate(task->src_iovs, task->src_iovcnt, task->num_blocks, &task->dif_ctx); 1198 SPDK_CU_ASSERT_FATAL(rc == 0); 1199 1200 rc = spdk_dif_ctx_init(&task->dif_ctx, 1201 g_block_size_bytes + g_md_size_bytes, 1202 g_md_size_bytes, true, true, 1203 SPDK_DIF_TYPE1, 1204 dif_flags, 1205 30, 0xFFFF, 40, 0, 0, &dif_opts); 1206 SPDK_CU_ASSERT_FATAL(rc == 0); 1207 1208 req.channel = g_channel; 1209 req.src_iovs = task->src_iovs; 1210 req.src_iovcnt = task->src_iovcnt; 1211 req.num_blocks = task->num_blocks; 1212 req.ctx = &task->dif_ctx; 1213 req.err = &task->dif_err; 1214 req.cb_fn = accel_dif_oper_done; 1215 req.cb_arg = task; 1216 1217 execute_spdk_function(accel_dif_verify_test, &req); 1218 CU_ASSERT_EQUAL(g_completion_success, true); 1219 1220 free_dif_verify_bufs(task); 1221 } 1222 1223 static void 1224 accel_dix_verify_op_tag_incorrect_no_check_or_ignore(uint32_t dif_flags) 1225 { 1226 const char *module_name = NULL; 1227 struct spdk_dif_ctx_init_ext_opts dif_opts; 1228 struct accel_dif_request req; 1229 struct dif_task *task = &g_dif_task; 1230 int rc; 1231 1232 rc = spdk_accel_get_opc_module_name(SPDK_ACCEL_OPC_DIX_VERIFY, &module_name); 1233 SPDK_CU_ASSERT_FATAL(rc == 0); 1234 1235 /* Intel DSA does not allow for selective DIF fields verify for DIX */ 1236 if (!strcmp(module_name, "dsa") && (dif_flags != (SPDK_DIF_FLAGS_GUARD_CHECK | 1237 SPDK_DIF_FLAGS_APPTAG_CHECK | 1238 SPDK_DIF_FLAGS_REFTAG_CHECK))) { 1239 return; 1240 } 1241 1242 rc = alloc_dix_bufs(task, 1); 1243 SPDK_CU_ASSERT_FATAL(rc == 0); 1244 1245 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 1246 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 1247 1248 /* For set 'Application Tag F Detect' (Source DIF Flags) 1249 * When all bits of the Application Tag field of the source Data Integrity Field 1250 * are equal to 1, the Application Tag check is not done and the Guard field and 1251 * Reference Tag field are ignored. */ 1252 rc = spdk_dif_ctx_init(&task->dif_ctx, 1253 g_block_size_bytes, 1254 g_md_size_bytes, false, true, 1255 SPDK_DIF_TYPE1, 1256 SPDK_DIF_FLAGS_GUARD_CHECK | 1257 SPDK_DIF_FLAGS_APPTAG_CHECK | 1258 SPDK_DIF_FLAGS_REFTAG_CHECK, 1259 10, 0xFFFF, 0xFFFF, 0, 0, &dif_opts); 1260 SPDK_CU_ASSERT_FATAL(rc == 0); 1261 1262 rc = spdk_dix_generate(task->src_iovs, task->src_iovcnt, &task->md_iov, task->num_blocks, 1263 &task->dif_ctx); 1264 SPDK_CU_ASSERT_FATAL(rc == 0); 1265 1266 rc = spdk_dif_ctx_init(&task->dif_ctx, 1267 g_block_size_bytes, 1268 g_md_size_bytes, false, true, 1269 SPDK_DIF_TYPE1, 1270 dif_flags, 1271 30, 0xFFFF, 40, 0, 0, &dif_opts); 1272 SPDK_CU_ASSERT_FATAL(rc == 0); 1273 1274 req.channel = g_channel; 1275 req.src_iovs = task->src_iovs; 1276 req.src_iovcnt = task->src_iovcnt; 1277 req.md_iov = &task->md_iov; 1278 req.num_blocks = task->num_blocks; 1279 req.ctx = &task->dif_ctx; 1280 req.err = &task->dif_err; 1281 req.cb_fn = accel_dif_oper_done; 1282 req.cb_arg = task; 1283 1284 execute_spdk_function(accel_dix_verify_test, &req); 1285 1286 CU_ASSERT_EQUAL(g_completion_success, true); 1287 1288 free_dix_bufs(task); 1289 } 1290 1291 static void 1292 accel_dif_verify_op_apptag_incorrect_no_apptag_check(void) 1293 { 1294 accel_dif_verify_op_tag_incorrect_no_check_or_ignore(SPDK_DIF_FLAGS_APPTAG_CHECK); 1295 } 1296 1297 static void 1298 accel_dix_verify_op_apptag_incorrect_no_apptag_check(void) 1299 { 1300 accel_dix_verify_op_tag_incorrect_no_check_or_ignore(SPDK_DIF_FLAGS_APPTAG_CHECK); 1301 } 1302 1303 static void 1304 accel_dif_verify_op_reftag_incorrect_reftag_ignore(void) 1305 { 1306 accel_dif_verify_op_tag_incorrect_no_check_or_ignore(SPDK_DIF_FLAGS_REFTAG_CHECK); 1307 } 1308 1309 static void 1310 accel_dix_verify_op_reftag_incorrect_reftag_ignore(void) 1311 { 1312 accel_dix_verify_op_tag_incorrect_no_check_or_ignore(SPDK_DIF_FLAGS_REFTAG_CHECK); 1313 } 1314 1315 static void 1316 accel_dif_verify_op_reftag_init_correct_reftag_check(void) 1317 { 1318 struct spdk_dif_ctx_init_ext_opts dif_opts; 1319 struct accel_dif_request req; 1320 struct dif_task *task = &g_dif_task; 1321 int rc; 1322 1323 rc = alloc_dif_verify_bufs(task, 2); 1324 SPDK_CU_ASSERT_FATAL(rc == 0); 1325 1326 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 1327 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 1328 1329 rc = spdk_dif_ctx_init(&task->dif_ctx, 1330 g_block_size_bytes + g_md_size_bytes, 1331 g_md_size_bytes, true, true, 1332 SPDK_DIF_TYPE1, 1333 SPDK_DIF_FLAGS_REFTAG_CHECK, 1334 10, 0xFFFF, 20, 0, 0, &dif_opts); 1335 SPDK_CU_ASSERT_FATAL(rc == 0); 1336 1337 rc = spdk_dif_generate(task->src_iovs, task->src_iovcnt, task->num_blocks, &task->dif_ctx); 1338 SPDK_CU_ASSERT_FATAL(rc == 0); 1339 1340 req.channel = g_channel; 1341 req.src_iovs = task->src_iovs; 1342 req.src_iovcnt = task->src_iovcnt; 1343 req.num_blocks = task->num_blocks; 1344 req.ctx = &task->dif_ctx; 1345 req.err = &task->dif_err; 1346 req.cb_fn = accel_dif_oper_done; 1347 req.cb_arg = task; 1348 1349 execute_spdk_function(accel_dif_verify_test, &req); 1350 CU_ASSERT_EQUAL(g_completion_success, true); 1351 1352 free_dif_verify_bufs(task); 1353 } 1354 1355 static void 1356 accel_dix_verify_op_reftag_init_correct_reftag_check(void) 1357 { 1358 const char *module_name = NULL; 1359 struct spdk_dif_ctx_init_ext_opts dif_opts; 1360 struct accel_dif_request req; 1361 struct dif_task *task = &g_dif_task; 1362 int rc; 1363 1364 rc = spdk_accel_get_opc_module_name(SPDK_ACCEL_OPC_DIX_VERIFY, &module_name); 1365 SPDK_CU_ASSERT_FATAL(rc == 0); 1366 1367 /* Intel DSA does not allow for selective DIF fields verification for DIX */ 1368 if (!strcmp(module_name, "dsa")) { 1369 return; 1370 } 1371 1372 rc = alloc_dix_bufs(task, 2); 1373 SPDK_CU_ASSERT_FATAL(rc == 0); 1374 1375 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 1376 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 1377 1378 rc = spdk_dif_ctx_init(&task->dif_ctx, 1379 g_block_size_bytes, 1380 g_md_size_bytes, false, true, 1381 SPDK_DIF_TYPE1, 1382 SPDK_DIF_FLAGS_REFTAG_CHECK, 1383 10, 0xFFFF, 20, 0, 0, &dif_opts); 1384 SPDK_CU_ASSERT_FATAL(rc == 0); 1385 1386 rc = spdk_dix_generate(task->src_iovs, task->src_iovcnt, &task->md_iov, task->num_blocks, 1387 &task->dif_ctx); 1388 SPDK_CU_ASSERT_FATAL(rc == 0); 1389 1390 req.channel = g_channel; 1391 req.src_iovs = task->src_iovs; 1392 req.src_iovcnt = task->src_iovcnt; 1393 req.md_iov = &task->md_iov; 1394 req.num_blocks = task->num_blocks; 1395 req.ctx = &task->dif_ctx; 1396 req.err = &task->dif_err; 1397 req.cb_fn = accel_dif_oper_done; 1398 req.cb_arg = task; 1399 1400 execute_spdk_function(accel_dix_verify_test, &req); 1401 1402 CU_ASSERT_EQUAL(g_completion_success, true); 1403 1404 free_dix_bufs(task); 1405 } 1406 1407 static void 1408 accel_dif_verify_op_reftag_init_incorrect_reftag_check(void) 1409 { 1410 struct spdk_dif_ctx_init_ext_opts dif_opts; 1411 struct accel_dif_request req; 1412 struct dif_task *task = &g_dif_task; 1413 int rc; 1414 1415 rc = alloc_dif_verify_bufs(task, 2); 1416 SPDK_CU_ASSERT_FATAL(rc == 0); 1417 1418 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 1419 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 1420 1421 rc = spdk_dif_ctx_init(&task->dif_ctx, 1422 g_block_size_bytes + g_md_size_bytes, 1423 g_md_size_bytes, true, true, 1424 SPDK_DIF_TYPE1, 1425 SPDK_DIF_FLAGS_REFTAG_CHECK, 1426 16, 0xFFFF, 20, 0, 0, &dif_opts); 1427 SPDK_CU_ASSERT_FATAL(rc == 0); 1428 1429 rc = spdk_dif_generate(task->src_iovs, task->src_iovcnt, task->num_blocks, &task->dif_ctx); 1430 SPDK_CU_ASSERT_FATAL(rc == 0); 1431 1432 rc = spdk_dif_ctx_init(&task->dif_ctx, 1433 g_block_size_bytes + g_md_size_bytes, 1434 g_md_size_bytes, true, true, 1435 SPDK_DIF_TYPE1, 1436 SPDK_DIF_FLAGS_REFTAG_CHECK, 1437 10, 0xFFFF, 20, 0, 0, &dif_opts); 1438 SPDK_CU_ASSERT_FATAL(rc == 0); 1439 1440 req.channel = g_channel; 1441 req.src_iovs = task->src_iovs; 1442 req.src_iovcnt = task->src_iovcnt; 1443 req.num_blocks = task->num_blocks; 1444 req.ctx = &task->dif_ctx; 1445 req.err = &task->dif_err; 1446 req.cb_fn = accel_dif_oper_done; 1447 req.cb_arg = task; 1448 1449 execute_spdk_function(accel_dif_verify_test, &req); 1450 CU_ASSERT_EQUAL(g_completion_success, false); 1451 1452 free_dif_verify_bufs(task); 1453 } 1454 1455 static void 1456 accel_dix_verify_op_reftag_init_incorrect_reftag_check(void) 1457 { 1458 struct spdk_dif_ctx_init_ext_opts dif_opts; 1459 struct accel_dif_request req; 1460 struct dif_task *task = &g_dif_task; 1461 int rc; 1462 1463 rc = alloc_dix_bufs(task, 2); 1464 SPDK_CU_ASSERT_FATAL(rc == 0); 1465 1466 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 1467 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 1468 1469 rc = spdk_dif_ctx_init(&task->dif_ctx, 1470 g_block_size_bytes, 1471 g_md_size_bytes, false, true, 1472 SPDK_DIF_TYPE1, 1473 SPDK_DIF_FLAGS_REFTAG_CHECK, 1474 16, 0xFFFF, 20, 0, 0, &dif_opts); 1475 SPDK_CU_ASSERT_FATAL(rc == 0); 1476 1477 rc = spdk_dix_generate(task->src_iovs, task->src_iovcnt, &task->md_iov, task->num_blocks, 1478 &task->dif_ctx); 1479 SPDK_CU_ASSERT_FATAL(rc == 0); 1480 1481 rc = spdk_dif_ctx_init(&task->dif_ctx, 1482 g_block_size_bytes, 1483 g_md_size_bytes, false, true, 1484 SPDK_DIF_TYPE1, 1485 SPDK_DIF_FLAGS_REFTAG_CHECK, 1486 10, 0xFFFF, 20, 0, 0, &dif_opts); 1487 SPDK_CU_ASSERT_FATAL(rc == 0); 1488 1489 req.channel = g_channel; 1490 req.src_iovs = task->src_iovs; 1491 req.src_iovcnt = task->src_iovcnt; 1492 req.md_iov = &task->md_iov; 1493 req.num_blocks = task->num_blocks; 1494 req.ctx = &task->dif_ctx; 1495 req.err = &task->dif_err; 1496 req.cb_fn = accel_dif_oper_done; 1497 req.cb_arg = task; 1498 1499 execute_spdk_function(accel_dix_verify_test, &req); 1500 CU_ASSERT_EQUAL(g_completion_success, false); 1501 1502 free_dix_bufs(task); 1503 } 1504 1505 static void 1506 accel_dif_verify_copy_op_dif_generated_do_check(uint32_t dif_flags) 1507 { 1508 struct spdk_dif_ctx_init_ext_opts dif_opts; 1509 struct accel_dif_request req; 1510 struct dif_task *task = &g_dif_task; 1511 int rc; 1512 1513 rc = alloc_dif_verify_copy_bufs(task, 1); 1514 SPDK_CU_ASSERT_FATAL(rc == 0); 1515 1516 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 1517 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 1518 1519 rc = spdk_dif_ctx_init(&task->dif_ctx, 1520 g_block_size_bytes + g_md_size_bytes, 1521 g_md_size_bytes, true, true, 1522 SPDK_DIF_TYPE1, 1523 SPDK_DIF_FLAGS_GUARD_CHECK | 1524 SPDK_DIF_FLAGS_APPTAG_CHECK | 1525 SPDK_DIF_FLAGS_REFTAG_CHECK, 1526 10, 0xFFFF, 20, 0, 0, &dif_opts); 1527 SPDK_CU_ASSERT_FATAL(rc == 0); 1528 1529 rc = spdk_dif_generate(task->src_iovs, task->src_iovcnt, task->num_blocks, &task->dif_ctx); 1530 SPDK_CU_ASSERT_FATAL(rc == 0); 1531 1532 rc = spdk_dif_ctx_init(&task->dif_ctx, 1533 g_block_size_bytes + g_md_size_bytes, 1534 g_md_size_bytes, true, true, 1535 SPDK_DIF_TYPE1, 1536 dif_flags, 1537 10, 0xFFFF, 20, 0, 0, &dif_opts); 1538 SPDK_CU_ASSERT_FATAL(rc == 0); 1539 1540 req.channel = g_channel; 1541 req.dst_iovs = task->dst_iovs; 1542 req.dst_iovcnt = task->dst_iovcnt; 1543 req.src_iovs = task->src_iovs; 1544 req.src_iovcnt = task->src_iovcnt; 1545 req.num_blocks = task->num_blocks; 1546 req.ctx = &task->dif_ctx; 1547 req.err = &task->dif_err; 1548 req.cb_fn = accel_dif_oper_done; 1549 req.cb_arg = task; 1550 1551 execute_spdk_function(accel_dif_verify_copy_test, &req); 1552 CU_ASSERT_EQUAL(g_completion_success, true); 1553 1554 free_dif_verify_copy_bufs(task); 1555 } 1556 1557 static void 1558 accel_dif_verify_copy_op_dif_generated_guard_check(void) 1559 { 1560 accel_dif_verify_copy_op_dif_generated_do_check(SPDK_DIF_FLAGS_GUARD_CHECK); 1561 } 1562 1563 static void 1564 accel_dif_verify_copy_op_dif_generated_apptag_check(void) 1565 { 1566 accel_dif_verify_copy_op_dif_generated_do_check(SPDK_DIF_FLAGS_APPTAG_CHECK); 1567 } 1568 1569 static void 1570 accel_dif_verify_copy_op_dif_generated_reftag_check(void) 1571 { 1572 accel_dif_verify_copy_op_dif_generated_do_check(SPDK_DIF_FLAGS_REFTAG_CHECK); 1573 } 1574 1575 static void 1576 accel_dif_verify_copy_op_dif_not_generated_do_check(uint32_t dif_flags) 1577 { 1578 struct spdk_dif_ctx_init_ext_opts dif_opts; 1579 struct accel_dif_request req; 1580 struct dif_task *task = &g_dif_task; 1581 int rc; 1582 1583 rc = alloc_dif_verify_copy_bufs(task, 1); 1584 SPDK_CU_ASSERT_FATAL(rc == 0); 1585 1586 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 1587 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 1588 1589 rc = spdk_dif_ctx_init(&task->dif_ctx, 1590 g_block_size_bytes + g_md_size_bytes, 1591 g_md_size_bytes, true, true, 1592 SPDK_DIF_TYPE1, 1593 dif_flags, 1594 10, 0xFFFF, 20, 0, 0, &dif_opts); 1595 SPDK_CU_ASSERT_FATAL(rc == 0); 1596 1597 req.channel = g_channel; 1598 req.dst_iovs = task->dst_iovs; 1599 req.dst_iovcnt = task->dst_iovcnt; 1600 req.src_iovs = task->src_iovs; 1601 req.src_iovcnt = task->src_iovcnt; 1602 req.num_blocks = task->num_blocks; 1603 req.ctx = &task->dif_ctx; 1604 req.err = &task->dif_err; 1605 req.cb_fn = accel_dif_oper_done; 1606 req.cb_arg = task; 1607 1608 execute_spdk_function(accel_dif_verify_copy_test, &req); 1609 CU_ASSERT_EQUAL(g_completion_success, false); 1610 CU_ASSERT_EQUAL(accel_dif_error_validate(dif_flags, req.err), true); 1611 1612 free_dif_verify_copy_bufs(task); 1613 } 1614 1615 static void 1616 accel_dif_verify_copy_op_dif_not_generated_guard_check(void) 1617 { 1618 accel_dif_verify_copy_op_dif_not_generated_do_check(SPDK_DIF_FLAGS_GUARD_CHECK); 1619 } 1620 1621 static void 1622 accel_dif_verify_copy_op_dif_not_generated_apptag_check(void) 1623 { 1624 accel_dif_verify_copy_op_dif_not_generated_do_check(SPDK_DIF_FLAGS_APPTAG_CHECK); 1625 } 1626 1627 static void 1628 accel_dif_verify_copy_op_dif_not_generated_reftag_check(void) 1629 { 1630 accel_dif_verify_copy_op_dif_not_generated_do_check(SPDK_DIF_FLAGS_REFTAG_CHECK); 1631 } 1632 1633 static void 1634 accel_dif_generate_copy_op_dif_generated_do_check(uint32_t dif_flags) 1635 { 1636 struct spdk_dif_ctx_init_ext_opts dif_opts; 1637 struct accel_dif_request req; 1638 struct dif_task *task = &g_dif_task; 1639 struct spdk_dif_error err_blk; 1640 int rc; 1641 1642 rc = alloc_dif_generate_copy_bufs(task, 1); 1643 SPDK_CU_ASSERT_FATAL(rc == 0); 1644 1645 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 1646 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 1647 1648 rc = spdk_dif_ctx_init(&task->dif_ctx, 1649 g_block_size_bytes + g_md_size_bytes, 1650 g_md_size_bytes, true, true, 1651 SPDK_DIF_TYPE1, 1652 SPDK_DIF_FLAGS_GUARD_CHECK | 1653 SPDK_DIF_FLAGS_APPTAG_CHECK | 1654 SPDK_DIF_FLAGS_REFTAG_CHECK, 1655 16, 0xFFFF, 10, 0, 0, &dif_opts); 1656 SPDK_CU_ASSERT_FATAL(rc == 0); 1657 1658 req.channel = g_channel; 1659 req.dst_iovs = task->dst_iovs; 1660 req.dst_iovcnt = task->dst_iovcnt; 1661 req.src_iovs = task->src_iovs; 1662 req.src_iovcnt = task->src_iovcnt; 1663 req.num_blocks = task->num_blocks; 1664 req.ctx = &task->dif_ctx; 1665 req.err = &task->dif_err; 1666 req.cb_fn = accel_dif_oper_done; 1667 req.cb_arg = task; 1668 1669 execute_spdk_function(accel_dif_generate_copy_test, &req); 1670 CU_ASSERT_EQUAL(g_completion_success, true); 1671 1672 rc = spdk_dif_ctx_init(&task->dif_ctx, 1673 g_block_size_bytes + g_md_size_bytes, 1674 g_md_size_bytes, true, true, 1675 SPDK_DIF_TYPE1, 1676 dif_flags, 1677 16, 0xFFFF, 10, 0, 0, &dif_opts); 1678 SPDK_CU_ASSERT_FATAL(rc == 0); 1679 1680 rc = spdk_dif_verify(req.dst_iovs, req.dst_iovcnt, req.num_blocks, 1681 &task->dif_ctx, &err_blk); 1682 SPDK_CU_ASSERT_FATAL(rc == 0); 1683 1684 free_dif_generate_copy_bufs(task); 1685 } 1686 1687 static void 1688 accel_dix_generate_op_dix_generated_do_check(uint32_t dif_flags) 1689 { 1690 struct spdk_dif_ctx_init_ext_opts dif_opts; 1691 struct accel_dif_request req; 1692 struct dif_task *task = &g_dif_task; 1693 struct spdk_dif_error err_blk; 1694 int rc; 1695 1696 rc = alloc_dix_bufs(task, 3); 1697 SPDK_CU_ASSERT_FATAL(rc == 0); 1698 1699 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 1700 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 1701 1702 rc = spdk_dif_ctx_init(&task->dif_ctx, 1703 g_block_size_bytes, 1704 g_md_size_bytes, false, true, 1705 SPDK_DIF_TYPE1, 1706 SPDK_DIF_FLAGS_GUARD_CHECK | 1707 SPDK_DIF_FLAGS_APPTAG_CHECK | 1708 SPDK_DIF_FLAGS_REFTAG_CHECK, 1709 10, 0xFFFF, 20, 0, 0, &dif_opts); 1710 SPDK_CU_ASSERT_FATAL(rc == 0); 1711 1712 req.channel = g_channel; 1713 req.src_iovs = task->src_iovs; 1714 req.src_iovcnt = task->src_iovcnt; 1715 req.md_iov = &task->md_iov; 1716 req.num_blocks = task->num_blocks; 1717 req.ctx = &task->dif_ctx; 1718 req.err = &task->dif_err; 1719 req.cb_fn = accel_dif_oper_done; 1720 req.cb_arg = task; 1721 1722 execute_spdk_function(accel_dix_generate_test, &req); 1723 CU_ASSERT_EQUAL(g_completion_success, true); 1724 1725 rc = spdk_dif_ctx_init(&task->dif_ctx, 1726 g_block_size_bytes, 1727 g_md_size_bytes, false, true, 1728 SPDK_DIF_TYPE1, 1729 dif_flags, 1730 10, 0xFFFF, 20, 0, 0, &dif_opts); 1731 SPDK_CU_ASSERT_FATAL(rc == 0); 1732 1733 rc = spdk_dix_verify(req.src_iovs, req.src_iovcnt, req.md_iov, req.num_blocks, 1734 &task->dif_ctx, &err_blk); 1735 CU_ASSERT_EQUAL(rc, 0); 1736 1737 free_dix_bufs(task); 1738 } 1739 1740 static void 1741 accel_dif_generate_copy_op_dif_generated_guard_check(void) 1742 { 1743 accel_dif_generate_copy_op_dif_generated_do_check(SPDK_DIF_FLAGS_GUARD_CHECK); 1744 } 1745 1746 static void 1747 accel_dix_generate_op_dix_generated_guard_check(void) 1748 { 1749 accel_dix_generate_op_dix_generated_do_check(SPDK_DIF_FLAGS_GUARD_CHECK); 1750 } 1751 1752 static void 1753 accel_dif_generate_copy_op_dif_generated_apptag_check(void) 1754 { 1755 accel_dif_generate_copy_op_dif_generated_do_check(SPDK_DIF_FLAGS_APPTAG_CHECK); 1756 } 1757 1758 static void 1759 accel_dix_generate_op_dix_generated_apptag_check(void) 1760 { 1761 accel_dix_generate_op_dix_generated_do_check(SPDK_DIF_FLAGS_APPTAG_CHECK); 1762 } 1763 1764 static void 1765 accel_dif_generate_copy_op_dif_generated_reftag_check(void) 1766 { 1767 accel_dif_generate_copy_op_dif_generated_do_check(SPDK_DIF_FLAGS_REFTAG_CHECK); 1768 } 1769 1770 static void 1771 accel_dix_generate_op_dix_generated_reftag_check(void) 1772 { 1773 accel_dix_generate_op_dix_generated_do_check(SPDK_DIF_FLAGS_REFTAG_CHECK); 1774 } 1775 1776 static void 1777 accel_dif_generate_copy_op_dif_generated_no_guard_check_flag_set(void) 1778 { 1779 const char *module_name = NULL; 1780 struct spdk_dif_ctx_init_ext_opts dif_opts; 1781 struct accel_dif_request req; 1782 struct dif_task *task = &g_dif_task; 1783 int rc; 1784 1785 rc = spdk_accel_get_opc_module_name(SPDK_ACCEL_OPC_DIF_GENERATE_COPY, &module_name); 1786 SPDK_CU_ASSERT_FATAL(rc == 0); 1787 1788 rc = alloc_dif_generate_copy_bufs(task, 1); 1789 SPDK_CU_ASSERT_FATAL(rc == 0); 1790 1791 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 1792 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 1793 1794 rc = spdk_dif_ctx_init(&task->dif_ctx, 1795 g_block_size_bytes + g_md_size_bytes, 1796 g_md_size_bytes, true, true, 1797 SPDK_DIF_TYPE1, 1798 SPDK_DIF_FLAGS_APPTAG_CHECK | 1799 SPDK_DIF_FLAGS_REFTAG_CHECK, 1800 16, 0xFFFF, 10, 0, 0, &dif_opts); 1801 SPDK_CU_ASSERT_FATAL(rc == 0); 1802 1803 req.channel = g_channel; 1804 req.dst_iovs = task->dst_iovs; 1805 req.dst_iovcnt = task->dst_iovcnt; 1806 req.src_iovs = task->src_iovs; 1807 req.src_iovcnt = task->src_iovcnt; 1808 req.num_blocks = task->num_blocks; 1809 req.ctx = &task->dif_ctx; 1810 req.err = &task->dif_err; 1811 req.cb_fn = accel_dif_oper_done; 1812 req.cb_arg = task; 1813 1814 execute_spdk_function(accel_dif_generate_copy_test, &req); 1815 1816 /* Intel DSA does not allow for selective DIF fields generation */ 1817 if (!strcmp(module_name, "dsa")) { 1818 CU_ASSERT_EQUAL(g_completion_success, false); 1819 } else if (!strcmp(module_name, "software")) { 1820 CU_ASSERT_EQUAL(g_completion_success, true); 1821 } else { 1822 SPDK_CU_ASSERT_FATAL(false); 1823 } 1824 1825 free_dif_generate_copy_bufs(task); 1826 } 1827 1828 static void 1829 accel_dif_generate_copy_op_dif_generated_no_apptag_check_flag_set(void) 1830 { 1831 const char *module_name = NULL; 1832 struct spdk_dif_ctx_init_ext_opts dif_opts; 1833 struct accel_dif_request req; 1834 struct dif_task *task = &g_dif_task; 1835 int rc; 1836 1837 rc = spdk_accel_get_opc_module_name(SPDK_ACCEL_OPC_DIF_GENERATE_COPY, &module_name); 1838 SPDK_CU_ASSERT_FATAL(rc == 0); 1839 1840 rc = alloc_dif_generate_copy_bufs(task, 1); 1841 SPDK_CU_ASSERT_FATAL(rc == 0); 1842 1843 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 1844 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 1845 1846 rc = spdk_dif_ctx_init(&task->dif_ctx, 1847 g_block_size_bytes + g_md_size_bytes, 1848 g_md_size_bytes, true, true, 1849 SPDK_DIF_TYPE1, 1850 SPDK_DIF_FLAGS_GUARD_CHECK | 1851 SPDK_DIF_FLAGS_REFTAG_CHECK, 1852 16, 0xFFFF, 10, 0, 0, &dif_opts); 1853 SPDK_CU_ASSERT_FATAL(rc == 0); 1854 1855 req.channel = g_channel; 1856 req.dst_iovs = task->dst_iovs; 1857 req.dst_iovcnt = task->dst_iovcnt; 1858 req.src_iovs = task->src_iovs; 1859 req.src_iovcnt = task->src_iovcnt; 1860 req.num_blocks = task->num_blocks; 1861 req.ctx = &task->dif_ctx; 1862 req.err = &task->dif_err; 1863 req.cb_fn = accel_dif_oper_done; 1864 req.cb_arg = task; 1865 1866 execute_spdk_function(accel_dif_generate_copy_test, &req); 1867 1868 /* Intel DSA does not allow for selective DIF fields generation */ 1869 if (!strcmp(module_name, "dsa")) { 1870 CU_ASSERT_EQUAL(g_completion_success, false); 1871 } else if (!strcmp(module_name, "software")) { 1872 CU_ASSERT_EQUAL(g_completion_success, true); 1873 } else { 1874 SPDK_CU_ASSERT_FATAL(false); 1875 } 1876 1877 free_dif_generate_copy_bufs(task); 1878 } 1879 1880 static void 1881 accel_dif_generate_copy_op_dif_generated_no_reftag_check_flag_set(void) 1882 { 1883 const char *module_name = NULL; 1884 struct spdk_dif_ctx_init_ext_opts dif_opts; 1885 struct accel_dif_request req; 1886 struct dif_task *task = &g_dif_task; 1887 int rc; 1888 1889 rc = spdk_accel_get_opc_module_name(SPDK_ACCEL_OPC_DIF_GENERATE_COPY, &module_name); 1890 SPDK_CU_ASSERT_FATAL(rc == 0); 1891 1892 rc = alloc_dif_generate_copy_bufs(task, 1); 1893 SPDK_CU_ASSERT_FATAL(rc == 0); 1894 1895 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 1896 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 1897 1898 rc = spdk_dif_ctx_init(&task->dif_ctx, 1899 g_block_size_bytes + g_md_size_bytes, 1900 g_md_size_bytes, true, true, 1901 SPDK_DIF_TYPE1, 1902 SPDK_DIF_FLAGS_GUARD_CHECK | 1903 SPDK_DIF_FLAGS_APPTAG_CHECK, 1904 16, 0xFFFF, 10, 0, 0, &dif_opts); 1905 SPDK_CU_ASSERT_FATAL(rc == 0); 1906 1907 req.channel = g_channel; 1908 req.dst_iovs = task->dst_iovs; 1909 req.dst_iovcnt = task->dst_iovcnt; 1910 req.src_iovs = task->src_iovs; 1911 req.src_iovcnt = task->src_iovcnt; 1912 req.num_blocks = task->num_blocks; 1913 req.ctx = &task->dif_ctx; 1914 req.err = &task->dif_err; 1915 req.cb_fn = accel_dif_oper_done; 1916 req.cb_arg = task; 1917 1918 execute_spdk_function(accel_dif_generate_copy_test, &req); 1919 1920 /* Intel DSA does not allow for selective DIF fields generation */ 1921 if (!strcmp(module_name, "dsa")) { 1922 CU_ASSERT_EQUAL(g_completion_success, false); 1923 } else if (!strcmp(module_name, "software")) { 1924 CU_ASSERT_EQUAL(g_completion_success, true); 1925 } else { 1926 SPDK_CU_ASSERT_FATAL(false); 1927 } 1928 1929 free_dif_generate_copy_bufs(task); 1930 } 1931 1932 static void 1933 accel_dif_generate_copy_op_iovecs_len_validate(void) 1934 { 1935 struct spdk_dif_ctx_init_ext_opts dif_opts; 1936 struct accel_dif_request req; 1937 struct dif_task *task = &g_dif_task; 1938 int rc; 1939 1940 rc = alloc_dif_generate_copy_bufs(task, 1); 1941 SPDK_CU_ASSERT_FATAL(rc == 0); 1942 1943 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 1944 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 1945 1946 rc = spdk_dif_ctx_init(&task->dif_ctx, 1947 g_block_size_bytes + g_md_size_bytes, 1948 g_md_size_bytes, true, true, 1949 SPDK_DIF_TYPE1, 1950 SPDK_DIF_FLAGS_GUARD_CHECK | 1951 SPDK_DIF_FLAGS_APPTAG_CHECK | 1952 SPDK_DIF_FLAGS_REFTAG_CHECK, 1953 16, 0xFFFF, 10, 0, 0, &dif_opts); 1954 SPDK_CU_ASSERT_FATAL(rc == 0); 1955 1956 req.channel = g_channel; 1957 req.dst_iovs = task->dst_iovs; 1958 /* Make iov_len param incorrect */ 1959 req.dst_iovs->iov_len -= 16; 1960 req.dst_iovcnt = task->dst_iovcnt; 1961 req.src_iovs = task->src_iovs; 1962 req.src_iovcnt = task->src_iovcnt; 1963 req.num_blocks = task->num_blocks; 1964 req.ctx = &task->dif_ctx; 1965 req.err = &task->dif_err; 1966 req.cb_fn = accel_dif_oper_done; 1967 req.cb_arg = task; 1968 1969 execute_spdk_function(accel_dif_generate_copy_test, &req); 1970 CU_ASSERT_EQUAL(g_completion_success, false); 1971 1972 free_dif_generate_copy_bufs(task); 1973 } 1974 1975 static void 1976 accel_dif_generate_copy_op_buf_align_validate(void) 1977 { 1978 struct spdk_dif_ctx_init_ext_opts dif_opts; 1979 struct accel_dif_request req; 1980 struct dif_task *task = &g_dif_task; 1981 int rc; 1982 1983 rc = alloc_dif_generate_copy_bufs(task, 1); 1984 SPDK_CU_ASSERT_FATAL(rc == 0); 1985 1986 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 1987 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 1988 1989 rc = spdk_dif_ctx_init(&task->dif_ctx, 1990 g_block_size_bytes + g_md_size_bytes, 1991 g_md_size_bytes, true, true, 1992 SPDK_DIF_TYPE1, 1993 SPDK_DIF_FLAGS_GUARD_CHECK | 1994 SPDK_DIF_FLAGS_APPTAG_CHECK | 1995 SPDK_DIF_FLAGS_REFTAG_CHECK, 1996 16, 0xFFFF, 10, 0, 0, &dif_opts); 1997 SPDK_CU_ASSERT_FATAL(rc == 0); 1998 1999 req.channel = g_channel; 2000 req.dst_iovs = task->dst_iovs; 2001 req.dst_iovcnt = task->dst_iovcnt; 2002 req.src_iovs = task->src_iovs; 2003 req.src_iovcnt = task->src_iovcnt; 2004 req.num_blocks = task->num_blocks; 2005 req.ctx = &task->dif_ctx; 2006 req.err = &task->dif_err; 2007 req.cb_fn = accel_dif_oper_done; 2008 req.cb_arg = task; 2009 2010 execute_spdk_function(accel_dif_generate_copy_test, &req); 2011 CU_ASSERT_EQUAL(g_completion_success, true); 2012 2013 free_dif_generate_copy_bufs(task); 2014 } 2015 2016 static void 2017 accel_dif_generate_copy_sequence_dif_generated_do_check(uint32_t dif_flags) 2018 { 2019 struct spdk_dif_ctx_init_ext_opts dif_opts; 2020 struct accel_dif_request req; 2021 struct dif_task *task = &g_dif_task; 2022 struct spdk_dif_error err_blk; 2023 int rc; 2024 2025 rc = alloc_dif_generate_copy_sequence_bufs(task, 1); 2026 SPDK_CU_ASSERT_FATAL(rc == 0); 2027 2028 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 2029 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 2030 2031 rc = spdk_dif_ctx_init(&task->dif_ctx, 2032 g_block_size_bytes + g_md_size_bytes, 2033 g_md_size_bytes, true, true, 2034 SPDK_DIF_TYPE1, 2035 SPDK_DIF_FLAGS_GUARD_CHECK | 2036 SPDK_DIF_FLAGS_APPTAG_CHECK | 2037 SPDK_DIF_FLAGS_REFTAG_CHECK, 2038 16, 0xFFFF, 10, 0, 0, &dif_opts); 2039 SPDK_CU_ASSERT_FATAL(rc == 0); 2040 2041 req.channel = g_channel; 2042 req.dst_iovs = task->dst_iovs; 2043 req.dst_iovcnt = task->dst_iovcnt; 2044 req.src_iovs = task->src_iovs; 2045 req.src_iovcnt = task->src_iovcnt; 2046 req.aux_iovs = task->aux_iovs; 2047 req.aux_iovcnt = task->aux_iovcnt; 2048 req.num_blocks = task->num_blocks; 2049 req.ctx = &task->dif_ctx; 2050 req.err = &task->dif_err; 2051 req.cb_fn = accel_dif_oper_done; 2052 req.cb_arg = task; 2053 2054 execute_spdk_function(accel_dif_generate_copy_sequence_test, &req); 2055 CU_ASSERT_EQUAL(g_completion_success, true); 2056 2057 rc = spdk_dif_ctx_init(&task->dif_ctx, 2058 g_block_size_bytes + g_md_size_bytes, 2059 g_md_size_bytes, true, true, 2060 SPDK_DIF_TYPE1, 2061 dif_flags, 2062 16, 0xFFFF, 10, 0, 0, &dif_opts); 2063 SPDK_CU_ASSERT_FATAL(rc == 0); 2064 2065 rc = spdk_dif_verify(req.dst_iovs, req.dst_iovcnt, req.num_blocks, 2066 &task->dif_ctx, &err_blk); 2067 SPDK_CU_ASSERT_FATAL(rc == 0); 2068 2069 free_dif_generate_copy_sequence_bufs(task); 2070 } 2071 2072 static void 2073 accel_dif_generate_copy_sequence_dif_generated_guard_check(void) 2074 { 2075 accel_dif_generate_copy_sequence_dif_generated_do_check(SPDK_DIF_FLAGS_GUARD_CHECK); 2076 } 2077 2078 static void 2079 accel_dif_generate_copy_sequence_dif_generated_apptag_check(void) 2080 { 2081 accel_dif_generate_copy_sequence_dif_generated_do_check(SPDK_DIF_FLAGS_APPTAG_CHECK); 2082 } 2083 2084 static void 2085 accel_dif_generate_copy_sequence_dif_generated_reftag_check(void) 2086 { 2087 accel_dif_generate_copy_sequence_dif_generated_do_check(SPDK_DIF_FLAGS_REFTAG_CHECK); 2088 } 2089 2090 static void 2091 accel_dif_verify_copy_sequence_dif_generated_do_check(uint32_t dif_flags) 2092 { 2093 struct spdk_dif_ctx_init_ext_opts dif_opts; 2094 struct accel_dif_request req; 2095 struct dif_task *task = &g_dif_task; 2096 int rc; 2097 2098 rc = alloc_dif_verify_copy_bufs(task, 1); 2099 SPDK_CU_ASSERT_FATAL(rc == 0); 2100 2101 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 2102 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 2103 2104 rc = spdk_dif_ctx_init(&task->dif_ctx, 2105 g_block_size_bytes + g_md_size_bytes, 2106 g_md_size_bytes, true, true, 2107 SPDK_DIF_TYPE1, 2108 SPDK_DIF_FLAGS_GUARD_CHECK | 2109 SPDK_DIF_FLAGS_APPTAG_CHECK | 2110 SPDK_DIF_FLAGS_REFTAG_CHECK, 2111 10, 0xFFFF, 20, 0, 0, &dif_opts); 2112 SPDK_CU_ASSERT_FATAL(rc == 0); 2113 2114 rc = spdk_dif_generate(task->src_iovs, task->src_iovcnt, task->num_blocks, &task->dif_ctx); 2115 SPDK_CU_ASSERT_FATAL(rc == 0); 2116 2117 rc = spdk_dif_ctx_init(&task->dif_ctx, 2118 g_block_size_bytes + g_md_size_bytes, 2119 g_md_size_bytes, true, true, 2120 SPDK_DIF_TYPE1, 2121 dif_flags, 2122 10, 0xFFFF, 20, 0, 0, &dif_opts); 2123 SPDK_CU_ASSERT_FATAL(rc == 0); 2124 2125 req.channel = g_channel; 2126 req.dst_iovs = task->dst_iovs; 2127 req.dst_iovcnt = task->dst_iovcnt; 2128 req.src_iovs = task->src_iovs; 2129 req.src_iovcnt = task->src_iovcnt; 2130 req.num_blocks = task->num_blocks; 2131 req.ctx = &task->dif_ctx; 2132 req.err = &task->dif_err; 2133 req.cb_fn = accel_dif_oper_done; 2134 req.cb_arg = task; 2135 2136 execute_spdk_function(accel_dif_verify_copy_sequence_test, &req); 2137 CU_ASSERT_EQUAL(g_completion_success, true); 2138 2139 free_dif_verify_copy_bufs(task); 2140 } 2141 2142 static void 2143 accel_dif_verify_copy_sequence_dif_generated_guard_check(void) 2144 { 2145 accel_dif_verify_copy_sequence_dif_generated_do_check(SPDK_DIF_FLAGS_GUARD_CHECK); 2146 } 2147 2148 static void 2149 accel_dif_verify_copy_sequence_dif_generated_apptag_check(void) 2150 { 2151 accel_dif_verify_copy_sequence_dif_generated_do_check(SPDK_DIF_FLAGS_APPTAG_CHECK); 2152 } 2153 2154 static void 2155 accel_dif_verify_copy_sequence_dif_generated_reftag_check(void) 2156 { 2157 accel_dif_verify_copy_sequence_dif_generated_do_check(SPDK_DIF_FLAGS_REFTAG_CHECK); 2158 } 2159 2160 static void 2161 _stop_init_thread(void *arg) 2162 { 2163 unsigned num_failures = g_num_failures; 2164 2165 g_num_failures = 0; 2166 2167 assert(spdk_get_thread() == g_thread[WORKER_UT]); 2168 assert(spdk_thread_is_app_thread(NULL)); 2169 execute_spdk_function(exit_io_thread, NULL); 2170 spdk_app_stop(num_failures); 2171 } 2172 2173 static void 2174 stop_init_thread(unsigned num_failures, struct spdk_jsonrpc_request *request) 2175 { 2176 g_num_failures = num_failures; 2177 2178 spdk_thread_send_msg(g_thread[WORKER_UT], _stop_init_thread, request); 2179 } 2180 2181 static int 2182 setup_accel_tests(void) 2183 { 2184 unsigned rc = 0; 2185 CU_pSuite suite = NULL; 2186 2187 suite = CU_add_suite("accel_dif", NULL, NULL); 2188 if (suite == NULL) { 2189 CU_cleanup_registry(); 2190 rc = CU_get_error(); 2191 return -rc; 2192 } 2193 2194 if (CU_add_test(suite, "verify: DIF generated, GUARD check", 2195 accel_dif_verify_op_dif_generated_guard_check) == NULL || 2196 CU_add_test(suite, "verify: DIX generated, GUARD check", 2197 accel_dix_verify_op_dix_generated_guard_check) == NULL || 2198 CU_add_test(suite, "verify: DIF generated, APPTAG check", 2199 accel_dif_verify_op_dif_generated_apptag_check) == NULL || 2200 CU_add_test(suite, "verify: DIX generated, APPTAG check", 2201 accel_dix_verify_op_dix_generated_apptag_check) == NULL || 2202 CU_add_test(suite, "verify: DIF generated, REFTAG check", 2203 accel_dif_verify_op_dif_generated_reftag_check) == NULL || 2204 CU_add_test(suite, "verify: DIX generated, REFTAG check", 2205 accel_dix_verify_op_dix_generated_reftag_check) == NULL || 2206 CU_add_test(suite, "verify: DIX generated, all flags check", 2207 accel_dix_verify_op_dix_generated_all_flags_check) == NULL || 2208 2209 CU_add_test(suite, "verify: DIF not generated, GUARD check", 2210 accel_dif_verify_op_dif_not_generated_guard_check) == NULL || 2211 CU_add_test(suite, "verify: DIX not generated, GUARD check", 2212 accel_dix_verify_op_dix_not_generated_guard_check) == NULL || 2213 CU_add_test(suite, "verify: DIF not generated, APPTAG check", 2214 accel_dif_verify_op_dif_not_generated_apptag_check) == NULL || 2215 CU_add_test(suite, "verify: DIX not generated, APPTAG check", 2216 accel_dix_verify_op_dix_not_generated_apptag_check) == NULL || 2217 CU_add_test(suite, "verify: DIF not generated, REFTAG check", 2218 accel_dif_verify_op_dif_not_generated_reftag_check) == NULL || 2219 CU_add_test(suite, "verify: DIX not generated, REFTAG check", 2220 accel_dix_verify_op_dix_not_generated_reftag_check) == NULL || 2221 CU_add_test(suite, "verify: DIX not generated, all flags check", 2222 accel_dix_verify_op_dix_not_generated_all_flags_check) == NULL || 2223 CU_add_test(suite, "verify: DIX guard not generated, all flags check", 2224 accel_dix_verify_op_dix_guard_not_generated_all_flags_check) == NULL || 2225 CU_add_test(suite, "verify: DIX apptag not generated, all flags check", 2226 accel_dix_verify_op_dix_apptag_not_generated_all_flags_check) == NULL || 2227 CU_add_test(suite, "verify: DIX reftag not generated, all flags check", 2228 accel_dix_verify_op_dix_reftag_not_generated_all_flags_check) == NULL || 2229 2230 CU_add_test(suite, "verify: DIF APPTAG correct, APPTAG check", 2231 accel_dif_verify_op_apptag_correct_apptag_check) == NULL || 2232 CU_add_test(suite, "verify: DIX APPTAG correct, APPTAG check", 2233 accel_dix_verify_op_apptag_correct_apptag_check) == NULL || 2234 CU_add_test(suite, "verify: DIF APPTAG incorrect, APPTAG check", 2235 accel_dif_verify_op_apptag_incorrect_apptag_check) == NULL || 2236 CU_add_test(suite, "verify: DIX APPTAG incorrect, APPTAG check", 2237 accel_dix_verify_op_apptag_incorrect_apptag_check) == NULL || 2238 CU_add_test(suite, "verify: DIF APPTAG incorrect, no APPTAG check", 2239 accel_dif_verify_op_apptag_incorrect_no_apptag_check) == NULL || 2240 CU_add_test(suite, "verify: DIX APPTAG incorrect, no APPTAG check", 2241 accel_dix_verify_op_apptag_incorrect_no_apptag_check) == NULL || 2242 CU_add_test(suite, "verify: DIF REFTAG incorrect, REFTAG ignore", 2243 accel_dif_verify_op_reftag_incorrect_reftag_ignore) == NULL || 2244 CU_add_test(suite, "verify: DIX REFTAG incorrect, REFTAG ignore", 2245 accel_dix_verify_op_reftag_incorrect_reftag_ignore) == NULL || 2246 2247 CU_add_test(suite, "verify: DIF REFTAG_INIT correct, REFTAG check", 2248 accel_dif_verify_op_reftag_init_correct_reftag_check) == NULL || 2249 CU_add_test(suite, "verify: DIX REFTAG_INIT correct, REFTAG check", 2250 accel_dix_verify_op_reftag_init_correct_reftag_check) == NULL || 2251 CU_add_test(suite, "verify: DIF REFTAG_INIT incorrect, REFTAG check", 2252 accel_dif_verify_op_reftag_init_incorrect_reftag_check) == NULL || 2253 CU_add_test(suite, "verify: DIX REFTAG_INIT incorrect, REFTAG check", 2254 accel_dix_verify_op_reftag_init_incorrect_reftag_check) == NULL || 2255 2256 CU_add_test(suite, "verify copy: DIF generated, GUARD check", 2257 accel_dif_verify_copy_op_dif_generated_guard_check) == NULL || 2258 CU_add_test(suite, "verify copy: DIF generated, APPTAG check", 2259 accel_dif_verify_copy_op_dif_generated_apptag_check) == NULL || 2260 CU_add_test(suite, "verify copy: DIF generated, REFTAG check", 2261 accel_dif_verify_copy_op_dif_generated_reftag_check) == NULL || 2262 2263 CU_add_test(suite, "verify copy: DIF not generated, GUARD check", 2264 accel_dif_verify_copy_op_dif_not_generated_guard_check) == NULL || 2265 CU_add_test(suite, "verify copy: DIF not generated, APPTAG check", 2266 accel_dif_verify_copy_op_dif_not_generated_apptag_check) == NULL || 2267 CU_add_test(suite, "verify copy: DIF not generated, REFTAG check", 2268 accel_dif_verify_copy_op_dif_not_generated_reftag_check) == NULL || 2269 2270 CU_add_test(suite, "generate copy: DIF generated, GUARD check", 2271 accel_dif_generate_copy_op_dif_generated_guard_check) == NULL || 2272 CU_add_test(suite, "generate copy: DIF generated, APTTAG check", 2273 accel_dif_generate_copy_op_dif_generated_apptag_check) == NULL || 2274 CU_add_test(suite, "generate copy: DIF generated, REFTAG check", 2275 accel_dif_generate_copy_op_dif_generated_reftag_check) == NULL || 2276 2277 CU_add_test(suite, "generate: DIX generated, GUARD check", 2278 accel_dix_generate_op_dix_generated_guard_check) == NULL || 2279 CU_add_test(suite, "generate: DIX generated, APTTAG check", 2280 accel_dix_generate_op_dix_generated_apptag_check) == NULL || 2281 CU_add_test(suite, "generate: DIX generated, REFTAG check", 2282 accel_dix_generate_op_dix_generated_reftag_check) == NULL || 2283 2284 CU_add_test(suite, "generate copy: DIF generated, no GUARD check flag set", 2285 accel_dif_generate_copy_op_dif_generated_no_guard_check_flag_set) == NULL || 2286 CU_add_test(suite, "generate copy: DIF generated, no APPTAG check flag set", 2287 accel_dif_generate_copy_op_dif_generated_no_apptag_check_flag_set) == NULL || 2288 CU_add_test(suite, "generate copy: DIF generated, no REFTAG check flag set", 2289 accel_dif_generate_copy_op_dif_generated_no_reftag_check_flag_set) == NULL || 2290 2291 CU_add_test(suite, "generate copy: DIF iovecs-len validate", 2292 accel_dif_generate_copy_op_iovecs_len_validate) == NULL || 2293 CU_add_test(suite, "generate copy: DIF buffer alignment validate", 2294 accel_dif_generate_copy_op_buf_align_validate) == NULL || 2295 2296 CU_add_test(suite, "generate copy sequence: DIF generated, GUARD check", 2297 accel_dif_generate_copy_sequence_dif_generated_guard_check) == NULL || 2298 CU_add_test(suite, "generate copy sequence: DIF generated, APTTAG check", 2299 accel_dif_generate_copy_sequence_dif_generated_apptag_check) == NULL || 2300 CU_add_test(suite, "generate copy sequence: DIF generated, REFTAG check", 2301 accel_dif_generate_copy_sequence_dif_generated_reftag_check) == NULL || 2302 CU_add_test(suite, "verify copy sequence: DIF generated, GUARD check", 2303 accel_dif_verify_copy_sequence_dif_generated_guard_check) == NULL || 2304 CU_add_test(suite, "verify copy sequence: DIF generated, APPTAG check", 2305 accel_dif_verify_copy_sequence_dif_generated_apptag_check) == NULL || 2306 CU_add_test(suite, "verify copy sequence: DIF generated, REFTAG check", 2307 accel_dif_verify_copy_sequence_dif_generated_reftag_check) == NULL) { 2308 CU_cleanup_registry(); 2309 rc = CU_get_error(); 2310 return -rc; 2311 } 2312 return 0; 2313 } 2314 2315 static void 2316 get_io_channel(void *arg) 2317 { 2318 g_channel = spdk_accel_get_io_channel(); 2319 assert(g_channel); 2320 wake_ut_thread(); 2321 } 2322 2323 static void 2324 put_io_channel(void *arg) 2325 { 2326 assert(g_channel); 2327 spdk_put_io_channel(g_channel); 2328 wake_ut_thread(); 2329 } 2330 2331 static void 2332 run_accel_test_thread(void *arg) 2333 { 2334 struct spdk_jsonrpc_request *request = arg; 2335 int rc = 0; 2336 2337 execute_spdk_function(get_io_channel, NULL); 2338 if (g_channel == NULL) { 2339 fprintf(stderr, "Unable to get an accel channel\n"); 2340 goto ret; 2341 } 2342 2343 if (CU_initialize_registry() != CUE_SUCCESS) { 2344 /* CUnit error, probably won't recover */ 2345 rc = CU_get_error(); 2346 rc = -rc; 2347 goto ret; 2348 } 2349 2350 rc = setup_accel_tests(); 2351 if (rc < 0) { 2352 /* CUnit error, probably won't recover */ 2353 rc = -rc; 2354 goto ret; 2355 } 2356 CU_basic_set_mode(CU_BRM_VERBOSE); 2357 CU_basic_run_tests(); 2358 rc = CU_get_number_of_failures(); 2359 CU_cleanup_registry(); 2360 2361 ret: 2362 if (g_channel != NULL) { 2363 execute_spdk_function(put_io_channel, NULL); 2364 } 2365 stop_init_thread(rc, request); 2366 } 2367 2368 static void 2369 accel_dif_test_main(void *arg1) 2370 { 2371 struct spdk_cpuset tmpmask = {}; 2372 uint32_t i; 2373 2374 pthread_mutex_init(&g_test_mutex, NULL); 2375 pthread_cond_init(&g_test_cond, NULL); 2376 2377 /* This test runs specifically on at least two cores. 2378 * g_thread[WORKER_UT] is the app_thread on main core from event framework. 2379 * Next one is only for the tests and should always be on separate CPU cores. */ 2380 if (spdk_env_get_core_count() < 3) { 2381 spdk_app_stop(-1); 2382 return; 2383 } 2384 2385 SPDK_ENV_FOREACH_CORE(i) { 2386 if (i == spdk_env_get_current_core()) { 2387 g_thread[WORKER_UT] = spdk_get_thread(); 2388 continue; 2389 } 2390 spdk_cpuset_zero(&tmpmask); 2391 spdk_cpuset_set_cpu(&tmpmask, i, true); 2392 if (g_thread[WORKER_IO] == NULL) { 2393 g_thread[WORKER_IO] = spdk_thread_create("io_thread", &tmpmask); 2394 } 2395 2396 } 2397 2398 spdk_thread_send_msg(g_thread[WORKER_UT], run_accel_test_thread, NULL); 2399 } 2400 2401 static void 2402 accel_dif_usage(void) 2403 { 2404 } 2405 2406 static int 2407 accel_dif_parse_arg(int ch, char *arg) 2408 { 2409 return 0; 2410 } 2411 2412 static void 2413 spdk_dif_shutdown_cb(void) 2414 { 2415 g_shutdown = true; 2416 spdk_thread_send_msg(g_thread[WORKER_UT], _stop_init_thread, NULL); 2417 } 2418 2419 int 2420 main(int argc, char **argv) 2421 { 2422 struct spdk_app_opts opts = {}; 2423 char reactor_mask[8]; 2424 int rc; 2425 2426 spdk_app_opts_init(&opts, sizeof(opts)); 2427 opts.name = "DIF"; 2428 snprintf(reactor_mask, sizeof(reactor_mask), "0x%x", (1 << (SPDK_COUNTOF(g_thread) + 1)) - 1); 2429 opts.reactor_mask = reactor_mask; 2430 opts.shutdown_cb = spdk_dif_shutdown_cb; 2431 opts.rpc_addr = NULL; 2432 2433 if ((rc = spdk_app_parse_args(argc, argv, &opts, "", NULL, 2434 accel_dif_parse_arg, accel_dif_usage)) != 2435 SPDK_APP_PARSE_ARGS_SUCCESS) { 2436 return rc; 2437 } 2438 2439 rc = spdk_app_start(&opts, accel_dif_test_main, NULL); 2440 spdk_app_fini(); 2441 2442 return rc; 2443 } 2444