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 uint32_t num_blocks; /* used for the DIF related operations */ 39 struct spdk_dif_ctx dif_ctx; 40 struct spdk_dif_error dif_err; 41 }; 42 43 static void 44 execute_spdk_function(spdk_msg_fn fn, void *arg) 45 { 46 pthread_mutex_lock(&g_test_mutex); 47 spdk_thread_send_msg(g_thread[WORKER_IO], fn, arg); 48 pthread_cond_wait(&g_test_cond, &g_test_mutex); 49 pthread_mutex_unlock(&g_test_mutex); 50 } 51 52 static void 53 wake_ut_thread(void) 54 { 55 pthread_mutex_lock(&g_test_mutex); 56 pthread_cond_signal(&g_test_cond); 57 pthread_mutex_unlock(&g_test_mutex); 58 } 59 60 static void 61 exit_io_thread(void *arg) 62 { 63 assert(spdk_get_thread() == g_thread[WORKER_IO]); 64 spdk_thread_exit(g_thread[WORKER_IO]); 65 wake_ut_thread(); 66 } 67 68 #define DATA_PATTERN 0x5A 69 70 static int g_xfer_size_bytes = 4096; 71 static int g_block_size_bytes = 512; 72 static int g_md_size_bytes = 8; 73 struct dif_task g_dif_task; 74 75 struct accel_dif_request { 76 struct spdk_io_channel *channel; 77 struct iovec *dst_iovs; 78 size_t dst_iovcnt; 79 struct iovec *src_iovs; 80 size_t src_iovcnt; 81 uint32_t num_blocks; 82 const struct spdk_dif_ctx *ctx; 83 struct spdk_dif_error *err; 84 spdk_accel_completion_cb cb_fn; 85 void *cb_arg; 86 }; 87 88 static void 89 accel_dif_oper_done(void *arg1, int status) 90 { 91 if (status == 0) { 92 g_completion_success = true; 93 } 94 wake_ut_thread(); 95 } 96 97 static bool 98 accel_dif_error_validate(const uint32_t dif_flags, 99 const struct spdk_dif_error *err) 100 { 101 switch (dif_flags) { 102 case SPDK_DIF_FLAGS_GUARD_CHECK: 103 return err->err_type == SPDK_DIF_GUARD_ERROR; 104 case SPDK_DIF_FLAGS_APPTAG_CHECK: 105 return err->err_type == SPDK_DIF_APPTAG_ERROR; 106 case SPDK_DIF_FLAGS_REFTAG_CHECK: 107 return err->err_type == SPDK_DIF_REFTAG_ERROR; 108 default: 109 return false; 110 } 111 } 112 113 static int 114 alloc_dif_verify_bufs(struct dif_task *task, uint32_t chained_count) 115 { 116 int src_buff_len = g_xfer_size_bytes; 117 uint32_t i = 0; 118 119 assert(chained_count > 0); 120 task->src_iovcnt = chained_count; 121 task->src_iovs = calloc(task->src_iovcnt, sizeof(struct iovec)); 122 if (spdk_unlikely(task->src_iovs == NULL)) { 123 return -ENOMEM; 124 } 125 126 src_buff_len += (g_xfer_size_bytes / g_block_size_bytes) * g_md_size_bytes; 127 128 for (i = 0; i < task->src_iovcnt; i++) { 129 task->src_iovs[i].iov_base = spdk_dma_zmalloc(src_buff_len, 0, NULL); 130 if (spdk_unlikely(task->src_iovs[i].iov_base == NULL)) { 131 return -ENOMEM; 132 } 133 134 memset(task->src_iovs[i].iov_base, DATA_PATTERN, src_buff_len); 135 task->src_iovs[i].iov_len = src_buff_len; 136 } 137 138 task->num_blocks = (g_xfer_size_bytes * chained_count) / g_block_size_bytes; 139 140 return 0; 141 } 142 143 static void 144 free_dif_verify_bufs(struct dif_task *task) 145 { 146 uint32_t i = 0; 147 148 if (task->src_iovs != NULL) { 149 for (i = 0; i < task->src_iovcnt; i++) { 150 if (task->src_iovs[i].iov_base != NULL) { 151 spdk_dma_free(task->src_iovs[i].iov_base); 152 } 153 } 154 free(task->src_iovs); 155 } 156 } 157 158 static int 159 alloc_dif_verify_copy_bufs(struct dif_task *task, uint32_t chained_count) 160 { 161 int dst_buff_len = g_xfer_size_bytes; 162 uint32_t data_size_with_md; 163 uint32_t i = 0; 164 165 assert(chained_count > 0); 166 task->src_iovcnt = chained_count; 167 task->src_iovs = calloc(task->src_iovcnt, sizeof(struct iovec)); 168 if (spdk_unlikely(task->src_iovs == NULL)) { 169 return -ENOMEM; 170 } 171 172 task->num_blocks = g_xfer_size_bytes / g_block_size_bytes; 173 174 /* Add bytes for each block for metadata */ 175 data_size_with_md = g_xfer_size_bytes + (task->num_blocks * g_md_size_bytes); 176 177 for (i = 0; i < task->src_iovcnt; i++) { 178 task->src_iovs[i].iov_base = spdk_dma_zmalloc(data_size_with_md, 0, NULL); 179 if (spdk_unlikely(task->src_iovs[i].iov_base == NULL)) { 180 return -ENOMEM; 181 } 182 183 memset(task->src_iovs[i].iov_base, DATA_PATTERN, data_size_with_md); 184 task->src_iovs[i].iov_len = data_size_with_md; 185 } 186 187 task->dst_iovcnt = chained_count; 188 task->dst_iovs = calloc(task->dst_iovcnt, sizeof(struct iovec)); 189 if (spdk_unlikely(task->dst_iovs == NULL)) { 190 return -ENOMEM; 191 } 192 193 for (i = 0; i < task->dst_iovcnt; i++) { 194 task->dst_iovs[i].iov_base = spdk_dma_zmalloc(dst_buff_len, 0, NULL); 195 if (spdk_unlikely(task->dst_iovs[i].iov_base == NULL)) { 196 return -ENOMEM; 197 } 198 199 memset(task->dst_iovs[i].iov_base, 0, dst_buff_len); 200 task->dst_iovs[i].iov_len = dst_buff_len; 201 } 202 203 return 0; 204 } 205 206 static void 207 free_dif_verify_copy_bufs(struct dif_task *task) 208 { 209 uint32_t i = 0; 210 211 if (task->dst_iovs != NULL) { 212 for (i = 0; i < task->dst_iovcnt; i++) { 213 if (task->dst_iovs[i].iov_base != NULL) { 214 spdk_dma_free(task->dst_iovs[i].iov_base); 215 } 216 } 217 free(task->dst_iovs); 218 } 219 220 if (task->src_iovs != NULL) { 221 for (i = 0; i < task->src_iovcnt; i++) { 222 if (task->src_iovs[i].iov_base != NULL) { 223 spdk_dma_free(task->src_iovs[i].iov_base); 224 } 225 } 226 free(task->src_iovs); 227 } 228 } 229 230 static int 231 alloc_dif_generate_copy_bufs(struct dif_task *task, uint32_t chained_count) 232 { 233 int src_buff_len = g_xfer_size_bytes; 234 uint32_t transfer_size_with_md; 235 uint32_t i = 0; 236 237 assert(chained_count > 0); 238 task->dst_iovcnt = chained_count; 239 task->dst_iovs = calloc(task->dst_iovcnt, sizeof(struct iovec)); 240 if (spdk_unlikely(task->dst_iovs == NULL)) { 241 return -ENOMEM; 242 } 243 244 task->num_blocks = g_xfer_size_bytes / g_block_size_bytes; 245 246 /* Add bytes for each block for metadata */ 247 transfer_size_with_md = g_xfer_size_bytes + (task->num_blocks * g_md_size_bytes); 248 249 for (i = 0; i < task->dst_iovcnt; i++) { 250 task->dst_iovs[i].iov_base = spdk_dma_zmalloc(transfer_size_with_md, 0, NULL); 251 if (spdk_unlikely(task->dst_iovs[i].iov_base == NULL)) { 252 return -ENOMEM; 253 } 254 255 memset(task->dst_iovs[i].iov_base, 0, transfer_size_with_md); 256 task->dst_iovs[i].iov_len = transfer_size_with_md; 257 } 258 259 task->src_iovcnt = chained_count; 260 task->src_iovs = calloc(task->src_iovcnt, sizeof(struct iovec)); 261 if (spdk_unlikely(task->src_iovs == NULL)) { 262 return -ENOMEM; 263 } 264 265 for (i = 0; i < task->src_iovcnt; i++) { 266 task->src_iovs[i].iov_base = spdk_dma_zmalloc(src_buff_len, 0, NULL); 267 if (spdk_unlikely(task->src_iovs[i].iov_base == NULL)) { 268 return -ENOMEM; 269 } 270 271 memset(task->src_iovs[i].iov_base, DATA_PATTERN, src_buff_len); 272 task->src_iovs[i].iov_len = src_buff_len; 273 } 274 275 return 0; 276 } 277 278 static void 279 free_dif_generate_copy_bufs(struct dif_task *task) 280 { 281 uint32_t i = 0; 282 283 if (task->dst_iovs != NULL) { 284 for (i = 0; i < task->dst_iovcnt; i++) { 285 if (task->dst_iovs[i].iov_base != NULL) { 286 spdk_dma_free(task->dst_iovs[i].iov_base); 287 } 288 } 289 free(task->dst_iovs); 290 } 291 292 if (task->src_iovs != NULL) { 293 for (i = 0; i < task->src_iovcnt; i++) { 294 if (task->src_iovs[i].iov_base != NULL) { 295 spdk_dma_free(task->src_iovs[i].iov_base); 296 } 297 } 298 free(task->src_iovs); 299 } 300 } 301 302 static void 303 accel_dif_verify_test(void *arg) 304 { 305 int rc; 306 struct accel_dif_request *req = arg; 307 308 g_completion_success = false; 309 rc = spdk_accel_submit_dif_verify(req->channel, req->src_iovs, req->src_iovcnt, 310 req->num_blocks, req->ctx, req->err, 311 req->cb_fn, req->cb_arg); 312 if (rc) { 313 wake_ut_thread(); 314 } 315 } 316 317 static void 318 accel_dif_verify_copy_test(void *arg) 319 { 320 int rc; 321 struct accel_dif_request *req = arg; 322 323 g_completion_success = false; 324 rc = spdk_accel_submit_dif_verify_copy(req->channel, req->dst_iovs, req->dst_iovcnt, 325 req->src_iovs, req->src_iovcnt, 326 req->num_blocks, req->ctx, req->err, 327 req->cb_fn, req->cb_arg); 328 if (rc) { 329 wake_ut_thread(); 330 } 331 } 332 333 static void 334 accel_dif_generate_copy_test(void *arg) 335 { 336 int rc; 337 struct accel_dif_request *req = arg; 338 339 g_completion_success = false; 340 rc = spdk_accel_submit_dif_generate_copy(req->channel, req->dst_iovs, req->dst_iovcnt, 341 req->src_iovs, req->src_iovcnt, req->num_blocks, req->ctx, 342 req->cb_fn, req->cb_arg); 343 if (rc) { 344 wake_ut_thread(); 345 } 346 } 347 348 static void 349 accel_dif_verify_op_dif_generated_do_check(uint32_t dif_flags) 350 { 351 struct spdk_dif_ctx_init_ext_opts dif_opts; 352 struct accel_dif_request req; 353 struct dif_task *task = &g_dif_task; 354 int rc; 355 356 rc = alloc_dif_verify_bufs(task, 1); 357 SPDK_CU_ASSERT_FATAL(rc == 0); 358 359 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 360 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 361 362 rc = spdk_dif_ctx_init(&task->dif_ctx, 363 g_block_size_bytes + g_md_size_bytes, 364 g_md_size_bytes, true, true, 365 SPDK_DIF_TYPE1, 366 SPDK_DIF_FLAGS_GUARD_CHECK | 367 SPDK_DIF_FLAGS_APPTAG_CHECK | 368 SPDK_DIF_FLAGS_REFTAG_CHECK, 369 10, 0xFFFF, 20, 0, 0, &dif_opts); 370 SPDK_CU_ASSERT_FATAL(rc == 0); 371 372 rc = spdk_dif_generate(task->src_iovs, task->src_iovcnt, task->num_blocks, &task->dif_ctx); 373 SPDK_CU_ASSERT_FATAL(rc == 0); 374 375 rc = spdk_dif_ctx_init(&task->dif_ctx, 376 g_block_size_bytes + g_md_size_bytes, 377 g_md_size_bytes, true, true, 378 SPDK_DIF_TYPE1, 379 dif_flags, 380 10, 0xFFFF, 20, 0, 0, &dif_opts); 381 SPDK_CU_ASSERT_FATAL(rc == 0); 382 383 req.channel = g_channel; 384 req.src_iovs = task->src_iovs; 385 req.src_iovcnt = task->src_iovcnt; 386 req.num_blocks = task->num_blocks; 387 req.ctx = &task->dif_ctx; 388 req.err = &task->dif_err; 389 req.cb_fn = accel_dif_oper_done; 390 req.cb_arg = task; 391 392 execute_spdk_function(accel_dif_verify_test, &req); 393 CU_ASSERT_EQUAL(g_completion_success, true); 394 395 free_dif_verify_bufs(task); 396 } 397 398 static void 399 accel_dif_verify_op_dif_generated_guard_check(void) 400 { 401 accel_dif_verify_op_dif_generated_do_check(SPDK_DIF_FLAGS_GUARD_CHECK); 402 } 403 404 static void 405 accel_dif_verify_op_dif_generated_apptag_check(void) 406 { 407 accel_dif_verify_op_dif_generated_do_check(SPDK_DIF_FLAGS_APPTAG_CHECK); 408 } 409 410 static void 411 accel_dif_verify_op_dif_generated_reftag_check(void) 412 { 413 accel_dif_verify_op_dif_generated_do_check(SPDK_DIF_FLAGS_REFTAG_CHECK); 414 } 415 416 static void 417 accel_dif_verify_op_dif_not_generated_do_check(uint32_t dif_flags) 418 { 419 struct spdk_dif_ctx_init_ext_opts dif_opts; 420 struct accel_dif_request req; 421 struct dif_task *task = &g_dif_task; 422 int rc; 423 424 rc = alloc_dif_verify_bufs(task, 1); 425 SPDK_CU_ASSERT_FATAL(rc == 0); 426 427 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 428 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 429 430 rc = spdk_dif_ctx_init(&task->dif_ctx, 431 g_block_size_bytes + g_md_size_bytes, 432 g_md_size_bytes, true, true, 433 SPDK_DIF_TYPE1, 434 dif_flags, 435 10, 0xFFFF, 20, 0, 0, &dif_opts); 436 SPDK_CU_ASSERT_FATAL(rc == 0); 437 438 req.channel = g_channel; 439 req.src_iovs = task->src_iovs; 440 req.src_iovcnt = task->src_iovcnt; 441 req.num_blocks = task->num_blocks; 442 req.ctx = &task->dif_ctx; 443 req.err = &task->dif_err; 444 req.cb_fn = accel_dif_oper_done; 445 req.cb_arg = task; 446 447 execute_spdk_function(accel_dif_verify_test, &req); 448 CU_ASSERT_EQUAL(g_completion_success, false); 449 CU_ASSERT_EQUAL(accel_dif_error_validate(dif_flags, req.err), true); 450 451 free_dif_verify_bufs(task); 452 } 453 454 static void 455 accel_dif_verify_op_dif_not_generated_guard_check(void) 456 { 457 accel_dif_verify_op_dif_not_generated_do_check(SPDK_DIF_FLAGS_GUARD_CHECK); 458 } 459 460 static void 461 accel_dif_verify_op_dif_not_generated_apptag_check(void) 462 { 463 accel_dif_verify_op_dif_not_generated_do_check(SPDK_DIF_FLAGS_APPTAG_CHECK); 464 } 465 466 static void 467 accel_dif_verify_op_dif_not_generated_reftag_check(void) 468 { 469 accel_dif_verify_op_dif_not_generated_do_check(SPDK_DIF_FLAGS_REFTAG_CHECK); 470 } 471 472 static void 473 accel_dif_verify_op_apptag_correct_apptag_check(void) 474 { 475 struct spdk_dif_ctx_init_ext_opts dif_opts; 476 struct accel_dif_request req; 477 struct dif_task *task = &g_dif_task; 478 int rc; 479 480 rc = alloc_dif_verify_bufs(task, 1); 481 SPDK_CU_ASSERT_FATAL(rc == 0); 482 483 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 484 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 485 486 rc = spdk_dif_ctx_init(&task->dif_ctx, 487 g_block_size_bytes + g_md_size_bytes, 488 g_md_size_bytes, true, true, 489 SPDK_DIF_TYPE1, 490 SPDK_DIF_FLAGS_APPTAG_CHECK, 491 10, 0xFFFF, 20, 0, 0, &dif_opts); 492 SPDK_CU_ASSERT_FATAL(rc == 0); 493 494 rc = spdk_dif_generate(task->src_iovs, task->src_iovcnt, task->num_blocks, &task->dif_ctx); 495 SPDK_CU_ASSERT_FATAL(rc == 0); 496 497 req.channel = g_channel; 498 req.src_iovs = task->src_iovs; 499 req.src_iovcnt = task->src_iovcnt; 500 req.num_blocks = task->num_blocks; 501 req.ctx = &task->dif_ctx; 502 req.err = &task->dif_err; 503 req.cb_fn = accel_dif_oper_done; 504 req.cb_arg = task; 505 506 execute_spdk_function(accel_dif_verify_test, &req); 507 CU_ASSERT_EQUAL(g_completion_success, true); 508 509 free_dif_verify_bufs(task); 510 } 511 512 static void 513 accel_dif_verify_op_apptag_incorrect_apptag_check(void) 514 { 515 struct spdk_dif_ctx_init_ext_opts dif_opts; 516 struct accel_dif_request req; 517 struct dif_task *task = &g_dif_task; 518 int rc; 519 520 rc = alloc_dif_verify_bufs(task, 1); 521 SPDK_CU_ASSERT_FATAL(rc == 0); 522 523 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 524 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 525 526 rc = spdk_dif_ctx_init(&task->dif_ctx, 527 g_block_size_bytes + g_md_size_bytes, 528 g_md_size_bytes, true, true, 529 SPDK_DIF_TYPE1, 530 SPDK_DIF_FLAGS_APPTAG_CHECK, 531 10, 0xFFFF, 20, 0, 0, &dif_opts); 532 SPDK_CU_ASSERT_FATAL(rc == 0); 533 534 rc = spdk_dif_generate(task->src_iovs, task->src_iovcnt, task->num_blocks, &task->dif_ctx); 535 SPDK_CU_ASSERT_FATAL(rc == 0); 536 537 rc = spdk_dif_ctx_init(&task->dif_ctx, 538 g_block_size_bytes + g_md_size_bytes, 539 g_md_size_bytes, true, true, 540 SPDK_DIF_TYPE1, 541 SPDK_DIF_FLAGS_APPTAG_CHECK, 542 30, 0xFFFF, 40, 0, 0, &dif_opts); 543 SPDK_CU_ASSERT_FATAL(rc == 0); 544 545 req.channel = g_channel; 546 req.src_iovs = task->src_iovs; 547 req.src_iovcnt = task->src_iovcnt; 548 req.num_blocks = task->num_blocks; 549 req.ctx = &task->dif_ctx; 550 req.err = &task->dif_err; 551 req.cb_fn = accel_dif_oper_done; 552 req.cb_arg = task; 553 554 execute_spdk_function(accel_dif_verify_test, &req); 555 CU_ASSERT_EQUAL(g_completion_success, false); 556 557 free_dif_verify_bufs(task); 558 } 559 560 static void 561 accel_dif_verify_op_tag_incorrect_no_check_or_ignore(uint32_t dif_flags) 562 { 563 struct spdk_dif_ctx_init_ext_opts dif_opts; 564 struct accel_dif_request req; 565 struct dif_task *task = &g_dif_task; 566 int rc; 567 568 rc = alloc_dif_verify_bufs(task, 1); 569 SPDK_CU_ASSERT_FATAL(rc == 0); 570 571 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 572 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 573 574 /* For set 'Application Tag F Detect' (Source DIF Flags) 575 * When all bits of the Application Tag field of the source Data Integrity Field 576 * are equal to 1, the Application Tag check is not done and the Guard field and 577 * Reference Tag field are ignored. */ 578 rc = spdk_dif_ctx_init(&task->dif_ctx, 579 g_block_size_bytes + g_md_size_bytes, 580 g_md_size_bytes, true, true, 581 SPDK_DIF_TYPE1, 582 SPDK_DIF_FLAGS_GUARD_CHECK | 583 SPDK_DIF_FLAGS_APPTAG_CHECK | 584 SPDK_DIF_FLAGS_REFTAG_CHECK, 585 10, 0xFFFF, 0xFFFF, 0, 0, &dif_opts); 586 SPDK_CU_ASSERT_FATAL(rc == 0); 587 588 rc = spdk_dif_generate(task->src_iovs, task->src_iovcnt, task->num_blocks, &task->dif_ctx); 589 SPDK_CU_ASSERT_FATAL(rc == 0); 590 591 rc = spdk_dif_ctx_init(&task->dif_ctx, 592 g_block_size_bytes + g_md_size_bytes, 593 g_md_size_bytes, true, true, 594 SPDK_DIF_TYPE1, 595 dif_flags, 596 30, 0xFFFF, 40, 0, 0, &dif_opts); 597 SPDK_CU_ASSERT_FATAL(rc == 0); 598 599 req.channel = g_channel; 600 req.src_iovs = task->src_iovs; 601 req.src_iovcnt = task->src_iovcnt; 602 req.num_blocks = task->num_blocks; 603 req.ctx = &task->dif_ctx; 604 req.err = &task->dif_err; 605 req.cb_fn = accel_dif_oper_done; 606 req.cb_arg = task; 607 608 execute_spdk_function(accel_dif_verify_test, &req); 609 CU_ASSERT_EQUAL(g_completion_success, true); 610 611 free_dif_verify_bufs(task); 612 } 613 614 static void 615 accel_dif_verify_op_apptag_incorrect_no_apptag_check(void) 616 { 617 accel_dif_verify_op_tag_incorrect_no_check_or_ignore(SPDK_DIF_FLAGS_APPTAG_CHECK); 618 } 619 620 static void 621 accel_dif_verify_op_reftag_incorrect_reftag_ignore(void) 622 { 623 accel_dif_verify_op_tag_incorrect_no_check_or_ignore(SPDK_DIF_FLAGS_REFTAG_CHECK); 624 } 625 626 static void 627 accel_dif_verify_op_reftag_init_correct_reftag_check(void) 628 { 629 struct spdk_dif_ctx_init_ext_opts dif_opts; 630 struct accel_dif_request req; 631 struct dif_task *task = &g_dif_task; 632 int rc; 633 634 rc = alloc_dif_verify_bufs(task, 2); 635 SPDK_CU_ASSERT_FATAL(rc == 0); 636 637 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 638 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 639 640 rc = spdk_dif_ctx_init(&task->dif_ctx, 641 g_block_size_bytes + g_md_size_bytes, 642 g_md_size_bytes, true, true, 643 SPDK_DIF_TYPE1, 644 SPDK_DIF_FLAGS_REFTAG_CHECK, 645 10, 0xFFFF, 20, 0, 0, &dif_opts); 646 SPDK_CU_ASSERT_FATAL(rc == 0); 647 648 rc = spdk_dif_generate(task->src_iovs, task->src_iovcnt, task->num_blocks, &task->dif_ctx); 649 SPDK_CU_ASSERT_FATAL(rc == 0); 650 651 req.channel = g_channel; 652 req.src_iovs = task->src_iovs; 653 req.src_iovcnt = task->src_iovcnt; 654 req.num_blocks = task->num_blocks; 655 req.ctx = &task->dif_ctx; 656 req.err = &task->dif_err; 657 req.cb_fn = accel_dif_oper_done; 658 req.cb_arg = task; 659 660 execute_spdk_function(accel_dif_verify_test, &req); 661 CU_ASSERT_EQUAL(g_completion_success, true); 662 663 free_dif_verify_bufs(task); 664 } 665 666 static void 667 accel_dif_verify_op_reftag_init_incorrect_reftag_check(void) 668 { 669 struct spdk_dif_ctx_init_ext_opts dif_opts; 670 struct accel_dif_request req; 671 struct dif_task *task = &g_dif_task; 672 int rc; 673 674 rc = alloc_dif_verify_bufs(task, 2); 675 SPDK_CU_ASSERT_FATAL(rc == 0); 676 677 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 678 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 679 680 rc = spdk_dif_ctx_init(&task->dif_ctx, 681 g_block_size_bytes + g_md_size_bytes, 682 g_md_size_bytes, true, true, 683 SPDK_DIF_TYPE1, 684 SPDK_DIF_FLAGS_REFTAG_CHECK, 685 16, 0xFFFF, 20, 0, 0, &dif_opts); 686 SPDK_CU_ASSERT_FATAL(rc == 0); 687 688 rc = spdk_dif_generate(task->src_iovs, task->src_iovcnt, task->num_blocks, &task->dif_ctx); 689 SPDK_CU_ASSERT_FATAL(rc == 0); 690 691 rc = spdk_dif_ctx_init(&task->dif_ctx, 692 g_block_size_bytes + g_md_size_bytes, 693 g_md_size_bytes, true, true, 694 SPDK_DIF_TYPE1, 695 SPDK_DIF_FLAGS_REFTAG_CHECK, 696 10, 0xFFFF, 20, 0, 0, &dif_opts); 697 SPDK_CU_ASSERT_FATAL(rc == 0); 698 699 req.channel = g_channel; 700 req.src_iovs = task->src_iovs; 701 req.src_iovcnt = task->src_iovcnt; 702 req.num_blocks = task->num_blocks; 703 req.ctx = &task->dif_ctx; 704 req.err = &task->dif_err; 705 req.cb_fn = accel_dif_oper_done; 706 req.cb_arg = task; 707 708 execute_spdk_function(accel_dif_verify_test, &req); 709 CU_ASSERT_EQUAL(g_completion_success, false); 710 711 free_dif_verify_bufs(task); 712 } 713 714 static void 715 accel_dif_verify_copy_op_dif_generated_do_check(uint32_t dif_flags) 716 { 717 struct spdk_dif_ctx_init_ext_opts dif_opts; 718 struct accel_dif_request req; 719 struct dif_task *task = &g_dif_task; 720 int rc; 721 722 rc = alloc_dif_verify_copy_bufs(task, 1); 723 SPDK_CU_ASSERT_FATAL(rc == 0); 724 725 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 726 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 727 728 rc = spdk_dif_ctx_init(&task->dif_ctx, 729 g_block_size_bytes + g_md_size_bytes, 730 g_md_size_bytes, true, true, 731 SPDK_DIF_TYPE1, 732 SPDK_DIF_FLAGS_GUARD_CHECK | 733 SPDK_DIF_FLAGS_APPTAG_CHECK | 734 SPDK_DIF_FLAGS_REFTAG_CHECK, 735 10, 0xFFFF, 20, 0, 0, &dif_opts); 736 SPDK_CU_ASSERT_FATAL(rc == 0); 737 738 rc = spdk_dif_generate(task->src_iovs, task->src_iovcnt, task->num_blocks, &task->dif_ctx); 739 SPDK_CU_ASSERT_FATAL(rc == 0); 740 741 rc = spdk_dif_ctx_init(&task->dif_ctx, 742 g_block_size_bytes + g_md_size_bytes, 743 g_md_size_bytes, true, true, 744 SPDK_DIF_TYPE1, 745 dif_flags, 746 10, 0xFFFF, 20, 0, 0, &dif_opts); 747 SPDK_CU_ASSERT_FATAL(rc == 0); 748 749 req.channel = g_channel; 750 req.dst_iovs = task->dst_iovs; 751 req.dst_iovcnt = task->dst_iovcnt; 752 req.src_iovs = task->src_iovs; 753 req.src_iovcnt = task->src_iovcnt; 754 req.num_blocks = task->num_blocks; 755 req.ctx = &task->dif_ctx; 756 req.err = &task->dif_err; 757 req.cb_fn = accel_dif_oper_done; 758 req.cb_arg = task; 759 760 execute_spdk_function(accel_dif_verify_copy_test, &req); 761 CU_ASSERT_EQUAL(g_completion_success, true); 762 763 free_dif_verify_copy_bufs(task); 764 } 765 766 static void 767 accel_dif_verify_copy_op_dif_generated_guard_check(void) 768 { 769 accel_dif_verify_copy_op_dif_generated_do_check(SPDK_DIF_FLAGS_GUARD_CHECK); 770 } 771 772 static void 773 accel_dif_verify_copy_op_dif_generated_apptag_check(void) 774 { 775 accel_dif_verify_copy_op_dif_generated_do_check(SPDK_DIF_FLAGS_APPTAG_CHECK); 776 } 777 778 static void 779 accel_dif_verify_copy_op_dif_generated_reftag_check(void) 780 { 781 accel_dif_verify_copy_op_dif_generated_do_check(SPDK_DIF_FLAGS_REFTAG_CHECK); 782 } 783 784 static void 785 accel_dif_verify_copy_op_dif_not_generated_do_check(uint32_t dif_flags) 786 { 787 struct spdk_dif_ctx_init_ext_opts dif_opts; 788 struct accel_dif_request req; 789 struct dif_task *task = &g_dif_task; 790 int rc; 791 792 rc = alloc_dif_verify_copy_bufs(task, 1); 793 SPDK_CU_ASSERT_FATAL(rc == 0); 794 795 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 796 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 797 798 rc = spdk_dif_ctx_init(&task->dif_ctx, 799 g_block_size_bytes + g_md_size_bytes, 800 g_md_size_bytes, true, true, 801 SPDK_DIF_TYPE1, 802 dif_flags, 803 10, 0xFFFF, 20, 0, 0, &dif_opts); 804 SPDK_CU_ASSERT_FATAL(rc == 0); 805 806 req.channel = g_channel; 807 req.dst_iovs = task->dst_iovs; 808 req.dst_iovcnt = task->dst_iovcnt; 809 req.src_iovs = task->src_iovs; 810 req.src_iovcnt = task->src_iovcnt; 811 req.num_blocks = task->num_blocks; 812 req.ctx = &task->dif_ctx; 813 req.err = &task->dif_err; 814 req.cb_fn = accel_dif_oper_done; 815 req.cb_arg = task; 816 817 execute_spdk_function(accel_dif_verify_copy_test, &req); 818 CU_ASSERT_EQUAL(g_completion_success, false); 819 CU_ASSERT_EQUAL(accel_dif_error_validate(dif_flags, req.err), true); 820 821 free_dif_verify_copy_bufs(task); 822 } 823 824 static void 825 accel_dif_verify_copy_op_dif_not_generated_guard_check(void) 826 { 827 accel_dif_verify_copy_op_dif_not_generated_do_check(SPDK_DIF_FLAGS_GUARD_CHECK); 828 } 829 830 static void 831 accel_dif_verify_copy_op_dif_not_generated_apptag_check(void) 832 { 833 accel_dif_verify_copy_op_dif_not_generated_do_check(SPDK_DIF_FLAGS_APPTAG_CHECK); 834 } 835 836 static void 837 accel_dif_verify_copy_op_dif_not_generated_reftag_check(void) 838 { 839 accel_dif_verify_copy_op_dif_not_generated_do_check(SPDK_DIF_FLAGS_REFTAG_CHECK); 840 } 841 842 static void 843 accel_dif_generate_copy_op_dif_generated_do_check(uint32_t dif_flags) 844 { 845 struct spdk_dif_ctx_init_ext_opts dif_opts; 846 struct accel_dif_request req; 847 struct dif_task *task = &g_dif_task; 848 struct spdk_dif_error err_blk; 849 int rc; 850 851 rc = alloc_dif_generate_copy_bufs(task, 1); 852 SPDK_CU_ASSERT_FATAL(rc == 0); 853 854 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 855 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 856 857 rc = spdk_dif_ctx_init(&task->dif_ctx, 858 g_block_size_bytes + g_md_size_bytes, 859 g_md_size_bytes, true, true, 860 SPDK_DIF_TYPE1, 861 SPDK_DIF_FLAGS_GUARD_CHECK | 862 SPDK_DIF_FLAGS_APPTAG_CHECK | 863 SPDK_DIF_FLAGS_REFTAG_CHECK, 864 16, 0xFFFF, 10, 0, 0, &dif_opts); 865 SPDK_CU_ASSERT_FATAL(rc == 0); 866 867 req.channel = g_channel; 868 req.dst_iovs = task->dst_iovs; 869 req.dst_iovcnt = task->dst_iovcnt; 870 req.src_iovs = task->src_iovs; 871 req.src_iovcnt = task->src_iovcnt; 872 req.num_blocks = task->num_blocks; 873 req.ctx = &task->dif_ctx; 874 req.err = &task->dif_err; 875 req.cb_fn = accel_dif_oper_done; 876 req.cb_arg = task; 877 878 execute_spdk_function(accel_dif_generate_copy_test, &req); 879 CU_ASSERT_EQUAL(g_completion_success, true); 880 881 rc = spdk_dif_ctx_init(&task->dif_ctx, 882 g_block_size_bytes + g_md_size_bytes, 883 g_md_size_bytes, true, true, 884 SPDK_DIF_TYPE1, 885 dif_flags, 886 16, 0xFFFF, 10, 0, 0, &dif_opts); 887 SPDK_CU_ASSERT_FATAL(rc == 0); 888 889 rc = spdk_dif_verify(req.dst_iovs, req.dst_iovcnt, req.num_blocks, 890 &task->dif_ctx, &err_blk); 891 SPDK_CU_ASSERT_FATAL(rc == 0); 892 893 free_dif_generate_copy_bufs(task); 894 } 895 896 static void 897 accel_dif_generate_copy_op_dif_generated_guard_check(void) 898 { 899 accel_dif_generate_copy_op_dif_generated_do_check(SPDK_DIF_FLAGS_GUARD_CHECK); 900 } 901 902 static void 903 accel_dif_generate_copy_op_dif_generated_apptag_check(void) 904 { 905 accel_dif_generate_copy_op_dif_generated_do_check(SPDK_DIF_FLAGS_APPTAG_CHECK); 906 } 907 908 static void 909 accel_dif_generate_copy_op_dif_generated_reftag_check(void) 910 { 911 accel_dif_generate_copy_op_dif_generated_do_check(SPDK_DIF_FLAGS_REFTAG_CHECK); 912 } 913 914 static void 915 accel_dif_generate_copy_op_dif_generated_no_guard_check_flag_set(void) 916 { 917 const char *module_name = NULL; 918 struct spdk_dif_ctx_init_ext_opts dif_opts; 919 struct accel_dif_request req; 920 struct dif_task *task = &g_dif_task; 921 int rc; 922 923 rc = spdk_accel_get_opc_module_name(SPDK_ACCEL_OPC_DIF_GENERATE_COPY, &module_name); 924 SPDK_CU_ASSERT_FATAL(rc == 0); 925 926 rc = alloc_dif_generate_copy_bufs(task, 1); 927 SPDK_CU_ASSERT_FATAL(rc == 0); 928 929 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 930 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 931 932 rc = spdk_dif_ctx_init(&task->dif_ctx, 933 g_block_size_bytes + g_md_size_bytes, 934 g_md_size_bytes, true, true, 935 SPDK_DIF_TYPE1, 936 SPDK_DIF_FLAGS_APPTAG_CHECK | 937 SPDK_DIF_FLAGS_REFTAG_CHECK, 938 16, 0xFFFF, 10, 0, 0, &dif_opts); 939 SPDK_CU_ASSERT_FATAL(rc == 0); 940 941 req.channel = g_channel; 942 req.dst_iovs = task->dst_iovs; 943 req.dst_iovcnt = task->dst_iovcnt; 944 req.src_iovs = task->src_iovs; 945 req.src_iovcnt = task->src_iovcnt; 946 req.num_blocks = task->num_blocks; 947 req.ctx = &task->dif_ctx; 948 req.err = &task->dif_err; 949 req.cb_fn = accel_dif_oper_done; 950 req.cb_arg = task; 951 952 execute_spdk_function(accel_dif_generate_copy_test, &req); 953 954 /* Intel DSA does not allow for selective DIF fields generation */ 955 if (!strcmp(module_name, "dsa")) { 956 CU_ASSERT_EQUAL(g_completion_success, false); 957 } else if (!strcmp(module_name, "software")) { 958 CU_ASSERT_EQUAL(g_completion_success, true); 959 } else { 960 SPDK_CU_ASSERT_FATAL(false); 961 } 962 963 free_dif_generate_copy_bufs(task); 964 } 965 966 static void 967 accel_dif_generate_copy_op_dif_generated_no_apptag_check_flag_set(void) 968 { 969 const char *module_name = NULL; 970 struct spdk_dif_ctx_init_ext_opts dif_opts; 971 struct accel_dif_request req; 972 struct dif_task *task = &g_dif_task; 973 int rc; 974 975 rc = spdk_accel_get_opc_module_name(SPDK_ACCEL_OPC_DIF_GENERATE_COPY, &module_name); 976 SPDK_CU_ASSERT_FATAL(rc == 0); 977 978 rc = alloc_dif_generate_copy_bufs(task, 1); 979 SPDK_CU_ASSERT_FATAL(rc == 0); 980 981 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 982 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 983 984 rc = spdk_dif_ctx_init(&task->dif_ctx, 985 g_block_size_bytes + g_md_size_bytes, 986 g_md_size_bytes, true, true, 987 SPDK_DIF_TYPE1, 988 SPDK_DIF_FLAGS_GUARD_CHECK | 989 SPDK_DIF_FLAGS_REFTAG_CHECK, 990 16, 0xFFFF, 10, 0, 0, &dif_opts); 991 SPDK_CU_ASSERT_FATAL(rc == 0); 992 993 req.channel = g_channel; 994 req.dst_iovs = task->dst_iovs; 995 req.dst_iovcnt = task->dst_iovcnt; 996 req.src_iovs = task->src_iovs; 997 req.src_iovcnt = task->src_iovcnt; 998 req.num_blocks = task->num_blocks; 999 req.ctx = &task->dif_ctx; 1000 req.err = &task->dif_err; 1001 req.cb_fn = accel_dif_oper_done; 1002 req.cb_arg = task; 1003 1004 execute_spdk_function(accel_dif_generate_copy_test, &req); 1005 1006 /* Intel DSA does not allow for selective DIF fields generation */ 1007 if (!strcmp(module_name, "dsa")) { 1008 CU_ASSERT_EQUAL(g_completion_success, false); 1009 } else if (!strcmp(module_name, "software")) { 1010 CU_ASSERT_EQUAL(g_completion_success, true); 1011 } else { 1012 SPDK_CU_ASSERT_FATAL(false); 1013 } 1014 1015 free_dif_generate_copy_bufs(task); 1016 } 1017 1018 static void 1019 accel_dif_generate_copy_op_dif_generated_no_reftag_check_flag_set(void) 1020 { 1021 const char *module_name = NULL; 1022 struct spdk_dif_ctx_init_ext_opts dif_opts; 1023 struct accel_dif_request req; 1024 struct dif_task *task = &g_dif_task; 1025 int rc; 1026 1027 rc = spdk_accel_get_opc_module_name(SPDK_ACCEL_OPC_DIF_GENERATE_COPY, &module_name); 1028 SPDK_CU_ASSERT_FATAL(rc == 0); 1029 1030 rc = alloc_dif_generate_copy_bufs(task, 1); 1031 SPDK_CU_ASSERT_FATAL(rc == 0); 1032 1033 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 1034 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 1035 1036 rc = spdk_dif_ctx_init(&task->dif_ctx, 1037 g_block_size_bytes + g_md_size_bytes, 1038 g_md_size_bytes, true, true, 1039 SPDK_DIF_TYPE1, 1040 SPDK_DIF_FLAGS_GUARD_CHECK | 1041 SPDK_DIF_FLAGS_APPTAG_CHECK, 1042 16, 0xFFFF, 10, 0, 0, &dif_opts); 1043 SPDK_CU_ASSERT_FATAL(rc == 0); 1044 1045 req.channel = g_channel; 1046 req.dst_iovs = task->dst_iovs; 1047 req.dst_iovcnt = task->dst_iovcnt; 1048 req.src_iovs = task->src_iovs; 1049 req.src_iovcnt = task->src_iovcnt; 1050 req.num_blocks = task->num_blocks; 1051 req.ctx = &task->dif_ctx; 1052 req.err = &task->dif_err; 1053 req.cb_fn = accel_dif_oper_done; 1054 req.cb_arg = task; 1055 1056 execute_spdk_function(accel_dif_generate_copy_test, &req); 1057 1058 /* Intel DSA does not allow for selective DIF fields generation */ 1059 if (!strcmp(module_name, "dsa")) { 1060 CU_ASSERT_EQUAL(g_completion_success, false); 1061 } else if (!strcmp(module_name, "software")) { 1062 CU_ASSERT_EQUAL(g_completion_success, true); 1063 } else { 1064 SPDK_CU_ASSERT_FATAL(false); 1065 } 1066 1067 free_dif_generate_copy_bufs(task); 1068 } 1069 1070 static void 1071 accel_dif_generate_copy_op_iovecs_len_validate(void) 1072 { 1073 struct spdk_dif_ctx_init_ext_opts dif_opts; 1074 struct accel_dif_request req; 1075 struct dif_task *task = &g_dif_task; 1076 int rc; 1077 1078 rc = alloc_dif_generate_copy_bufs(task, 1); 1079 SPDK_CU_ASSERT_FATAL(rc == 0); 1080 1081 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 1082 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 1083 1084 rc = spdk_dif_ctx_init(&task->dif_ctx, 1085 g_block_size_bytes + g_md_size_bytes, 1086 g_md_size_bytes, true, true, 1087 SPDK_DIF_TYPE1, 1088 SPDK_DIF_FLAGS_GUARD_CHECK | 1089 SPDK_DIF_FLAGS_APPTAG_CHECK | 1090 SPDK_DIF_FLAGS_REFTAG_CHECK, 1091 16, 0xFFFF, 10, 0, 0, &dif_opts); 1092 SPDK_CU_ASSERT_FATAL(rc == 0); 1093 1094 req.channel = g_channel; 1095 req.dst_iovs = task->dst_iovs; 1096 /* Make iov_len param incorrect */ 1097 req.dst_iovs->iov_len += 16; 1098 req.dst_iovcnt = task->dst_iovcnt; 1099 req.src_iovs = task->src_iovs; 1100 req.src_iovcnt = task->src_iovcnt; 1101 req.num_blocks = task->num_blocks; 1102 req.ctx = &task->dif_ctx; 1103 req.err = &task->dif_err; 1104 req.cb_fn = accel_dif_oper_done; 1105 req.cb_arg = task; 1106 1107 execute_spdk_function(accel_dif_generate_copy_test, &req); 1108 CU_ASSERT_EQUAL(g_completion_success, false); 1109 1110 free_dif_generate_copy_bufs(task); 1111 } 1112 1113 static void 1114 accel_dif_generate_copy_op_buf_align_validate(void) 1115 { 1116 struct spdk_dif_ctx_init_ext_opts dif_opts; 1117 struct accel_dif_request req; 1118 struct dif_task *task = &g_dif_task; 1119 int rc; 1120 1121 rc = alloc_dif_generate_copy_bufs(task, 1); 1122 SPDK_CU_ASSERT_FATAL(rc == 0); 1123 1124 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 1125 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 1126 1127 rc = spdk_dif_ctx_init(&task->dif_ctx, 1128 g_block_size_bytes + g_md_size_bytes, 1129 g_md_size_bytes, true, true, 1130 SPDK_DIF_TYPE1, 1131 SPDK_DIF_FLAGS_GUARD_CHECK | 1132 SPDK_DIF_FLAGS_APPTAG_CHECK | 1133 SPDK_DIF_FLAGS_REFTAG_CHECK, 1134 16, 0xFFFF, 10, 0, 0, &dif_opts); 1135 SPDK_CU_ASSERT_FATAL(rc == 0); 1136 1137 req.channel = g_channel; 1138 req.dst_iovs = task->dst_iovs; 1139 req.dst_iovcnt = task->dst_iovcnt; 1140 req.src_iovs = task->src_iovs; 1141 req.src_iovcnt = task->src_iovcnt; 1142 req.num_blocks = task->num_blocks; 1143 req.ctx = &task->dif_ctx; 1144 req.err = &task->dif_err; 1145 req.cb_fn = accel_dif_oper_done; 1146 req.cb_arg = task; 1147 1148 execute_spdk_function(accel_dif_generate_copy_test, &req); 1149 CU_ASSERT_EQUAL(g_completion_success, true); 1150 1151 free_dif_generate_copy_bufs(task); 1152 } 1153 1154 static void 1155 _stop_init_thread(void *arg) 1156 { 1157 unsigned num_failures = g_num_failures; 1158 1159 g_num_failures = 0; 1160 1161 assert(spdk_get_thread() == g_thread[WORKER_UT]); 1162 assert(spdk_thread_is_app_thread(NULL)); 1163 execute_spdk_function(exit_io_thread, NULL); 1164 spdk_app_stop(num_failures); 1165 } 1166 1167 static void 1168 stop_init_thread(unsigned num_failures, struct spdk_jsonrpc_request *request) 1169 { 1170 g_num_failures = num_failures; 1171 1172 spdk_thread_send_msg(g_thread[WORKER_UT], _stop_init_thread, request); 1173 } 1174 1175 static int 1176 setup_accel_tests(void) 1177 { 1178 unsigned rc = 0; 1179 CU_pSuite suite = NULL; 1180 1181 suite = CU_add_suite("accel_dif", NULL, NULL); 1182 if (suite == NULL) { 1183 CU_cleanup_registry(); 1184 rc = CU_get_error(); 1185 return -rc; 1186 } 1187 1188 if (CU_add_test(suite, "verify: DIF generated, GUARD check", 1189 accel_dif_verify_op_dif_generated_guard_check) == NULL || 1190 CU_add_test(suite, "verify: DIF generated, APPTAG check", 1191 accel_dif_verify_op_dif_generated_apptag_check) == NULL || 1192 CU_add_test(suite, "verify: DIF generated, REFTAG check", 1193 accel_dif_verify_op_dif_generated_reftag_check) == NULL || 1194 1195 CU_add_test(suite, "verify: DIF not generated, GUARD check", 1196 accel_dif_verify_op_dif_not_generated_guard_check) == NULL || 1197 CU_add_test(suite, "verify: DIF not generated, APPTAG check", 1198 accel_dif_verify_op_dif_not_generated_apptag_check) == NULL || 1199 CU_add_test(suite, "verify: DIF not generated, REFTAG check", 1200 accel_dif_verify_op_dif_not_generated_reftag_check) == NULL || 1201 1202 CU_add_test(suite, "verify: APPTAG correct, APPTAG check", 1203 accel_dif_verify_op_apptag_correct_apptag_check) == NULL || 1204 CU_add_test(suite, "verify: APPTAG incorrect, APPTAG check", 1205 accel_dif_verify_op_apptag_incorrect_apptag_check) == NULL || 1206 CU_add_test(suite, "verify: APPTAG incorrect, no APPTAG check", 1207 accel_dif_verify_op_apptag_incorrect_no_apptag_check) == NULL || 1208 CU_add_test(suite, "verify: REFTAG incorrect, REFTAG ignore", 1209 accel_dif_verify_op_reftag_incorrect_reftag_ignore) == NULL || 1210 1211 CU_add_test(suite, "verify: REFTAG_INIT correct, REFTAG check", 1212 accel_dif_verify_op_reftag_init_correct_reftag_check) == NULL || 1213 CU_add_test(suite, "verify: REFTAG_INIT incorrect, REFTAG check", 1214 accel_dif_verify_op_reftag_init_incorrect_reftag_check) == NULL || 1215 1216 CU_add_test(suite, "verify copy: DIF generated, GUARD check", 1217 accel_dif_verify_copy_op_dif_generated_guard_check) == NULL || 1218 CU_add_test(suite, "verify copy: DIF generated, APPTAG check", 1219 accel_dif_verify_copy_op_dif_generated_apptag_check) == NULL || 1220 CU_add_test(suite, "verify copy: DIF generated, REFTAG check", 1221 accel_dif_verify_copy_op_dif_generated_reftag_check) == NULL || 1222 1223 CU_add_test(suite, "verify copy: DIF not generated, GUARD check", 1224 accel_dif_verify_copy_op_dif_not_generated_guard_check) == NULL || 1225 CU_add_test(suite, "verify copy: DIF not generated, APPTAG check", 1226 accel_dif_verify_copy_op_dif_not_generated_apptag_check) == NULL || 1227 CU_add_test(suite, "verify copy: DIF not generated, REFTAG check", 1228 accel_dif_verify_copy_op_dif_not_generated_reftag_check) == NULL || 1229 1230 CU_add_test(suite, "generate copy: DIF generated, GUARD check", 1231 accel_dif_generate_copy_op_dif_generated_guard_check) == NULL || 1232 CU_add_test(suite, "generate copy: DIF generated, APTTAG check", 1233 accel_dif_generate_copy_op_dif_generated_apptag_check) == NULL || 1234 CU_add_test(suite, "generate copy: DIF generated, REFTAG check", 1235 accel_dif_generate_copy_op_dif_generated_reftag_check) == NULL || 1236 1237 CU_add_test(suite, "generate copy: DIF generated, no GUARD check flag set", 1238 accel_dif_generate_copy_op_dif_generated_no_guard_check_flag_set) == NULL || 1239 CU_add_test(suite, "generate copy: DIF generated, no APPTAG check flag set", 1240 accel_dif_generate_copy_op_dif_generated_no_apptag_check_flag_set) == NULL || 1241 CU_add_test(suite, "generate copy: DIF generated, no REFTAG check flag set", 1242 accel_dif_generate_copy_op_dif_generated_no_reftag_check_flag_set) == NULL || 1243 1244 CU_add_test(suite, "generate copy: iovecs-len validate", 1245 accel_dif_generate_copy_op_iovecs_len_validate) == NULL || 1246 CU_add_test(suite, "generate copy: buffer alignment validate", 1247 accel_dif_generate_copy_op_buf_align_validate) == NULL) { 1248 CU_cleanup_registry(); 1249 rc = CU_get_error(); 1250 return -rc; 1251 } 1252 return 0; 1253 } 1254 1255 static void 1256 get_io_channel(void *arg) 1257 { 1258 g_channel = spdk_accel_get_io_channel(); 1259 assert(g_channel); 1260 wake_ut_thread(); 1261 } 1262 1263 static void 1264 put_io_channel(void *arg) 1265 { 1266 assert(g_channel); 1267 spdk_put_io_channel(g_channel); 1268 wake_ut_thread(); 1269 } 1270 1271 static void 1272 run_accel_test_thread(void *arg) 1273 { 1274 struct spdk_jsonrpc_request *request = arg; 1275 int rc = 0; 1276 1277 execute_spdk_function(get_io_channel, NULL); 1278 if (g_channel == NULL) { 1279 fprintf(stderr, "Unable to get an accel channel\n"); 1280 goto ret; 1281 } 1282 1283 if (CU_initialize_registry() != CUE_SUCCESS) { 1284 /* CUnit error, probably won't recover */ 1285 rc = CU_get_error(); 1286 rc = -rc; 1287 goto ret; 1288 } 1289 1290 rc = setup_accel_tests(); 1291 if (rc < 0) { 1292 /* CUnit error, probably won't recover */ 1293 rc = -rc; 1294 goto ret; 1295 } 1296 CU_basic_set_mode(CU_BRM_VERBOSE); 1297 CU_basic_run_tests(); 1298 rc = CU_get_number_of_failures(); 1299 CU_cleanup_registry(); 1300 1301 ret: 1302 if (g_channel != NULL) { 1303 execute_spdk_function(put_io_channel, NULL); 1304 } 1305 stop_init_thread(rc, request); 1306 } 1307 1308 static void 1309 accel_dif_test_main(void *arg1) 1310 { 1311 struct spdk_cpuset tmpmask = {}; 1312 uint32_t i; 1313 1314 pthread_mutex_init(&g_test_mutex, NULL); 1315 pthread_cond_init(&g_test_cond, NULL); 1316 1317 /* This test runs specifically on at least two cores. 1318 * g_thread[WORKER_UT] is the app_thread on main core from event framework. 1319 * Next one is only for the tests and should always be on separate CPU cores. */ 1320 if (spdk_env_get_core_count() < 3) { 1321 spdk_app_stop(-1); 1322 return; 1323 } 1324 1325 SPDK_ENV_FOREACH_CORE(i) { 1326 if (i == spdk_env_get_current_core()) { 1327 g_thread[WORKER_UT] = spdk_get_thread(); 1328 continue; 1329 } 1330 spdk_cpuset_zero(&tmpmask); 1331 spdk_cpuset_set_cpu(&tmpmask, i, true); 1332 if (g_thread[WORKER_IO] == NULL) { 1333 g_thread[WORKER_IO] = spdk_thread_create("io_thread", &tmpmask); 1334 } 1335 1336 } 1337 1338 spdk_thread_send_msg(g_thread[WORKER_UT], run_accel_test_thread, NULL); 1339 } 1340 1341 static void 1342 accel_dif_usage(void) 1343 { 1344 } 1345 1346 static int 1347 accel_dif_parse_arg(int ch, char *arg) 1348 { 1349 return 0; 1350 } 1351 1352 static void 1353 spdk_dif_shutdown_cb(void) 1354 { 1355 g_shutdown = true; 1356 spdk_thread_send_msg(g_thread[WORKER_UT], _stop_init_thread, NULL); 1357 } 1358 1359 int 1360 main(int argc, char **argv) 1361 { 1362 struct spdk_app_opts opts = {}; 1363 char reactor_mask[8]; 1364 int rc; 1365 1366 spdk_app_opts_init(&opts, sizeof(opts)); 1367 opts.name = "DIF"; 1368 snprintf(reactor_mask, sizeof(reactor_mask), "0x%x", (1 << (SPDK_COUNTOF(g_thread) + 1)) - 1); 1369 opts.reactor_mask = reactor_mask; 1370 opts.shutdown_cb = spdk_dif_shutdown_cb; 1371 opts.rpc_addr = NULL; 1372 1373 if ((rc = spdk_app_parse_args(argc, argv, &opts, "", NULL, 1374 accel_dif_parse_arg, accel_dif_usage)) != 1375 SPDK_APP_PARSE_ARGS_SUCCESS) { 1376 return rc; 1377 } 1378 1379 rc = spdk_app_start(&opts, accel_dif_test_main, NULL); 1380 spdk_app_fini(); 1381 1382 return rc; 1383 } 1384