1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. All rights reserved. 5 * Copyright (c) 2019 Mellanox Technologies LTD. All rights reserved. 6 * Copyright (c) 2021-2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * * Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * * Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the 17 * distribution. 18 * * Neither the name of Intel Corporation nor the names of its 19 * contributors may be used to endorse or promote products derived 20 * from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 #include "spdk_cunit.h" 36 37 #include "common/lib/ut_multithread.c" 38 #include "unit/lib/json_mock.c" 39 40 #include "spdk/config.h" 41 /* HACK: disable VTune integration so the unit test doesn't need VTune headers and libs to build */ 42 #undef SPDK_CONFIG_VTUNE 43 44 #include "bdev/bdev.c" 45 46 DEFINE_STUB(spdk_notify_send, uint64_t, (const char *type, const char *ctx), 0); 47 DEFINE_STUB(spdk_notify_type_register, struct spdk_notify_type *, (const char *type), NULL); 48 DEFINE_STUB(spdk_memory_domain_get_dma_device_id, const char *, (struct spdk_memory_domain *domain), 49 "test_domain"); 50 DEFINE_STUB(spdk_memory_domain_get_dma_device_type, enum spdk_dma_device_type, 51 (struct spdk_memory_domain *domain), 0); 52 53 static bool g_memory_domain_pull_data_called; 54 static bool g_memory_domain_push_data_called; 55 56 DEFINE_RETURN_MOCK(spdk_memory_domain_pull_data, int); 57 int 58 spdk_memory_domain_pull_data(struct spdk_memory_domain *src_domain, void *src_domain_ctx, 59 struct iovec *src_iov, uint32_t src_iov_cnt, struct iovec *dst_iov, uint32_t dst_iov_cnt, 60 spdk_memory_domain_data_cpl_cb cpl_cb, void *cpl_cb_arg) 61 { 62 g_memory_domain_pull_data_called = true; 63 HANDLE_RETURN_MOCK(spdk_memory_domain_pull_data); 64 cpl_cb(cpl_cb_arg, 0); 65 return 0; 66 } 67 68 DEFINE_RETURN_MOCK(spdk_memory_domain_push_data, int); 69 int 70 spdk_memory_domain_push_data(struct spdk_memory_domain *dst_domain, void *dst_domain_ctx, 71 struct iovec *dst_iov, uint32_t dst_iovcnt, struct iovec *src_iov, uint32_t src_iovcnt, 72 spdk_memory_domain_data_cpl_cb cpl_cb, void *cpl_cb_arg) 73 { 74 g_memory_domain_push_data_called = true; 75 HANDLE_RETURN_MOCK(spdk_memory_domain_push_data); 76 cpl_cb(cpl_cb_arg, 0); 77 return 0; 78 } 79 80 int g_status; 81 int g_count; 82 enum spdk_bdev_event_type g_event_type1; 83 enum spdk_bdev_event_type g_event_type2; 84 struct spdk_histogram_data *g_histogram; 85 void *g_unregister_arg; 86 int g_unregister_rc; 87 88 void 89 spdk_scsi_nvme_translate(const struct spdk_bdev_io *bdev_io, 90 int *sc, int *sk, int *asc, int *ascq) 91 { 92 } 93 94 static int 95 null_init(void) 96 { 97 return 0; 98 } 99 100 static int 101 null_clean(void) 102 { 103 return 0; 104 } 105 106 static int 107 stub_destruct(void *ctx) 108 { 109 return 0; 110 } 111 112 struct ut_expected_io { 113 uint8_t type; 114 uint64_t offset; 115 uint64_t length; 116 int iovcnt; 117 struct iovec iov[BDEV_IO_NUM_CHILD_IOV]; 118 void *md_buf; 119 struct spdk_bdev_ext_io_opts *ext_io_opts; 120 TAILQ_ENTRY(ut_expected_io) link; 121 }; 122 123 struct bdev_ut_channel { 124 TAILQ_HEAD(, spdk_bdev_io) outstanding_io; 125 uint32_t outstanding_io_count; 126 TAILQ_HEAD(, ut_expected_io) expected_io; 127 }; 128 129 static bool g_io_done; 130 static struct spdk_bdev_io *g_bdev_io; 131 static enum spdk_bdev_io_status g_io_status; 132 static enum spdk_bdev_io_status g_io_exp_status = SPDK_BDEV_IO_STATUS_SUCCESS; 133 static uint32_t g_bdev_ut_io_device; 134 static struct bdev_ut_channel *g_bdev_ut_channel; 135 static void *g_compare_read_buf; 136 static uint32_t g_compare_read_buf_len; 137 static void *g_compare_write_buf; 138 static uint32_t g_compare_write_buf_len; 139 static bool g_abort_done; 140 static enum spdk_bdev_io_status g_abort_status; 141 static void *g_zcopy_read_buf; 142 static uint32_t g_zcopy_read_buf_len; 143 static void *g_zcopy_write_buf; 144 static uint32_t g_zcopy_write_buf_len; 145 static struct spdk_bdev_io *g_zcopy_bdev_io; 146 147 static struct ut_expected_io * 148 ut_alloc_expected_io(uint8_t type, uint64_t offset, uint64_t length, int iovcnt) 149 { 150 struct ut_expected_io *expected_io; 151 152 expected_io = calloc(1, sizeof(*expected_io)); 153 SPDK_CU_ASSERT_FATAL(expected_io != NULL); 154 155 expected_io->type = type; 156 expected_io->offset = offset; 157 expected_io->length = length; 158 expected_io->iovcnt = iovcnt; 159 160 return expected_io; 161 } 162 163 static void 164 ut_expected_io_set_iov(struct ut_expected_io *expected_io, int pos, void *base, size_t len) 165 { 166 expected_io->iov[pos].iov_base = base; 167 expected_io->iov[pos].iov_len = len; 168 } 169 170 static void 171 stub_submit_request(struct spdk_io_channel *_ch, struct spdk_bdev_io *bdev_io) 172 { 173 struct bdev_ut_channel *ch = spdk_io_channel_get_ctx(_ch); 174 struct ut_expected_io *expected_io; 175 struct iovec *iov, *expected_iov; 176 struct spdk_bdev_io *bio_to_abort; 177 int i; 178 179 g_bdev_io = bdev_io; 180 181 if (g_compare_read_buf && bdev_io->type == SPDK_BDEV_IO_TYPE_READ) { 182 uint32_t len = bdev_io->u.bdev.iovs[0].iov_len; 183 184 CU_ASSERT(bdev_io->u.bdev.iovcnt == 1); 185 CU_ASSERT(g_compare_read_buf_len == len); 186 memcpy(bdev_io->u.bdev.iovs[0].iov_base, g_compare_read_buf, len); 187 } 188 189 if (g_compare_write_buf && bdev_io->type == SPDK_BDEV_IO_TYPE_WRITE) { 190 uint32_t len = bdev_io->u.bdev.iovs[0].iov_len; 191 192 CU_ASSERT(bdev_io->u.bdev.iovcnt == 1); 193 CU_ASSERT(g_compare_write_buf_len == len); 194 memcpy(g_compare_write_buf, bdev_io->u.bdev.iovs[0].iov_base, len); 195 } 196 197 if (g_compare_read_buf && bdev_io->type == SPDK_BDEV_IO_TYPE_COMPARE) { 198 uint32_t len = bdev_io->u.bdev.iovs[0].iov_len; 199 200 CU_ASSERT(bdev_io->u.bdev.iovcnt == 1); 201 CU_ASSERT(g_compare_read_buf_len == len); 202 if (memcmp(bdev_io->u.bdev.iovs[0].iov_base, g_compare_read_buf, len)) { 203 g_io_exp_status = SPDK_BDEV_IO_STATUS_MISCOMPARE; 204 } 205 } 206 207 if (bdev_io->type == SPDK_BDEV_IO_TYPE_ABORT) { 208 if (g_io_exp_status == SPDK_BDEV_IO_STATUS_SUCCESS) { 209 TAILQ_FOREACH(bio_to_abort, &ch->outstanding_io, module_link) { 210 if (bio_to_abort == bdev_io->u.abort.bio_to_abort) { 211 TAILQ_REMOVE(&ch->outstanding_io, bio_to_abort, module_link); 212 ch->outstanding_io_count--; 213 spdk_bdev_io_complete(bio_to_abort, SPDK_BDEV_IO_STATUS_FAILED); 214 break; 215 } 216 } 217 } 218 } 219 220 if (bdev_io->type == SPDK_BDEV_IO_TYPE_ZCOPY) { 221 if (bdev_io->u.bdev.zcopy.start) { 222 g_zcopy_bdev_io = bdev_io; 223 if (bdev_io->u.bdev.zcopy.populate) { 224 /* Start of a read */ 225 CU_ASSERT(g_zcopy_read_buf != NULL); 226 CU_ASSERT(g_zcopy_read_buf_len > 0); 227 bdev_io->u.bdev.iovs[0].iov_base = g_zcopy_read_buf; 228 bdev_io->u.bdev.iovs[0].iov_len = g_zcopy_read_buf_len; 229 bdev_io->u.bdev.iovcnt = 1; 230 } else { 231 /* Start of a write */ 232 CU_ASSERT(g_zcopy_write_buf != NULL); 233 CU_ASSERT(g_zcopy_write_buf_len > 0); 234 bdev_io->u.bdev.iovs[0].iov_base = g_zcopy_write_buf; 235 bdev_io->u.bdev.iovs[0].iov_len = g_zcopy_write_buf_len; 236 bdev_io->u.bdev.iovcnt = 1; 237 } 238 } else { 239 if (bdev_io->u.bdev.zcopy.commit) { 240 /* End of write */ 241 CU_ASSERT(bdev_io->u.bdev.iovs[0].iov_base == g_zcopy_write_buf); 242 CU_ASSERT(bdev_io->u.bdev.iovs[0].iov_len == g_zcopy_write_buf_len); 243 CU_ASSERT(bdev_io->u.bdev.iovcnt == 1); 244 g_zcopy_write_buf = NULL; 245 g_zcopy_write_buf_len = 0; 246 } else { 247 /* End of read */ 248 CU_ASSERT(bdev_io->u.bdev.iovs[0].iov_base == g_zcopy_read_buf); 249 CU_ASSERT(bdev_io->u.bdev.iovs[0].iov_len == g_zcopy_read_buf_len); 250 CU_ASSERT(bdev_io->u.bdev.iovcnt == 1); 251 g_zcopy_read_buf = NULL; 252 g_zcopy_read_buf_len = 0; 253 } 254 } 255 } 256 257 TAILQ_INSERT_TAIL(&ch->outstanding_io, bdev_io, module_link); 258 ch->outstanding_io_count++; 259 260 expected_io = TAILQ_FIRST(&ch->expected_io); 261 if (expected_io == NULL) { 262 return; 263 } 264 TAILQ_REMOVE(&ch->expected_io, expected_io, link); 265 266 if (expected_io->type != SPDK_BDEV_IO_TYPE_INVALID) { 267 CU_ASSERT(bdev_io->type == expected_io->type); 268 } 269 270 if (expected_io->md_buf != NULL) { 271 CU_ASSERT(expected_io->md_buf == bdev_io->u.bdev.md_buf); 272 if (bdev_io->u.bdev.ext_opts) { 273 CU_ASSERT(expected_io->md_buf == bdev_io->u.bdev.ext_opts->metadata); 274 } 275 } 276 277 if (expected_io->length == 0) { 278 free(expected_io); 279 return; 280 } 281 282 CU_ASSERT(expected_io->offset == bdev_io->u.bdev.offset_blocks); 283 CU_ASSERT(expected_io->length = bdev_io->u.bdev.num_blocks); 284 285 if (expected_io->iovcnt == 0) { 286 free(expected_io); 287 /* UNMAP, WRITE_ZEROES and FLUSH don't have iovs, so we can just return now. */ 288 return; 289 } 290 291 CU_ASSERT(expected_io->iovcnt == bdev_io->u.bdev.iovcnt); 292 for (i = 0; i < expected_io->iovcnt; i++) { 293 expected_iov = &expected_io->iov[i]; 294 if (bdev_io->internal.orig_iovcnt == 0) { 295 iov = &bdev_io->u.bdev.iovs[i]; 296 } else { 297 iov = bdev_io->internal.orig_iovs; 298 } 299 CU_ASSERT(iov->iov_len == expected_iov->iov_len); 300 CU_ASSERT(iov->iov_base == expected_iov->iov_base); 301 } 302 303 if (expected_io->ext_io_opts) { 304 CU_ASSERT(expected_io->ext_io_opts == bdev_io->internal.ext_opts) 305 } 306 307 free(expected_io); 308 } 309 310 static void 311 stub_submit_request_get_buf_cb(struct spdk_io_channel *_ch, 312 struct spdk_bdev_io *bdev_io, bool success) 313 { 314 CU_ASSERT(success == true); 315 316 stub_submit_request(_ch, bdev_io); 317 } 318 319 static void 320 stub_submit_request_get_buf(struct spdk_io_channel *_ch, struct spdk_bdev_io *bdev_io) 321 { 322 spdk_bdev_io_get_buf(bdev_io, stub_submit_request_get_buf_cb, 323 bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen); 324 } 325 326 static uint32_t 327 stub_complete_io(uint32_t num_to_complete) 328 { 329 struct bdev_ut_channel *ch = g_bdev_ut_channel; 330 struct spdk_bdev_io *bdev_io; 331 static enum spdk_bdev_io_status io_status; 332 uint32_t num_completed = 0; 333 334 while (num_completed < num_to_complete) { 335 if (TAILQ_EMPTY(&ch->outstanding_io)) { 336 break; 337 } 338 bdev_io = TAILQ_FIRST(&ch->outstanding_io); 339 TAILQ_REMOVE(&ch->outstanding_io, bdev_io, module_link); 340 ch->outstanding_io_count--; 341 io_status = g_io_exp_status == SPDK_BDEV_IO_STATUS_SUCCESS ? SPDK_BDEV_IO_STATUS_SUCCESS : 342 g_io_exp_status; 343 spdk_bdev_io_complete(bdev_io, io_status); 344 num_completed++; 345 } 346 347 return num_completed; 348 } 349 350 static struct spdk_io_channel * 351 bdev_ut_get_io_channel(void *ctx) 352 { 353 return spdk_get_io_channel(&g_bdev_ut_io_device); 354 } 355 356 static bool g_io_types_supported[SPDK_BDEV_NUM_IO_TYPES] = { 357 [SPDK_BDEV_IO_TYPE_READ] = true, 358 [SPDK_BDEV_IO_TYPE_WRITE] = true, 359 [SPDK_BDEV_IO_TYPE_COMPARE] = true, 360 [SPDK_BDEV_IO_TYPE_UNMAP] = true, 361 [SPDK_BDEV_IO_TYPE_FLUSH] = true, 362 [SPDK_BDEV_IO_TYPE_RESET] = true, 363 [SPDK_BDEV_IO_TYPE_NVME_ADMIN] = true, 364 [SPDK_BDEV_IO_TYPE_NVME_IO] = true, 365 [SPDK_BDEV_IO_TYPE_NVME_IO_MD] = true, 366 [SPDK_BDEV_IO_TYPE_WRITE_ZEROES] = true, 367 [SPDK_BDEV_IO_TYPE_ZCOPY] = true, 368 [SPDK_BDEV_IO_TYPE_ABORT] = true, 369 }; 370 371 static void 372 ut_enable_io_type(enum spdk_bdev_io_type io_type, bool enable) 373 { 374 g_io_types_supported[io_type] = enable; 375 } 376 377 static bool 378 stub_io_type_supported(void *_bdev, enum spdk_bdev_io_type io_type) 379 { 380 return g_io_types_supported[io_type]; 381 } 382 383 static struct spdk_bdev_fn_table fn_table = { 384 .destruct = stub_destruct, 385 .submit_request = stub_submit_request, 386 .get_io_channel = bdev_ut_get_io_channel, 387 .io_type_supported = stub_io_type_supported, 388 }; 389 390 static int 391 bdev_ut_create_ch(void *io_device, void *ctx_buf) 392 { 393 struct bdev_ut_channel *ch = ctx_buf; 394 395 CU_ASSERT(g_bdev_ut_channel == NULL); 396 g_bdev_ut_channel = ch; 397 398 TAILQ_INIT(&ch->outstanding_io); 399 ch->outstanding_io_count = 0; 400 TAILQ_INIT(&ch->expected_io); 401 return 0; 402 } 403 404 static void 405 bdev_ut_destroy_ch(void *io_device, void *ctx_buf) 406 { 407 CU_ASSERT(g_bdev_ut_channel != NULL); 408 g_bdev_ut_channel = NULL; 409 } 410 411 struct spdk_bdev_module bdev_ut_if; 412 413 static int 414 bdev_ut_module_init(void) 415 { 416 spdk_io_device_register(&g_bdev_ut_io_device, bdev_ut_create_ch, bdev_ut_destroy_ch, 417 sizeof(struct bdev_ut_channel), NULL); 418 spdk_bdev_module_init_done(&bdev_ut_if); 419 return 0; 420 } 421 422 static void 423 bdev_ut_module_fini(void) 424 { 425 spdk_io_device_unregister(&g_bdev_ut_io_device, NULL); 426 } 427 428 struct spdk_bdev_module bdev_ut_if = { 429 .name = "bdev_ut", 430 .module_init = bdev_ut_module_init, 431 .module_fini = bdev_ut_module_fini, 432 .async_init = true, 433 }; 434 435 static void vbdev_ut_examine(struct spdk_bdev *bdev); 436 437 static int 438 vbdev_ut_module_init(void) 439 { 440 return 0; 441 } 442 443 static void 444 vbdev_ut_module_fini(void) 445 { 446 } 447 448 struct spdk_bdev_module vbdev_ut_if = { 449 .name = "vbdev_ut", 450 .module_init = vbdev_ut_module_init, 451 .module_fini = vbdev_ut_module_fini, 452 .examine_config = vbdev_ut_examine, 453 }; 454 455 SPDK_BDEV_MODULE_REGISTER(bdev_ut, &bdev_ut_if) 456 SPDK_BDEV_MODULE_REGISTER(vbdev_ut, &vbdev_ut_if) 457 458 static void 459 vbdev_ut_examine(struct spdk_bdev *bdev) 460 { 461 spdk_bdev_module_examine_done(&vbdev_ut_if); 462 } 463 464 static struct spdk_bdev * 465 allocate_bdev(char *name) 466 { 467 struct spdk_bdev *bdev; 468 int rc; 469 470 bdev = calloc(1, sizeof(*bdev)); 471 SPDK_CU_ASSERT_FATAL(bdev != NULL); 472 473 bdev->name = name; 474 bdev->fn_table = &fn_table; 475 bdev->module = &bdev_ut_if; 476 bdev->blockcnt = 1024; 477 bdev->blocklen = 512; 478 479 rc = spdk_bdev_register(bdev); 480 CU_ASSERT(rc == 0); 481 482 return bdev; 483 } 484 485 static struct spdk_bdev * 486 allocate_vbdev(char *name) 487 { 488 struct spdk_bdev *bdev; 489 int rc; 490 491 bdev = calloc(1, sizeof(*bdev)); 492 SPDK_CU_ASSERT_FATAL(bdev != NULL); 493 494 bdev->name = name; 495 bdev->fn_table = &fn_table; 496 bdev->module = &vbdev_ut_if; 497 498 rc = spdk_bdev_register(bdev); 499 CU_ASSERT(rc == 0); 500 501 return bdev; 502 } 503 504 static void 505 free_bdev(struct spdk_bdev *bdev) 506 { 507 spdk_bdev_unregister(bdev, NULL, NULL); 508 poll_threads(); 509 memset(bdev, 0xFF, sizeof(*bdev)); 510 free(bdev); 511 } 512 513 static void 514 free_vbdev(struct spdk_bdev *bdev) 515 { 516 spdk_bdev_unregister(bdev, NULL, NULL); 517 poll_threads(); 518 memset(bdev, 0xFF, sizeof(*bdev)); 519 free(bdev); 520 } 521 522 static void 523 get_device_stat_cb(struct spdk_bdev *bdev, struct spdk_bdev_io_stat *stat, void *cb_arg, int rc) 524 { 525 const char *bdev_name; 526 527 CU_ASSERT(bdev != NULL); 528 CU_ASSERT(rc == 0); 529 bdev_name = spdk_bdev_get_name(bdev); 530 CU_ASSERT_STRING_EQUAL(bdev_name, "bdev0"); 531 532 free(stat); 533 534 *(bool *)cb_arg = true; 535 } 536 537 static void 538 bdev_unregister_cb(void *cb_arg, int rc) 539 { 540 g_unregister_arg = cb_arg; 541 g_unregister_rc = rc; 542 } 543 544 static void 545 bdev_ut_event_cb(enum spdk_bdev_event_type type, struct spdk_bdev *bdev, void *event_ctx) 546 { 547 } 548 549 static void 550 bdev_open_cb1(enum spdk_bdev_event_type type, struct spdk_bdev *bdev, void *event_ctx) 551 { 552 struct spdk_bdev_desc *desc = *(struct spdk_bdev_desc **)event_ctx; 553 554 g_event_type1 = type; 555 if (SPDK_BDEV_EVENT_REMOVE == type) { 556 spdk_bdev_close(desc); 557 } 558 } 559 560 static void 561 bdev_open_cb2(enum spdk_bdev_event_type type, struct spdk_bdev *bdev, void *event_ctx) 562 { 563 struct spdk_bdev_desc *desc = *(struct spdk_bdev_desc **)event_ctx; 564 565 g_event_type2 = type; 566 if (SPDK_BDEV_EVENT_REMOVE == type) { 567 spdk_bdev_close(desc); 568 } 569 } 570 571 static void 572 get_device_stat_test(void) 573 { 574 struct spdk_bdev *bdev; 575 struct spdk_bdev_io_stat *stat; 576 bool done; 577 578 bdev = allocate_bdev("bdev0"); 579 stat = calloc(1, sizeof(struct spdk_bdev_io_stat)); 580 if (stat == NULL) { 581 free_bdev(bdev); 582 return; 583 } 584 585 done = false; 586 spdk_bdev_get_device_stat(bdev, stat, get_device_stat_cb, &done); 587 while (!done) { poll_threads(); } 588 589 free_bdev(bdev); 590 } 591 592 static void 593 open_write_test(void) 594 { 595 struct spdk_bdev *bdev[9]; 596 struct spdk_bdev_desc *desc[9] = {}; 597 int rc; 598 599 /* 600 * Create a tree of bdevs to test various open w/ write cases. 601 * 602 * bdev0 through bdev3 are physical block devices, such as NVMe 603 * namespaces or Ceph block devices. 604 * 605 * bdev4 is a virtual bdev with multiple base bdevs. This models 606 * caching or RAID use cases. 607 * 608 * bdev5 through bdev7 are all virtual bdevs with the same base 609 * bdev (except bdev7). This models partitioning or logical volume 610 * use cases. 611 * 612 * bdev7 is a virtual bdev with multiple base bdevs. One of base bdevs 613 * (bdev2) is shared with other virtual bdevs: bdev5 and bdev6. This 614 * models caching, RAID, partitioning or logical volumes use cases. 615 * 616 * bdev8 is a virtual bdev with multiple base bdevs, but these 617 * base bdevs are themselves virtual bdevs. 618 * 619 * bdev8 620 * | 621 * +----------+ 622 * | | 623 * bdev4 bdev5 bdev6 bdev7 624 * | | | | 625 * +---+---+ +---+ + +---+---+ 626 * | | \ | / \ 627 * bdev0 bdev1 bdev2 bdev3 628 */ 629 630 bdev[0] = allocate_bdev("bdev0"); 631 rc = spdk_bdev_module_claim_bdev(bdev[0], NULL, &bdev_ut_if); 632 CU_ASSERT(rc == 0); 633 634 bdev[1] = allocate_bdev("bdev1"); 635 rc = spdk_bdev_module_claim_bdev(bdev[1], NULL, &bdev_ut_if); 636 CU_ASSERT(rc == 0); 637 638 bdev[2] = allocate_bdev("bdev2"); 639 rc = spdk_bdev_module_claim_bdev(bdev[2], NULL, &bdev_ut_if); 640 CU_ASSERT(rc == 0); 641 642 bdev[3] = allocate_bdev("bdev3"); 643 rc = spdk_bdev_module_claim_bdev(bdev[3], NULL, &bdev_ut_if); 644 CU_ASSERT(rc == 0); 645 646 bdev[4] = allocate_vbdev("bdev4"); 647 rc = spdk_bdev_module_claim_bdev(bdev[4], NULL, &bdev_ut_if); 648 CU_ASSERT(rc == 0); 649 650 bdev[5] = allocate_vbdev("bdev5"); 651 rc = spdk_bdev_module_claim_bdev(bdev[5], NULL, &bdev_ut_if); 652 CU_ASSERT(rc == 0); 653 654 bdev[6] = allocate_vbdev("bdev6"); 655 656 bdev[7] = allocate_vbdev("bdev7"); 657 658 bdev[8] = allocate_vbdev("bdev8"); 659 660 /* Open bdev0 read-only. This should succeed. */ 661 rc = spdk_bdev_open_ext("bdev0", false, bdev_ut_event_cb, NULL, &desc[0]); 662 CU_ASSERT(rc == 0); 663 SPDK_CU_ASSERT_FATAL(desc[0] != NULL); 664 CU_ASSERT(bdev[0] == spdk_bdev_desc_get_bdev(desc[0])); 665 spdk_bdev_close(desc[0]); 666 667 /* 668 * Open bdev1 read/write. This should fail since bdev1 has been claimed 669 * by a vbdev module. 670 */ 671 rc = spdk_bdev_open_ext("bdev1", true, bdev_ut_event_cb, NULL, &desc[1]); 672 CU_ASSERT(rc == -EPERM); 673 674 /* 675 * Open bdev4 read/write. This should fail since bdev3 has been claimed 676 * by a vbdev module. 677 */ 678 rc = spdk_bdev_open_ext("bdev4", true, bdev_ut_event_cb, NULL, &desc[4]); 679 CU_ASSERT(rc == -EPERM); 680 681 /* Open bdev4 read-only. This should succeed. */ 682 rc = spdk_bdev_open_ext("bdev4", false, bdev_ut_event_cb, NULL, &desc[4]); 683 CU_ASSERT(rc == 0); 684 SPDK_CU_ASSERT_FATAL(desc[4] != NULL); 685 CU_ASSERT(bdev[4] == spdk_bdev_desc_get_bdev(desc[4])); 686 spdk_bdev_close(desc[4]); 687 688 /* 689 * Open bdev8 read/write. This should succeed since it is a leaf 690 * bdev. 691 */ 692 rc = spdk_bdev_open_ext("bdev8", true, bdev_ut_event_cb, NULL, &desc[8]); 693 CU_ASSERT(rc == 0); 694 SPDK_CU_ASSERT_FATAL(desc[8] != NULL); 695 CU_ASSERT(bdev[8] == spdk_bdev_desc_get_bdev(desc[8])); 696 spdk_bdev_close(desc[8]); 697 698 /* 699 * Open bdev5 read/write. This should fail since bdev4 has been claimed 700 * by a vbdev module. 701 */ 702 rc = spdk_bdev_open_ext("bdev5", true, bdev_ut_event_cb, NULL, &desc[5]); 703 CU_ASSERT(rc == -EPERM); 704 705 /* Open bdev4 read-only. This should succeed. */ 706 rc = spdk_bdev_open_ext("bdev5", false, bdev_ut_event_cb, NULL, &desc[5]); 707 CU_ASSERT(rc == 0); 708 SPDK_CU_ASSERT_FATAL(desc[5] != NULL); 709 CU_ASSERT(bdev[5] == spdk_bdev_desc_get_bdev(desc[5])); 710 spdk_bdev_close(desc[5]); 711 712 free_vbdev(bdev[8]); 713 714 free_vbdev(bdev[5]); 715 free_vbdev(bdev[6]); 716 free_vbdev(bdev[7]); 717 718 free_vbdev(bdev[4]); 719 720 free_bdev(bdev[0]); 721 free_bdev(bdev[1]); 722 free_bdev(bdev[2]); 723 free_bdev(bdev[3]); 724 } 725 726 static void 727 claim_test(void) 728 { 729 struct spdk_bdev *bdev; 730 struct spdk_bdev_desc *desc, *open_desc; 731 int rc; 732 uint32_t count; 733 734 /* 735 * A vbdev that uses a read-only bdev may need it to remain read-only. 736 * To do so, it opens the bdev read-only, then claims it without 737 * passing a spdk_bdev_desc. 738 */ 739 bdev = allocate_bdev("bdev0"); 740 rc = spdk_bdev_open_ext("bdev0", false, bdev_ut_event_cb, NULL, &desc); 741 CU_ASSERT(rc == 0); 742 CU_ASSERT(desc->write == false); 743 744 rc = spdk_bdev_module_claim_bdev(bdev, NULL, &bdev_ut_if); 745 CU_ASSERT(rc == 0); 746 CU_ASSERT(bdev->internal.claim_module == &bdev_ut_if); 747 748 /* There should be only one open descriptor and it should still be ro */ 749 count = 0; 750 TAILQ_FOREACH(open_desc, &bdev->internal.open_descs, link) { 751 CU_ASSERT(open_desc == desc); 752 CU_ASSERT(!open_desc->write); 753 count++; 754 } 755 CU_ASSERT(count == 1); 756 757 /* A read-only bdev is upgraded to read-write if desc is passed. */ 758 spdk_bdev_module_release_bdev(bdev); 759 rc = spdk_bdev_module_claim_bdev(bdev, desc, &bdev_ut_if); 760 CU_ASSERT(rc == 0); 761 CU_ASSERT(bdev->internal.claim_module == &bdev_ut_if); 762 763 /* There should be only one open descriptor and it should be rw */ 764 count = 0; 765 TAILQ_FOREACH(open_desc, &bdev->internal.open_descs, link) { 766 CU_ASSERT(open_desc == desc); 767 CU_ASSERT(open_desc->write); 768 count++; 769 } 770 CU_ASSERT(count == 1); 771 772 spdk_bdev_close(desc); 773 free_bdev(bdev); 774 } 775 776 static void 777 bytes_to_blocks_test(void) 778 { 779 struct spdk_bdev bdev; 780 uint64_t offset_blocks, num_blocks; 781 782 memset(&bdev, 0, sizeof(bdev)); 783 784 bdev.blocklen = 512; 785 786 /* All parameters valid */ 787 offset_blocks = 0; 788 num_blocks = 0; 789 CU_ASSERT(bdev_bytes_to_blocks(&bdev, 512, &offset_blocks, 1024, &num_blocks) == 0); 790 CU_ASSERT(offset_blocks == 1); 791 CU_ASSERT(num_blocks == 2); 792 793 /* Offset not a block multiple */ 794 CU_ASSERT(bdev_bytes_to_blocks(&bdev, 3, &offset_blocks, 512, &num_blocks) != 0); 795 796 /* Length not a block multiple */ 797 CU_ASSERT(bdev_bytes_to_blocks(&bdev, 512, &offset_blocks, 3, &num_blocks) != 0); 798 799 /* In case blocklen not the power of two */ 800 bdev.blocklen = 100; 801 CU_ASSERT(bdev_bytes_to_blocks(&bdev, 100, &offset_blocks, 200, &num_blocks) == 0); 802 CU_ASSERT(offset_blocks == 1); 803 CU_ASSERT(num_blocks == 2); 804 805 /* Offset not a block multiple */ 806 CU_ASSERT(bdev_bytes_to_blocks(&bdev, 3, &offset_blocks, 100, &num_blocks) != 0); 807 808 /* Length not a block multiple */ 809 CU_ASSERT(bdev_bytes_to_blocks(&bdev, 100, &offset_blocks, 3, &num_blocks) != 0); 810 } 811 812 static void 813 num_blocks_test(void) 814 { 815 struct spdk_bdev bdev; 816 struct spdk_bdev_desc *desc = NULL; 817 int rc; 818 819 memset(&bdev, 0, sizeof(bdev)); 820 bdev.name = "num_blocks"; 821 bdev.fn_table = &fn_table; 822 bdev.module = &bdev_ut_if; 823 spdk_bdev_register(&bdev); 824 spdk_bdev_notify_blockcnt_change(&bdev, 50); 825 826 /* Growing block number */ 827 CU_ASSERT(spdk_bdev_notify_blockcnt_change(&bdev, 70) == 0); 828 /* Shrinking block number */ 829 CU_ASSERT(spdk_bdev_notify_blockcnt_change(&bdev, 30) == 0); 830 831 rc = spdk_bdev_open_ext("num_blocks", false, bdev_open_cb1, &desc, &desc); 832 CU_ASSERT(rc == 0); 833 SPDK_CU_ASSERT_FATAL(desc != NULL); 834 CU_ASSERT(&bdev == spdk_bdev_desc_get_bdev(desc)); 835 836 /* Growing block number */ 837 CU_ASSERT(spdk_bdev_notify_blockcnt_change(&bdev, 80) == 0); 838 /* Shrinking block number */ 839 CU_ASSERT(spdk_bdev_notify_blockcnt_change(&bdev, 20) != 0); 840 841 g_event_type1 = 0xFF; 842 /* Growing block number */ 843 CU_ASSERT(spdk_bdev_notify_blockcnt_change(&bdev, 90) == 0); 844 845 poll_threads(); 846 CU_ASSERT_EQUAL(g_event_type1, SPDK_BDEV_EVENT_RESIZE); 847 848 g_event_type1 = 0xFF; 849 /* Growing block number and closing */ 850 CU_ASSERT(spdk_bdev_notify_blockcnt_change(&bdev, 100) == 0); 851 852 spdk_bdev_close(desc); 853 spdk_bdev_unregister(&bdev, NULL, NULL); 854 855 poll_threads(); 856 857 /* Callback is not called for closed device */ 858 CU_ASSERT_EQUAL(g_event_type1, 0xFF); 859 } 860 861 static void 862 io_valid_test(void) 863 { 864 struct spdk_bdev bdev; 865 866 memset(&bdev, 0, sizeof(bdev)); 867 868 bdev.blocklen = 512; 869 CU_ASSERT(pthread_mutex_init(&bdev.internal.mutex, NULL) == 0); 870 871 spdk_bdev_notify_blockcnt_change(&bdev, 100); 872 873 /* All parameters valid */ 874 CU_ASSERT(bdev_io_valid_blocks(&bdev, 1, 2) == true); 875 876 /* Last valid block */ 877 CU_ASSERT(bdev_io_valid_blocks(&bdev, 99, 1) == true); 878 879 /* Offset past end of bdev */ 880 CU_ASSERT(bdev_io_valid_blocks(&bdev, 100, 1) == false); 881 882 /* Offset + length past end of bdev */ 883 CU_ASSERT(bdev_io_valid_blocks(&bdev, 99, 2) == false); 884 885 /* Offset near end of uint64_t range (2^64 - 1) */ 886 CU_ASSERT(bdev_io_valid_blocks(&bdev, 18446744073709551615ULL, 1) == false); 887 888 CU_ASSERT(pthread_mutex_destroy(&bdev.internal.mutex) == 0); 889 } 890 891 static void 892 alias_add_del_test(void) 893 { 894 struct spdk_bdev *bdev[3]; 895 int rc; 896 897 /* Creating and registering bdevs */ 898 bdev[0] = allocate_bdev("bdev0"); 899 SPDK_CU_ASSERT_FATAL(bdev[0] != 0); 900 901 bdev[1] = allocate_bdev("bdev1"); 902 SPDK_CU_ASSERT_FATAL(bdev[1] != 0); 903 904 bdev[2] = allocate_bdev("bdev2"); 905 SPDK_CU_ASSERT_FATAL(bdev[2] != 0); 906 907 poll_threads(); 908 909 /* 910 * Trying adding an alias identical to name. 911 * Alias is identical to name, so it can not be added to aliases list 912 */ 913 rc = spdk_bdev_alias_add(bdev[0], bdev[0]->name); 914 CU_ASSERT(rc == -EEXIST); 915 916 /* 917 * Trying to add empty alias, 918 * this one should fail 919 */ 920 rc = spdk_bdev_alias_add(bdev[0], NULL); 921 CU_ASSERT(rc == -EINVAL); 922 923 /* Trying adding same alias to two different registered bdevs */ 924 925 /* Alias is used first time, so this one should pass */ 926 rc = spdk_bdev_alias_add(bdev[0], "proper alias 0"); 927 CU_ASSERT(rc == 0); 928 929 /* Alias was added to another bdev, so this one should fail */ 930 rc = spdk_bdev_alias_add(bdev[1], "proper alias 0"); 931 CU_ASSERT(rc == -EEXIST); 932 933 /* Alias is used first time, so this one should pass */ 934 rc = spdk_bdev_alias_add(bdev[1], "proper alias 1"); 935 CU_ASSERT(rc == 0); 936 937 /* Trying removing an alias from registered bdevs */ 938 939 /* Alias is not on a bdev aliases list, so this one should fail */ 940 rc = spdk_bdev_alias_del(bdev[0], "not existing"); 941 CU_ASSERT(rc == -ENOENT); 942 943 /* Alias is present on a bdev aliases list, so this one should pass */ 944 rc = spdk_bdev_alias_del(bdev[0], "proper alias 0"); 945 CU_ASSERT(rc == 0); 946 947 /* Alias is present on a bdev aliases list, so this one should pass */ 948 rc = spdk_bdev_alias_del(bdev[1], "proper alias 1"); 949 CU_ASSERT(rc == 0); 950 951 /* Trying to remove name instead of alias, so this one should fail, name cannot be changed or removed */ 952 rc = spdk_bdev_alias_del(bdev[0], bdev[0]->name); 953 CU_ASSERT(rc != 0); 954 955 /* Trying to del all alias from empty alias list */ 956 spdk_bdev_alias_del_all(bdev[2]); 957 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&bdev[2]->aliases)); 958 959 /* Trying to del all alias from non-empty alias list */ 960 rc = spdk_bdev_alias_add(bdev[2], "alias0"); 961 CU_ASSERT(rc == 0); 962 rc = spdk_bdev_alias_add(bdev[2], "alias1"); 963 CU_ASSERT(rc == 0); 964 spdk_bdev_alias_del_all(bdev[2]); 965 CU_ASSERT(TAILQ_EMPTY(&bdev[2]->aliases)); 966 967 /* Unregister and free bdevs */ 968 spdk_bdev_unregister(bdev[0], NULL, NULL); 969 spdk_bdev_unregister(bdev[1], NULL, NULL); 970 spdk_bdev_unregister(bdev[2], NULL, NULL); 971 972 poll_threads(); 973 974 free(bdev[0]); 975 free(bdev[1]); 976 free(bdev[2]); 977 } 978 979 static void 980 io_done(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg) 981 { 982 g_io_done = true; 983 g_io_status = bdev_io->internal.status; 984 if ((bdev_io->type == SPDK_BDEV_IO_TYPE_ZCOPY) && 985 (bdev_io->u.bdev.zcopy.start)) { 986 g_zcopy_bdev_io = bdev_io; 987 } else { 988 spdk_bdev_free_io(bdev_io); 989 g_zcopy_bdev_io = NULL; 990 } 991 } 992 993 static void 994 bdev_init_cb(void *arg, int rc) 995 { 996 CU_ASSERT(rc == 0); 997 } 998 999 static void 1000 bdev_fini_cb(void *arg) 1001 { 1002 } 1003 1004 struct bdev_ut_io_wait_entry { 1005 struct spdk_bdev_io_wait_entry entry; 1006 struct spdk_io_channel *io_ch; 1007 struct spdk_bdev_desc *desc; 1008 bool submitted; 1009 }; 1010 1011 static void 1012 io_wait_cb(void *arg) 1013 { 1014 struct bdev_ut_io_wait_entry *entry = arg; 1015 int rc; 1016 1017 rc = spdk_bdev_read_blocks(entry->desc, entry->io_ch, NULL, 0, 1, io_done, NULL); 1018 CU_ASSERT(rc == 0); 1019 entry->submitted = true; 1020 } 1021 1022 static void 1023 bdev_io_types_test(void) 1024 { 1025 struct spdk_bdev *bdev; 1026 struct spdk_bdev_desc *desc = NULL; 1027 struct spdk_io_channel *io_ch; 1028 struct spdk_bdev_opts bdev_opts = {}; 1029 int rc; 1030 1031 spdk_bdev_get_opts(&bdev_opts, sizeof(bdev_opts)); 1032 bdev_opts.bdev_io_pool_size = 4; 1033 bdev_opts.bdev_io_cache_size = 2; 1034 1035 rc = spdk_bdev_set_opts(&bdev_opts); 1036 CU_ASSERT(rc == 0); 1037 spdk_bdev_initialize(bdev_init_cb, NULL); 1038 poll_threads(); 1039 1040 bdev = allocate_bdev("bdev0"); 1041 1042 rc = spdk_bdev_open_ext("bdev0", true, bdev_ut_event_cb, NULL, &desc); 1043 CU_ASSERT(rc == 0); 1044 poll_threads(); 1045 SPDK_CU_ASSERT_FATAL(desc != NULL); 1046 CU_ASSERT(bdev == spdk_bdev_desc_get_bdev(desc)); 1047 io_ch = spdk_bdev_get_io_channel(desc); 1048 CU_ASSERT(io_ch != NULL); 1049 1050 /* WRITE and WRITE ZEROES are not supported */ 1051 ut_enable_io_type(SPDK_BDEV_IO_TYPE_WRITE_ZEROES, false); 1052 ut_enable_io_type(SPDK_BDEV_IO_TYPE_WRITE, false); 1053 rc = spdk_bdev_write_zeroes_blocks(desc, io_ch, 0, 128, io_done, NULL); 1054 CU_ASSERT(rc == -ENOTSUP); 1055 ut_enable_io_type(SPDK_BDEV_IO_TYPE_WRITE_ZEROES, true); 1056 ut_enable_io_type(SPDK_BDEV_IO_TYPE_WRITE, true); 1057 1058 /* NVME_IO, NVME_IO_MD and NVME_ADMIN are not supported */ 1059 ut_enable_io_type(SPDK_BDEV_IO_TYPE_NVME_IO, false); 1060 ut_enable_io_type(SPDK_BDEV_IO_TYPE_NVME_IO_MD, false); 1061 ut_enable_io_type(SPDK_BDEV_IO_TYPE_NVME_ADMIN, false); 1062 rc = spdk_bdev_nvme_io_passthru(desc, io_ch, NULL, NULL, 0, NULL, NULL); 1063 CU_ASSERT(rc == -ENOTSUP); 1064 rc = spdk_bdev_nvme_io_passthru_md(desc, io_ch, NULL, NULL, 0, NULL, 0, NULL, NULL); 1065 CU_ASSERT(rc == -ENOTSUP); 1066 rc = spdk_bdev_nvme_admin_passthru(desc, io_ch, NULL, NULL, 0, NULL, NULL); 1067 CU_ASSERT(rc == -ENOTSUP); 1068 ut_enable_io_type(SPDK_BDEV_IO_TYPE_NVME_IO, true); 1069 ut_enable_io_type(SPDK_BDEV_IO_TYPE_NVME_IO_MD, true); 1070 ut_enable_io_type(SPDK_BDEV_IO_TYPE_NVME_ADMIN, true); 1071 1072 spdk_put_io_channel(io_ch); 1073 spdk_bdev_close(desc); 1074 free_bdev(bdev); 1075 spdk_bdev_finish(bdev_fini_cb, NULL); 1076 poll_threads(); 1077 } 1078 1079 static void 1080 bdev_io_wait_test(void) 1081 { 1082 struct spdk_bdev *bdev; 1083 struct spdk_bdev_desc *desc = NULL; 1084 struct spdk_io_channel *io_ch; 1085 struct spdk_bdev_opts bdev_opts = {}; 1086 struct bdev_ut_io_wait_entry io_wait_entry; 1087 struct bdev_ut_io_wait_entry io_wait_entry2; 1088 int rc; 1089 1090 spdk_bdev_get_opts(&bdev_opts, sizeof(bdev_opts)); 1091 bdev_opts.bdev_io_pool_size = 4; 1092 bdev_opts.bdev_io_cache_size = 2; 1093 1094 rc = spdk_bdev_set_opts(&bdev_opts); 1095 CU_ASSERT(rc == 0); 1096 spdk_bdev_initialize(bdev_init_cb, NULL); 1097 poll_threads(); 1098 1099 bdev = allocate_bdev("bdev0"); 1100 1101 rc = spdk_bdev_open_ext("bdev0", true, bdev_ut_event_cb, NULL, &desc); 1102 CU_ASSERT(rc == 0); 1103 poll_threads(); 1104 SPDK_CU_ASSERT_FATAL(desc != NULL); 1105 CU_ASSERT(bdev == spdk_bdev_desc_get_bdev(desc)); 1106 io_ch = spdk_bdev_get_io_channel(desc); 1107 CU_ASSERT(io_ch != NULL); 1108 1109 rc = spdk_bdev_read_blocks(desc, io_ch, NULL, 0, 1, io_done, NULL); 1110 CU_ASSERT(rc == 0); 1111 rc = spdk_bdev_read_blocks(desc, io_ch, NULL, 0, 1, io_done, NULL); 1112 CU_ASSERT(rc == 0); 1113 rc = spdk_bdev_read_blocks(desc, io_ch, NULL, 0, 1, io_done, NULL); 1114 CU_ASSERT(rc == 0); 1115 rc = spdk_bdev_read_blocks(desc, io_ch, NULL, 0, 1, io_done, NULL); 1116 CU_ASSERT(rc == 0); 1117 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 4); 1118 1119 rc = spdk_bdev_read_blocks(desc, io_ch, NULL, 0, 1, io_done, NULL); 1120 CU_ASSERT(rc == -ENOMEM); 1121 1122 io_wait_entry.entry.bdev = bdev; 1123 io_wait_entry.entry.cb_fn = io_wait_cb; 1124 io_wait_entry.entry.cb_arg = &io_wait_entry; 1125 io_wait_entry.io_ch = io_ch; 1126 io_wait_entry.desc = desc; 1127 io_wait_entry.submitted = false; 1128 /* Cannot use the same io_wait_entry for two different calls. */ 1129 memcpy(&io_wait_entry2, &io_wait_entry, sizeof(io_wait_entry)); 1130 io_wait_entry2.entry.cb_arg = &io_wait_entry2; 1131 1132 /* Queue two I/O waits. */ 1133 rc = spdk_bdev_queue_io_wait(bdev, io_ch, &io_wait_entry.entry); 1134 CU_ASSERT(rc == 0); 1135 CU_ASSERT(io_wait_entry.submitted == false); 1136 rc = spdk_bdev_queue_io_wait(bdev, io_ch, &io_wait_entry2.entry); 1137 CU_ASSERT(rc == 0); 1138 CU_ASSERT(io_wait_entry2.submitted == false); 1139 1140 stub_complete_io(1); 1141 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 4); 1142 CU_ASSERT(io_wait_entry.submitted == true); 1143 CU_ASSERT(io_wait_entry2.submitted == false); 1144 1145 stub_complete_io(1); 1146 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 4); 1147 CU_ASSERT(io_wait_entry2.submitted == true); 1148 1149 stub_complete_io(4); 1150 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 1151 1152 spdk_put_io_channel(io_ch); 1153 spdk_bdev_close(desc); 1154 free_bdev(bdev); 1155 spdk_bdev_finish(bdev_fini_cb, NULL); 1156 poll_threads(); 1157 } 1158 1159 static void 1160 bdev_io_spans_split_test(void) 1161 { 1162 struct spdk_bdev bdev; 1163 struct spdk_bdev_io bdev_io; 1164 struct iovec iov[BDEV_IO_NUM_CHILD_IOV]; 1165 1166 memset(&bdev, 0, sizeof(bdev)); 1167 bdev_io.u.bdev.iovs = iov; 1168 1169 bdev_io.type = SPDK_BDEV_IO_TYPE_READ; 1170 bdev.optimal_io_boundary = 0; 1171 bdev.max_segment_size = 0; 1172 bdev.max_num_segments = 0; 1173 bdev_io.bdev = &bdev; 1174 1175 /* bdev has no optimal_io_boundary and max_size set - so this should return false. */ 1176 CU_ASSERT(bdev_io_should_split(&bdev_io) == false); 1177 1178 bdev.split_on_optimal_io_boundary = true; 1179 bdev.optimal_io_boundary = 32; 1180 bdev_io.type = SPDK_BDEV_IO_TYPE_RESET; 1181 1182 /* RESETs are not based on LBAs - so this should return false. */ 1183 CU_ASSERT(bdev_io_should_split(&bdev_io) == false); 1184 1185 bdev_io.type = SPDK_BDEV_IO_TYPE_READ; 1186 bdev_io.u.bdev.offset_blocks = 0; 1187 bdev_io.u.bdev.num_blocks = 32; 1188 1189 /* This I/O run right up to, but does not cross, the boundary - so this should return false. */ 1190 CU_ASSERT(bdev_io_should_split(&bdev_io) == false); 1191 1192 bdev_io.u.bdev.num_blocks = 33; 1193 1194 /* This I/O spans a boundary. */ 1195 CU_ASSERT(bdev_io_should_split(&bdev_io) == true); 1196 1197 bdev_io.u.bdev.num_blocks = 32; 1198 bdev.max_segment_size = 512 * 32; 1199 bdev.max_num_segments = 1; 1200 bdev_io.u.bdev.iovcnt = 1; 1201 iov[0].iov_len = 512; 1202 1203 /* Does not cross and exceed max_size or max_segs */ 1204 CU_ASSERT(bdev_io_should_split(&bdev_io) == false); 1205 1206 bdev.split_on_optimal_io_boundary = false; 1207 bdev.max_segment_size = 512; 1208 bdev.max_num_segments = 1; 1209 bdev_io.u.bdev.iovcnt = 2; 1210 1211 /* Exceed max_segs */ 1212 CU_ASSERT(bdev_io_should_split(&bdev_io) == true); 1213 1214 bdev.max_num_segments = 2; 1215 iov[0].iov_len = 513; 1216 iov[1].iov_len = 512; 1217 1218 /* Exceed max_sizes */ 1219 CU_ASSERT(bdev_io_should_split(&bdev_io) == true); 1220 } 1221 1222 static void 1223 bdev_io_boundary_split_test(void) 1224 { 1225 struct spdk_bdev *bdev; 1226 struct spdk_bdev_desc *desc = NULL; 1227 struct spdk_io_channel *io_ch; 1228 struct spdk_bdev_opts bdev_opts = {}; 1229 struct iovec iov[BDEV_IO_NUM_CHILD_IOV * 2]; 1230 struct ut_expected_io *expected_io; 1231 void *md_buf = (void *)0xFF000000; 1232 uint64_t i; 1233 int rc; 1234 1235 spdk_bdev_get_opts(&bdev_opts, sizeof(bdev_opts)); 1236 bdev_opts.bdev_io_pool_size = 512; 1237 bdev_opts.bdev_io_cache_size = 64; 1238 1239 rc = spdk_bdev_set_opts(&bdev_opts); 1240 CU_ASSERT(rc == 0); 1241 spdk_bdev_initialize(bdev_init_cb, NULL); 1242 1243 bdev = allocate_bdev("bdev0"); 1244 1245 rc = spdk_bdev_open_ext("bdev0", true, bdev_ut_event_cb, NULL, &desc); 1246 CU_ASSERT(rc == 0); 1247 SPDK_CU_ASSERT_FATAL(desc != NULL); 1248 CU_ASSERT(bdev == spdk_bdev_desc_get_bdev(desc)); 1249 io_ch = spdk_bdev_get_io_channel(desc); 1250 CU_ASSERT(io_ch != NULL); 1251 1252 bdev->optimal_io_boundary = 16; 1253 bdev->split_on_optimal_io_boundary = false; 1254 1255 g_io_done = false; 1256 1257 /* First test that the I/O does not get split if split_on_optimal_io_boundary == false. */ 1258 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 14, 8, 1); 1259 ut_expected_io_set_iov(expected_io, 0, (void *)0xF000, 8 * 512); 1260 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1261 1262 rc = spdk_bdev_read_blocks(desc, io_ch, (void *)0xF000, 14, 8, io_done, NULL); 1263 CU_ASSERT(rc == 0); 1264 CU_ASSERT(g_io_done == false); 1265 1266 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1267 stub_complete_io(1); 1268 CU_ASSERT(g_io_done == true); 1269 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 1270 1271 bdev->split_on_optimal_io_boundary = true; 1272 bdev->md_interleave = false; 1273 bdev->md_len = 8; 1274 1275 /* Now test that a single-vector command is split correctly. 1276 * Offset 14, length 8, payload 0xF000 1277 * Child - Offset 14, length 2, payload 0xF000 1278 * Child - Offset 16, length 6, payload 0xF000 + 2 * 512 1279 * 1280 * Set up the expected values before calling spdk_bdev_read_blocks 1281 */ 1282 g_io_done = false; 1283 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 14, 2, 1); 1284 expected_io->md_buf = md_buf; 1285 ut_expected_io_set_iov(expected_io, 0, (void *)0xF000, 2 * 512); 1286 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1287 1288 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 16, 6, 1); 1289 expected_io->md_buf = md_buf + 2 * 8; 1290 ut_expected_io_set_iov(expected_io, 0, (void *)(0xF000 + 2 * 512), 6 * 512); 1291 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1292 1293 /* spdk_bdev_read_blocks will submit the first child immediately. */ 1294 rc = spdk_bdev_read_blocks_with_md(desc, io_ch, (void *)0xF000, md_buf, 1295 14, 8, io_done, NULL); 1296 CU_ASSERT(rc == 0); 1297 CU_ASSERT(g_io_done == false); 1298 1299 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 2); 1300 stub_complete_io(2); 1301 CU_ASSERT(g_io_done == true); 1302 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 1303 1304 /* Now set up a more complex, multi-vector command that needs to be split, 1305 * including splitting iovecs. 1306 */ 1307 iov[0].iov_base = (void *)0x10000; 1308 iov[0].iov_len = 512; 1309 iov[1].iov_base = (void *)0x20000; 1310 iov[1].iov_len = 20 * 512; 1311 iov[2].iov_base = (void *)0x30000; 1312 iov[2].iov_len = 11 * 512; 1313 1314 g_io_done = false; 1315 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 14, 2, 2); 1316 expected_io->md_buf = md_buf; 1317 ut_expected_io_set_iov(expected_io, 0, (void *)0x10000, 512); 1318 ut_expected_io_set_iov(expected_io, 1, (void *)0x20000, 512); 1319 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1320 1321 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 16, 16, 1); 1322 expected_io->md_buf = md_buf + 2 * 8; 1323 ut_expected_io_set_iov(expected_io, 0, (void *)(0x20000 + 512), 16 * 512); 1324 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1325 1326 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 32, 14, 2); 1327 expected_io->md_buf = md_buf + 18 * 8; 1328 ut_expected_io_set_iov(expected_io, 0, (void *)(0x20000 + 17 * 512), 3 * 512); 1329 ut_expected_io_set_iov(expected_io, 1, (void *)0x30000, 11 * 512); 1330 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1331 1332 rc = spdk_bdev_writev_blocks_with_md(desc, io_ch, iov, 3, md_buf, 1333 14, 32, io_done, NULL); 1334 CU_ASSERT(rc == 0); 1335 CU_ASSERT(g_io_done == false); 1336 1337 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 3); 1338 stub_complete_io(3); 1339 CU_ASSERT(g_io_done == true); 1340 1341 /* Test multi vector command that needs to be split by strip and then needs to be 1342 * split further due to the capacity of child iovs. 1343 */ 1344 for (i = 0; i < BDEV_IO_NUM_CHILD_IOV * 2; i++) { 1345 iov[i].iov_base = (void *)((i + 1) * 0x10000); 1346 iov[i].iov_len = 512; 1347 } 1348 1349 bdev->optimal_io_boundary = BDEV_IO_NUM_CHILD_IOV; 1350 g_io_done = false; 1351 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 0, BDEV_IO_NUM_CHILD_IOV, 1352 BDEV_IO_NUM_CHILD_IOV); 1353 expected_io->md_buf = md_buf; 1354 for (i = 0; i < BDEV_IO_NUM_CHILD_IOV; i++) { 1355 ut_expected_io_set_iov(expected_io, i, (void *)((i + 1) * 0x10000), 512); 1356 } 1357 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1358 1359 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, BDEV_IO_NUM_CHILD_IOV, 1360 BDEV_IO_NUM_CHILD_IOV, BDEV_IO_NUM_CHILD_IOV); 1361 expected_io->md_buf = md_buf + BDEV_IO_NUM_CHILD_IOV * 8; 1362 for (i = 0; i < BDEV_IO_NUM_CHILD_IOV; i++) { 1363 ut_expected_io_set_iov(expected_io, i, 1364 (void *)((i + 1 + BDEV_IO_NUM_CHILD_IOV) * 0x10000), 512); 1365 } 1366 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1367 1368 rc = spdk_bdev_readv_blocks_with_md(desc, io_ch, iov, BDEV_IO_NUM_CHILD_IOV * 2, md_buf, 1369 0, BDEV_IO_NUM_CHILD_IOV * 2, io_done, NULL); 1370 CU_ASSERT(rc == 0); 1371 CU_ASSERT(g_io_done == false); 1372 1373 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1374 stub_complete_io(1); 1375 CU_ASSERT(g_io_done == false); 1376 1377 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1378 stub_complete_io(1); 1379 CU_ASSERT(g_io_done == true); 1380 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 1381 1382 /* Test multi vector command that needs to be split by strip and then needs to be 1383 * split further due to the capacity of child iovs. In this case, the length of 1384 * the rest of iovec array with an I/O boundary is the multiple of block size. 1385 */ 1386 1387 /* Fill iovec array for exactly one boundary. The iovec cnt for this boundary 1388 * is BDEV_IO_NUM_CHILD_IOV + 1, which exceeds the capacity of child iovs. 1389 */ 1390 for (i = 0; i < BDEV_IO_NUM_CHILD_IOV - 2; i++) { 1391 iov[i].iov_base = (void *)((i + 1) * 0x10000); 1392 iov[i].iov_len = 512; 1393 } 1394 for (i = BDEV_IO_NUM_CHILD_IOV - 2; i < BDEV_IO_NUM_CHILD_IOV; i++) { 1395 iov[i].iov_base = (void *)((i + 1) * 0x10000); 1396 iov[i].iov_len = 256; 1397 } 1398 iov[BDEV_IO_NUM_CHILD_IOV].iov_base = (void *)((BDEV_IO_NUM_CHILD_IOV + 1) * 0x10000); 1399 iov[BDEV_IO_NUM_CHILD_IOV].iov_len = 512; 1400 1401 /* Add an extra iovec to trigger split */ 1402 iov[BDEV_IO_NUM_CHILD_IOV + 1].iov_base = (void *)((BDEV_IO_NUM_CHILD_IOV + 2) * 0x10000); 1403 iov[BDEV_IO_NUM_CHILD_IOV + 1].iov_len = 512; 1404 1405 bdev->optimal_io_boundary = BDEV_IO_NUM_CHILD_IOV; 1406 g_io_done = false; 1407 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 0, 1408 BDEV_IO_NUM_CHILD_IOV - 1, BDEV_IO_NUM_CHILD_IOV); 1409 expected_io->md_buf = md_buf; 1410 for (i = 0; i < BDEV_IO_NUM_CHILD_IOV - 2; i++) { 1411 ut_expected_io_set_iov(expected_io, i, 1412 (void *)((i + 1) * 0x10000), 512); 1413 } 1414 for (i = BDEV_IO_NUM_CHILD_IOV - 2; i < BDEV_IO_NUM_CHILD_IOV; i++) { 1415 ut_expected_io_set_iov(expected_io, i, 1416 (void *)((i + 1) * 0x10000), 256); 1417 } 1418 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1419 1420 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, BDEV_IO_NUM_CHILD_IOV - 1, 1421 1, 1); 1422 expected_io->md_buf = md_buf + (BDEV_IO_NUM_CHILD_IOV - 1) * 8; 1423 ut_expected_io_set_iov(expected_io, 0, 1424 (void *)((BDEV_IO_NUM_CHILD_IOV + 1) * 0x10000), 512); 1425 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1426 1427 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, BDEV_IO_NUM_CHILD_IOV, 1428 1, 1); 1429 expected_io->md_buf = md_buf + BDEV_IO_NUM_CHILD_IOV * 8; 1430 ut_expected_io_set_iov(expected_io, 0, 1431 (void *)((BDEV_IO_NUM_CHILD_IOV + 2) * 0x10000), 512); 1432 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1433 1434 rc = spdk_bdev_readv_blocks_with_md(desc, io_ch, iov, BDEV_IO_NUM_CHILD_IOV + 2, md_buf, 1435 0, BDEV_IO_NUM_CHILD_IOV + 1, io_done, NULL); 1436 CU_ASSERT(rc == 0); 1437 CU_ASSERT(g_io_done == false); 1438 1439 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1440 stub_complete_io(1); 1441 CU_ASSERT(g_io_done == false); 1442 1443 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 2); 1444 stub_complete_io(2); 1445 CU_ASSERT(g_io_done == true); 1446 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 1447 1448 /* Test multi vector command that needs to be split by strip and then needs to be 1449 * split further due to the capacity of child iovs, the child request offset should 1450 * be rewind to last aligned offset and go success without error. 1451 */ 1452 for (i = 0; i < BDEV_IO_NUM_CHILD_IOV - 1; i++) { 1453 iov[i].iov_base = (void *)((i + 1) * 0x10000); 1454 iov[i].iov_len = 512; 1455 } 1456 iov[BDEV_IO_NUM_CHILD_IOV - 1].iov_base = (void *)(BDEV_IO_NUM_CHILD_IOV * 0x10000); 1457 iov[BDEV_IO_NUM_CHILD_IOV - 1].iov_len = 256; 1458 1459 iov[BDEV_IO_NUM_CHILD_IOV].iov_base = (void *)((BDEV_IO_NUM_CHILD_IOV + 1) * 0x10000); 1460 iov[BDEV_IO_NUM_CHILD_IOV].iov_len = 256; 1461 1462 iov[BDEV_IO_NUM_CHILD_IOV + 1].iov_base = (void *)((BDEV_IO_NUM_CHILD_IOV + 2) * 0x10000); 1463 iov[BDEV_IO_NUM_CHILD_IOV + 1].iov_len = 512; 1464 1465 bdev->optimal_io_boundary = BDEV_IO_NUM_CHILD_IOV; 1466 g_io_done = false; 1467 g_io_status = 0; 1468 /* The first expected io should be start from offset 0 to BDEV_IO_NUM_CHILD_IOV - 1 */ 1469 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 0, 1470 BDEV_IO_NUM_CHILD_IOV - 1, BDEV_IO_NUM_CHILD_IOV - 1); 1471 expected_io->md_buf = md_buf; 1472 for (i = 0; i < BDEV_IO_NUM_CHILD_IOV - 1; i++) { 1473 ut_expected_io_set_iov(expected_io, i, 1474 (void *)((i + 1) * 0x10000), 512); 1475 } 1476 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1477 /* The second expected io should be start from offset BDEV_IO_NUM_CHILD_IOV - 1 to BDEV_IO_NUM_CHILD_IOV */ 1478 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, BDEV_IO_NUM_CHILD_IOV - 1, 1479 1, 2); 1480 expected_io->md_buf = md_buf + (BDEV_IO_NUM_CHILD_IOV - 1) * 8; 1481 ut_expected_io_set_iov(expected_io, 0, 1482 (void *)(BDEV_IO_NUM_CHILD_IOV * 0x10000), 256); 1483 ut_expected_io_set_iov(expected_io, 1, 1484 (void *)((BDEV_IO_NUM_CHILD_IOV + 1) * 0x10000), 256); 1485 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1486 /* The third expected io should be start from offset BDEV_IO_NUM_CHILD_IOV to BDEV_IO_NUM_CHILD_IOV + 1 */ 1487 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, BDEV_IO_NUM_CHILD_IOV, 1488 1, 1); 1489 expected_io->md_buf = md_buf + BDEV_IO_NUM_CHILD_IOV * 8; 1490 ut_expected_io_set_iov(expected_io, 0, 1491 (void *)((BDEV_IO_NUM_CHILD_IOV + 2) * 0x10000), 512); 1492 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1493 1494 rc = spdk_bdev_readv_blocks_with_md(desc, io_ch, iov, BDEV_IO_NUM_CHILD_IOV * 2, md_buf, 1495 0, BDEV_IO_NUM_CHILD_IOV + 1, io_done, NULL); 1496 CU_ASSERT(rc == 0); 1497 CU_ASSERT(g_io_done == false); 1498 1499 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1500 stub_complete_io(1); 1501 CU_ASSERT(g_io_done == false); 1502 1503 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 2); 1504 stub_complete_io(2); 1505 CU_ASSERT(g_io_done == true); 1506 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 1507 1508 /* Test multi vector command that needs to be split due to the IO boundary and 1509 * the capacity of child iovs. Especially test the case when the command is 1510 * split due to the capacity of child iovs, the tail address is not aligned with 1511 * block size and is rewinded to the aligned address. 1512 * 1513 * The iovecs used in read request is complex but is based on the data 1514 * collected in the real issue. We change the base addresses but keep the lengths 1515 * not to loose the credibility of the test. 1516 */ 1517 bdev->optimal_io_boundary = 128; 1518 g_io_done = false; 1519 g_io_status = 0; 1520 1521 for (i = 0; i < 31; i++) { 1522 iov[i].iov_base = (void *)(0xFEED0000000 + (i << 20)); 1523 iov[i].iov_len = 1024; 1524 } 1525 iov[31].iov_base = (void *)0xFEED1F00000; 1526 iov[31].iov_len = 32768; 1527 iov[32].iov_base = (void *)0xFEED2000000; 1528 iov[32].iov_len = 160; 1529 iov[33].iov_base = (void *)0xFEED2100000; 1530 iov[33].iov_len = 4096; 1531 iov[34].iov_base = (void *)0xFEED2200000; 1532 iov[34].iov_len = 4096; 1533 iov[35].iov_base = (void *)0xFEED2300000; 1534 iov[35].iov_len = 4096; 1535 iov[36].iov_base = (void *)0xFEED2400000; 1536 iov[36].iov_len = 4096; 1537 iov[37].iov_base = (void *)0xFEED2500000; 1538 iov[37].iov_len = 4096; 1539 iov[38].iov_base = (void *)0xFEED2600000; 1540 iov[38].iov_len = 4096; 1541 iov[39].iov_base = (void *)0xFEED2700000; 1542 iov[39].iov_len = 4096; 1543 iov[40].iov_base = (void *)0xFEED2800000; 1544 iov[40].iov_len = 4096; 1545 iov[41].iov_base = (void *)0xFEED2900000; 1546 iov[41].iov_len = 4096; 1547 iov[42].iov_base = (void *)0xFEED2A00000; 1548 iov[42].iov_len = 4096; 1549 iov[43].iov_base = (void *)0xFEED2B00000; 1550 iov[43].iov_len = 12288; 1551 iov[44].iov_base = (void *)0xFEED2C00000; 1552 iov[44].iov_len = 8192; 1553 iov[45].iov_base = (void *)0xFEED2F00000; 1554 iov[45].iov_len = 4096; 1555 iov[46].iov_base = (void *)0xFEED3000000; 1556 iov[46].iov_len = 4096; 1557 iov[47].iov_base = (void *)0xFEED3100000; 1558 iov[47].iov_len = 4096; 1559 iov[48].iov_base = (void *)0xFEED3200000; 1560 iov[48].iov_len = 24576; 1561 iov[49].iov_base = (void *)0xFEED3300000; 1562 iov[49].iov_len = 16384; 1563 iov[50].iov_base = (void *)0xFEED3400000; 1564 iov[50].iov_len = 12288; 1565 iov[51].iov_base = (void *)0xFEED3500000; 1566 iov[51].iov_len = 4096; 1567 iov[52].iov_base = (void *)0xFEED3600000; 1568 iov[52].iov_len = 4096; 1569 iov[53].iov_base = (void *)0xFEED3700000; 1570 iov[53].iov_len = 4096; 1571 iov[54].iov_base = (void *)0xFEED3800000; 1572 iov[54].iov_len = 28672; 1573 iov[55].iov_base = (void *)0xFEED3900000; 1574 iov[55].iov_len = 20480; 1575 iov[56].iov_base = (void *)0xFEED3A00000; 1576 iov[56].iov_len = 4096; 1577 iov[57].iov_base = (void *)0xFEED3B00000; 1578 iov[57].iov_len = 12288; 1579 iov[58].iov_base = (void *)0xFEED3C00000; 1580 iov[58].iov_len = 4096; 1581 iov[59].iov_base = (void *)0xFEED3D00000; 1582 iov[59].iov_len = 4096; 1583 iov[60].iov_base = (void *)0xFEED3E00000; 1584 iov[60].iov_len = 352; 1585 1586 /* The 1st child IO must be from iov[0] to iov[31] split by the capacity 1587 * of child iovs, 1588 */ 1589 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 0, 126, 32); 1590 expected_io->md_buf = md_buf; 1591 for (i = 0; i < 32; i++) { 1592 ut_expected_io_set_iov(expected_io, i, iov[i].iov_base, iov[i].iov_len); 1593 } 1594 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1595 1596 /* The 2nd child IO must be from iov[32] to the first 864 bytes of iov[33] 1597 * split by the IO boundary requirement. 1598 */ 1599 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 126, 2, 2); 1600 expected_io->md_buf = md_buf + 126 * 8; 1601 ut_expected_io_set_iov(expected_io, 0, iov[32].iov_base, iov[32].iov_len); 1602 ut_expected_io_set_iov(expected_io, 1, iov[33].iov_base, 864); 1603 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1604 1605 /* The 3rd child IO must be from the remaining 3232 bytes of iov[33] to 1606 * the first 864 bytes of iov[46] split by the IO boundary requirement. 1607 */ 1608 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 128, 128, 14); 1609 expected_io->md_buf = md_buf + 128 * 8; 1610 ut_expected_io_set_iov(expected_io, 0, (void *)((uintptr_t)iov[33].iov_base + 864), 1611 iov[33].iov_len - 864); 1612 ut_expected_io_set_iov(expected_io, 1, iov[34].iov_base, iov[34].iov_len); 1613 ut_expected_io_set_iov(expected_io, 2, iov[35].iov_base, iov[35].iov_len); 1614 ut_expected_io_set_iov(expected_io, 3, iov[36].iov_base, iov[36].iov_len); 1615 ut_expected_io_set_iov(expected_io, 4, iov[37].iov_base, iov[37].iov_len); 1616 ut_expected_io_set_iov(expected_io, 5, iov[38].iov_base, iov[38].iov_len); 1617 ut_expected_io_set_iov(expected_io, 6, iov[39].iov_base, iov[39].iov_len); 1618 ut_expected_io_set_iov(expected_io, 7, iov[40].iov_base, iov[40].iov_len); 1619 ut_expected_io_set_iov(expected_io, 8, iov[41].iov_base, iov[41].iov_len); 1620 ut_expected_io_set_iov(expected_io, 9, iov[42].iov_base, iov[42].iov_len); 1621 ut_expected_io_set_iov(expected_io, 10, iov[43].iov_base, iov[43].iov_len); 1622 ut_expected_io_set_iov(expected_io, 11, iov[44].iov_base, iov[44].iov_len); 1623 ut_expected_io_set_iov(expected_io, 12, iov[45].iov_base, iov[45].iov_len); 1624 ut_expected_io_set_iov(expected_io, 13, iov[46].iov_base, 864); 1625 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1626 1627 /* The 4th child IO must be from the remaining 3232 bytes of iov[46] to the 1628 * first 864 bytes of iov[52] split by the IO boundary requirement. 1629 */ 1630 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 256, 128, 7); 1631 expected_io->md_buf = md_buf + 256 * 8; 1632 ut_expected_io_set_iov(expected_io, 0, (void *)((uintptr_t)iov[46].iov_base + 864), 1633 iov[46].iov_len - 864); 1634 ut_expected_io_set_iov(expected_io, 1, iov[47].iov_base, iov[47].iov_len); 1635 ut_expected_io_set_iov(expected_io, 2, iov[48].iov_base, iov[48].iov_len); 1636 ut_expected_io_set_iov(expected_io, 3, iov[49].iov_base, iov[49].iov_len); 1637 ut_expected_io_set_iov(expected_io, 4, iov[50].iov_base, iov[50].iov_len); 1638 ut_expected_io_set_iov(expected_io, 5, iov[51].iov_base, iov[51].iov_len); 1639 ut_expected_io_set_iov(expected_io, 6, iov[52].iov_base, 864); 1640 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1641 1642 /* The 5th child IO must be from the remaining 3232 bytes of iov[52] to 1643 * the first 4096 bytes of iov[57] split by the IO boundary requirement. 1644 */ 1645 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 384, 128, 6); 1646 expected_io->md_buf = md_buf + 384 * 8; 1647 ut_expected_io_set_iov(expected_io, 0, (void *)((uintptr_t)iov[52].iov_base + 864), 1648 iov[52].iov_len - 864); 1649 ut_expected_io_set_iov(expected_io, 1, iov[53].iov_base, iov[53].iov_len); 1650 ut_expected_io_set_iov(expected_io, 2, iov[54].iov_base, iov[54].iov_len); 1651 ut_expected_io_set_iov(expected_io, 3, iov[55].iov_base, iov[55].iov_len); 1652 ut_expected_io_set_iov(expected_io, 4, iov[56].iov_base, iov[56].iov_len); 1653 ut_expected_io_set_iov(expected_io, 5, iov[57].iov_base, 4960); 1654 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1655 1656 /* The 6th child IO must be from the remaining 7328 bytes of iov[57] 1657 * to the first 3936 bytes of iov[58] split by the capacity of child iovs. 1658 */ 1659 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 512, 30, 3); 1660 expected_io->md_buf = md_buf + 512 * 8; 1661 ut_expected_io_set_iov(expected_io, 0, (void *)((uintptr_t)iov[57].iov_base + 4960), 1662 iov[57].iov_len - 4960); 1663 ut_expected_io_set_iov(expected_io, 1, iov[58].iov_base, iov[58].iov_len); 1664 ut_expected_io_set_iov(expected_io, 2, iov[59].iov_base, 3936); 1665 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1666 1667 /* The 7th child IO is from the remaining 160 bytes of iov[59] and iov[60]. */ 1668 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 542, 1, 2); 1669 expected_io->md_buf = md_buf + 542 * 8; 1670 ut_expected_io_set_iov(expected_io, 0, (void *)((uintptr_t)iov[59].iov_base + 3936), 1671 iov[59].iov_len - 3936); 1672 ut_expected_io_set_iov(expected_io, 1, iov[60].iov_base, iov[60].iov_len); 1673 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1674 1675 rc = spdk_bdev_readv_blocks_with_md(desc, io_ch, iov, 61, md_buf, 1676 0, 543, io_done, NULL); 1677 CU_ASSERT(rc == 0); 1678 CU_ASSERT(g_io_done == false); 1679 1680 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1681 stub_complete_io(1); 1682 CU_ASSERT(g_io_done == false); 1683 1684 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 5); 1685 stub_complete_io(5); 1686 CU_ASSERT(g_io_done == false); 1687 1688 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1689 stub_complete_io(1); 1690 CU_ASSERT(g_io_done == true); 1691 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 1692 CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_SUCCESS); 1693 1694 /* Test a WRITE_ZEROES that would span an I/O boundary. WRITE_ZEROES should not be 1695 * split, so test that. 1696 */ 1697 bdev->optimal_io_boundary = 15; 1698 g_io_done = false; 1699 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE_ZEROES, 9, 36, 0); 1700 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1701 1702 rc = spdk_bdev_write_zeroes_blocks(desc, io_ch, 9, 36, io_done, NULL); 1703 CU_ASSERT(rc == 0); 1704 CU_ASSERT(g_io_done == false); 1705 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1706 stub_complete_io(1); 1707 CU_ASSERT(g_io_done == true); 1708 1709 /* Test an UNMAP. This should also not be split. */ 1710 bdev->optimal_io_boundary = 16; 1711 g_io_done = false; 1712 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_UNMAP, 15, 2, 0); 1713 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1714 1715 rc = spdk_bdev_unmap_blocks(desc, io_ch, 15, 2, io_done, NULL); 1716 CU_ASSERT(rc == 0); 1717 CU_ASSERT(g_io_done == false); 1718 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1719 stub_complete_io(1); 1720 CU_ASSERT(g_io_done == true); 1721 1722 /* Test a FLUSH. This should also not be split. */ 1723 bdev->optimal_io_boundary = 16; 1724 g_io_done = false; 1725 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_FLUSH, 15, 2, 0); 1726 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1727 1728 rc = spdk_bdev_flush_blocks(desc, io_ch, 15, 2, io_done, NULL); 1729 CU_ASSERT(rc == 0); 1730 CU_ASSERT(g_io_done == false); 1731 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1732 stub_complete_io(1); 1733 CU_ASSERT(g_io_done == true); 1734 1735 CU_ASSERT(TAILQ_EMPTY(&g_bdev_ut_channel->expected_io)); 1736 1737 /* Children requests return an error status */ 1738 bdev->optimal_io_boundary = 16; 1739 iov[0].iov_base = (void *)0x10000; 1740 iov[0].iov_len = 512 * 64; 1741 g_io_exp_status = SPDK_BDEV_IO_STATUS_FAILED; 1742 g_io_done = false; 1743 g_io_status = SPDK_BDEV_IO_STATUS_SUCCESS; 1744 1745 rc = spdk_bdev_readv_blocks(desc, io_ch, iov, 1, 1, 64, io_done, NULL); 1746 CU_ASSERT(rc == 0); 1747 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 5); 1748 stub_complete_io(4); 1749 CU_ASSERT(g_io_done == false); 1750 CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_SUCCESS); 1751 stub_complete_io(1); 1752 CU_ASSERT(g_io_done == true); 1753 CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_FAILED); 1754 1755 /* Test if a multi vector command terminated with failure before continuing 1756 * splitting process when one of child I/O failed. 1757 * The multi vector command is as same as the above that needs to be split by strip 1758 * and then needs to be split further due to the capacity of child iovs. 1759 */ 1760 for (i = 0; i < BDEV_IO_NUM_CHILD_IOV - 1; i++) { 1761 iov[i].iov_base = (void *)((i + 1) * 0x10000); 1762 iov[i].iov_len = 512; 1763 } 1764 iov[BDEV_IO_NUM_CHILD_IOV - 1].iov_base = (void *)(BDEV_IO_NUM_CHILD_IOV * 0x10000); 1765 iov[BDEV_IO_NUM_CHILD_IOV - 1].iov_len = 256; 1766 1767 iov[BDEV_IO_NUM_CHILD_IOV].iov_base = (void *)((BDEV_IO_NUM_CHILD_IOV + 1) * 0x10000); 1768 iov[BDEV_IO_NUM_CHILD_IOV].iov_len = 256; 1769 1770 iov[BDEV_IO_NUM_CHILD_IOV + 1].iov_base = (void *)((BDEV_IO_NUM_CHILD_IOV + 2) * 0x10000); 1771 iov[BDEV_IO_NUM_CHILD_IOV + 1].iov_len = 512; 1772 1773 bdev->optimal_io_boundary = BDEV_IO_NUM_CHILD_IOV; 1774 1775 g_io_exp_status = SPDK_BDEV_IO_STATUS_FAILED; 1776 g_io_done = false; 1777 g_io_status = SPDK_BDEV_IO_STATUS_SUCCESS; 1778 1779 rc = spdk_bdev_readv_blocks(desc, io_ch, iov, BDEV_IO_NUM_CHILD_IOV * 2, 0, 1780 BDEV_IO_NUM_CHILD_IOV + 1, io_done, NULL); 1781 CU_ASSERT(rc == 0); 1782 CU_ASSERT(g_io_done == false); 1783 1784 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1785 stub_complete_io(1); 1786 CU_ASSERT(g_io_done == true); 1787 CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_FAILED); 1788 1789 g_io_exp_status = SPDK_BDEV_IO_STATUS_SUCCESS; 1790 1791 /* for this test we will create the following conditions to hit the code path where 1792 * we are trying to send and IO following a split that has no iovs because we had to 1793 * trim them for alignment reasons. 1794 * 1795 * - 16K boundary, our IO will start at offset 0 with a length of 0x4200 1796 * - Our IOVs are 0x212 in size so that we run into the 16K boundary at child IOV 1797 * position 30 and overshoot by 0x2e. 1798 * - That means we'll send the IO and loop back to pick up the remaining bytes at 1799 * child IOV index 31. When we do, we find that we have to shorten index 31 by 0x2e 1800 * which eliniates that vector so we just send the first split IO with 30 vectors 1801 * and let the completion pick up the last 2 vectors. 1802 */ 1803 bdev->optimal_io_boundary = 32; 1804 bdev->split_on_optimal_io_boundary = true; 1805 g_io_done = false; 1806 1807 /* Init all parent IOVs to 0x212 */ 1808 for (i = 0; i < BDEV_IO_NUM_CHILD_IOV + 2; i++) { 1809 iov[i].iov_base = (void *)((i + 1) * 0x10000); 1810 iov[i].iov_len = 0x212; 1811 } 1812 1813 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 0, BDEV_IO_NUM_CHILD_IOV, 1814 BDEV_IO_NUM_CHILD_IOV - 1); 1815 /* expect 0-29 to be 1:1 with the parent iov */ 1816 for (i = 0; i < BDEV_IO_NUM_CHILD_IOV - 2; i++) { 1817 ut_expected_io_set_iov(expected_io, i, iov[i].iov_base, iov[i].iov_len); 1818 } 1819 1820 /* expect index 30 to be shortened to 0x1e4 (0x212 - 0x1e) because of the alignment 1821 * where 0x1e is the amount we overshot the 16K boundary 1822 */ 1823 ut_expected_io_set_iov(expected_io, BDEV_IO_NUM_CHILD_IOV - 2, 1824 (void *)(iov[BDEV_IO_NUM_CHILD_IOV - 2].iov_base), 0x1e4); 1825 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1826 1827 /* 2nd child IO will have 2 remaining vectors, one to pick up from the one that was 1828 * shortened that take it to the next boundary and then a final one to get us to 1829 * 0x4200 bytes for the IO. 1830 */ 1831 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, BDEV_IO_NUM_CHILD_IOV, 1832 BDEV_IO_NUM_CHILD_IOV, 2); 1833 /* position 30 picked up the remaining bytes to the next boundary */ 1834 ut_expected_io_set_iov(expected_io, 0, 1835 (void *)(iov[BDEV_IO_NUM_CHILD_IOV - 2].iov_base + 0x1e4), 0x2e); 1836 1837 /* position 31 picked the the rest of the transfer to get us to 0x4200 */ 1838 ut_expected_io_set_iov(expected_io, 1, 1839 (void *)(iov[BDEV_IO_NUM_CHILD_IOV - 1].iov_base), 0x1d2); 1840 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1841 1842 rc = spdk_bdev_readv_blocks(desc, io_ch, iov, BDEV_IO_NUM_CHILD_IOV + 1, 0, 1843 BDEV_IO_NUM_CHILD_IOV + 1, io_done, NULL); 1844 CU_ASSERT(rc == 0); 1845 CU_ASSERT(g_io_done == false); 1846 1847 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1848 stub_complete_io(1); 1849 CU_ASSERT(g_io_done == false); 1850 1851 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1852 stub_complete_io(1); 1853 CU_ASSERT(g_io_done == true); 1854 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 1855 1856 spdk_put_io_channel(io_ch); 1857 spdk_bdev_close(desc); 1858 free_bdev(bdev); 1859 spdk_bdev_finish(bdev_fini_cb, NULL); 1860 poll_threads(); 1861 } 1862 1863 static void 1864 bdev_io_max_size_and_segment_split_test(void) 1865 { 1866 struct spdk_bdev *bdev; 1867 struct spdk_bdev_desc *desc = NULL; 1868 struct spdk_io_channel *io_ch; 1869 struct spdk_bdev_opts bdev_opts = {}; 1870 struct iovec iov[BDEV_IO_NUM_CHILD_IOV * 2]; 1871 struct ut_expected_io *expected_io; 1872 uint64_t i; 1873 int rc; 1874 1875 spdk_bdev_get_opts(&bdev_opts, sizeof(bdev_opts)); 1876 bdev_opts.bdev_io_pool_size = 512; 1877 bdev_opts.bdev_io_cache_size = 64; 1878 1879 bdev_opts.opts_size = sizeof(bdev_opts); 1880 rc = spdk_bdev_set_opts(&bdev_opts); 1881 CU_ASSERT(rc == 0); 1882 spdk_bdev_initialize(bdev_init_cb, NULL); 1883 1884 bdev = allocate_bdev("bdev0"); 1885 1886 rc = spdk_bdev_open_ext(bdev->name, true, bdev_ut_event_cb, NULL, &desc); 1887 CU_ASSERT(rc == 0); 1888 SPDK_CU_ASSERT_FATAL(desc != NULL); 1889 io_ch = spdk_bdev_get_io_channel(desc); 1890 CU_ASSERT(io_ch != NULL); 1891 1892 bdev->split_on_optimal_io_boundary = false; 1893 bdev->optimal_io_boundary = 0; 1894 1895 /* Case 0 max_num_segments == 0. 1896 * but segment size 2 * 512 > 512 1897 */ 1898 bdev->max_segment_size = 512; 1899 bdev->max_num_segments = 0; 1900 g_io_done = false; 1901 1902 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 14, 2, 2); 1903 ut_expected_io_set_iov(expected_io, 0, (void *)0xF000, 512); 1904 ut_expected_io_set_iov(expected_io, 1, (void *)(0xF000 + 512), 512); 1905 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1906 1907 rc = spdk_bdev_read_blocks(desc, io_ch, (void *)0xF000, 14, 2, io_done, NULL); 1908 CU_ASSERT(rc == 0); 1909 CU_ASSERT(g_io_done == false); 1910 1911 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1912 stub_complete_io(1); 1913 CU_ASSERT(g_io_done == true); 1914 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 1915 1916 /* Case 1 max_segment_size == 0 1917 * but iov num 2 > 1. 1918 */ 1919 bdev->max_segment_size = 0; 1920 bdev->max_num_segments = 1; 1921 g_io_done = false; 1922 1923 iov[0].iov_base = (void *)0x10000; 1924 iov[0].iov_len = 512; 1925 iov[1].iov_base = (void *)0x20000; 1926 iov[1].iov_len = 8 * 512; 1927 1928 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 14, 1, 1); 1929 ut_expected_io_set_iov(expected_io, 0, iov[0].iov_base, iov[0].iov_len); 1930 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1931 1932 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 15, 8, 1); 1933 ut_expected_io_set_iov(expected_io, 0, iov[1].iov_base, iov[1].iov_len); 1934 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1935 1936 rc = spdk_bdev_readv_blocks(desc, io_ch, iov, 2, 14, 9, io_done, NULL); 1937 CU_ASSERT(rc == 0); 1938 CU_ASSERT(g_io_done == false); 1939 1940 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 2); 1941 stub_complete_io(2); 1942 CU_ASSERT(g_io_done == true); 1943 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 1944 1945 /* Test that a non-vector command is split correctly. 1946 * Set up the expected values before calling spdk_bdev_read_blocks 1947 */ 1948 bdev->max_segment_size = 512; 1949 bdev->max_num_segments = 1; 1950 g_io_done = false; 1951 1952 /* Child IO 0 */ 1953 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 14, 1, 1); 1954 ut_expected_io_set_iov(expected_io, 0, (void *)0xF000, 512); 1955 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1956 1957 /* Child IO 1 */ 1958 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 15, 1, 1); 1959 ut_expected_io_set_iov(expected_io, 0, (void *)(0xF000 + 1 * 512), 512); 1960 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1961 1962 /* spdk_bdev_read_blocks will submit the first child immediately. */ 1963 rc = spdk_bdev_read_blocks(desc, io_ch, (void *)0xF000, 14, 2, io_done, NULL); 1964 CU_ASSERT(rc == 0); 1965 CU_ASSERT(g_io_done == false); 1966 1967 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 2); 1968 stub_complete_io(2); 1969 CU_ASSERT(g_io_done == true); 1970 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 1971 1972 /* Now set up a more complex, multi-vector command that needs to be split, 1973 * including splitting iovecs. 1974 */ 1975 bdev->max_segment_size = 2 * 512; 1976 bdev->max_num_segments = 1; 1977 g_io_done = false; 1978 1979 iov[0].iov_base = (void *)0x10000; 1980 iov[0].iov_len = 2 * 512; 1981 iov[1].iov_base = (void *)0x20000; 1982 iov[1].iov_len = 4 * 512; 1983 iov[2].iov_base = (void *)0x30000; 1984 iov[2].iov_len = 6 * 512; 1985 1986 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 14, 2, 1); 1987 ut_expected_io_set_iov(expected_io, 0, iov[0].iov_base, 512 * 2); 1988 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1989 1990 /* Split iov[1].size to 2 iov entries then split the segments */ 1991 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 16, 2, 1); 1992 ut_expected_io_set_iov(expected_io, 0, iov[1].iov_base, 512 * 2); 1993 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1994 1995 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 18, 2, 1); 1996 ut_expected_io_set_iov(expected_io, 0, iov[1].iov_base + 512 * 2, 512 * 2); 1997 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1998 1999 /* Split iov[2].size to 3 iov entries then split the segments */ 2000 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 20, 2, 1); 2001 ut_expected_io_set_iov(expected_io, 0, iov[2].iov_base, 512 * 2); 2002 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2003 2004 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 22, 2, 1); 2005 ut_expected_io_set_iov(expected_io, 0, iov[2].iov_base + 512 * 2, 512 * 2); 2006 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2007 2008 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 24, 2, 1); 2009 ut_expected_io_set_iov(expected_io, 0, iov[2].iov_base + 512 * 4, 512 * 2); 2010 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2011 2012 rc = spdk_bdev_writev_blocks(desc, io_ch, iov, 3, 14, 12, io_done, NULL); 2013 CU_ASSERT(rc == 0); 2014 CU_ASSERT(g_io_done == false); 2015 2016 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 6); 2017 stub_complete_io(6); 2018 CU_ASSERT(g_io_done == true); 2019 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 2020 2021 /* Test multi vector command that needs to be split by strip and then needs to be 2022 * split further due to the capacity of parent IO child iovs. 2023 */ 2024 bdev->max_segment_size = 512; 2025 bdev->max_num_segments = 1; 2026 g_io_done = false; 2027 2028 for (i = 0; i < BDEV_IO_NUM_CHILD_IOV; i++) { 2029 iov[i].iov_base = (void *)((i + 1) * 0x10000); 2030 iov[i].iov_len = 512 * 2; 2031 } 2032 2033 /* Each input iov.size is split into 2 iovs, 2034 * half of the input iov can fill all child iov entries of a single IO. 2035 */ 2036 for (i = 0; i < BDEV_IO_NUM_CHILD_IOV / 2; i++) { 2037 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 2 * i, 1, 1); 2038 ut_expected_io_set_iov(expected_io, 0, iov[i].iov_base, 512); 2039 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2040 2041 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 2 * i + 1, 1, 1); 2042 ut_expected_io_set_iov(expected_io, 0, iov[i].iov_base + 512, 512); 2043 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2044 } 2045 2046 /* The remaining iov is split in the second round */ 2047 for (i = BDEV_IO_NUM_CHILD_IOV / 2; i < BDEV_IO_NUM_CHILD_IOV; i++) { 2048 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, i * 2, 1, 1); 2049 ut_expected_io_set_iov(expected_io, 0, iov[i].iov_base, 512); 2050 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2051 2052 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, i * 2 + 1, 1, 1); 2053 ut_expected_io_set_iov(expected_io, 0, iov[i].iov_base + 512, 512); 2054 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2055 } 2056 2057 rc = spdk_bdev_readv_blocks(desc, io_ch, iov, BDEV_IO_NUM_CHILD_IOV, 0, 2058 BDEV_IO_NUM_CHILD_IOV * 2, io_done, NULL); 2059 CU_ASSERT(rc == 0); 2060 CU_ASSERT(g_io_done == false); 2061 2062 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == BDEV_IO_NUM_CHILD_IOV); 2063 stub_complete_io(BDEV_IO_NUM_CHILD_IOV); 2064 CU_ASSERT(g_io_done == false); 2065 2066 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == BDEV_IO_NUM_CHILD_IOV); 2067 stub_complete_io(BDEV_IO_NUM_CHILD_IOV); 2068 CU_ASSERT(g_io_done == true); 2069 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 2070 2071 /* A wrong case, a child IO that is divided does 2072 * not meet the principle of multiples of block size, 2073 * and exits with error 2074 */ 2075 bdev->max_segment_size = 512; 2076 bdev->max_num_segments = 1; 2077 g_io_done = false; 2078 2079 iov[0].iov_base = (void *)0x10000; 2080 iov[0].iov_len = 512 + 256; 2081 iov[1].iov_base = (void *)0x20000; 2082 iov[1].iov_len = 256; 2083 2084 /* iov[0] is split to 512 and 256. 2085 * 256 is less than a block size, and it is found 2086 * in the next round of split that it is the first child IO smaller than 2087 * the block size, so the error exit 2088 */ 2089 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 0, 1, 1); 2090 ut_expected_io_set_iov(expected_io, 0, iov[0].iov_base, 512); 2091 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2092 2093 rc = spdk_bdev_readv_blocks(desc, io_ch, iov, 2, 0, 2, io_done, NULL); 2094 CU_ASSERT(rc == 0); 2095 CU_ASSERT(g_io_done == false); 2096 2097 /* First child IO is OK */ 2098 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 2099 stub_complete_io(1); 2100 CU_ASSERT(g_io_done == true); 2101 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 2102 2103 /* error exit */ 2104 stub_complete_io(1); 2105 CU_ASSERT(g_io_done == true); 2106 CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_FAILED); 2107 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 2108 2109 /* Test multi vector command that needs to be split by strip and then needs to be 2110 * split further due to the capacity of child iovs. 2111 * 2112 * In this case, the last two iovs need to be split, but it will exceed the capacity 2113 * of child iovs, so it needs to wait until the first batch completed. 2114 */ 2115 bdev->max_segment_size = 512; 2116 bdev->max_num_segments = BDEV_IO_NUM_CHILD_IOV; 2117 g_io_done = false; 2118 2119 for (i = 0; i < BDEV_IO_NUM_CHILD_IOV - 2; i++) { 2120 iov[i].iov_base = (void *)((i + 1) * 0x10000); 2121 iov[i].iov_len = 512; 2122 } 2123 for (i = BDEV_IO_NUM_CHILD_IOV - 2; i < BDEV_IO_NUM_CHILD_IOV; i++) { 2124 iov[i].iov_base = (void *)((i + 1) * 0x10000); 2125 iov[i].iov_len = 512 * 2; 2126 } 2127 2128 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 0, 2129 BDEV_IO_NUM_CHILD_IOV, BDEV_IO_NUM_CHILD_IOV); 2130 /* 0 ~ (BDEV_IO_NUM_CHILD_IOV - 2) Will not be split */ 2131 for (i = 0; i < BDEV_IO_NUM_CHILD_IOV - 2; i++) { 2132 ut_expected_io_set_iov(expected_io, i, iov[i].iov_base, iov[i].iov_len); 2133 } 2134 /* (BDEV_IO_NUM_CHILD_IOV - 2) is split */ 2135 ut_expected_io_set_iov(expected_io, i, iov[i].iov_base, 512); 2136 ut_expected_io_set_iov(expected_io, i + 1, iov[i].iov_base + 512, 512); 2137 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2138 2139 /* Child iov entries exceed the max num of parent IO so split it in next round */ 2140 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, BDEV_IO_NUM_CHILD_IOV, 2, 2); 2141 ut_expected_io_set_iov(expected_io, 0, iov[i + 1].iov_base, 512); 2142 ut_expected_io_set_iov(expected_io, 1, iov[i + 1].iov_base + 512, 512); 2143 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2144 2145 rc = spdk_bdev_readv_blocks(desc, io_ch, iov, BDEV_IO_NUM_CHILD_IOV, 0, 2146 BDEV_IO_NUM_CHILD_IOV + 2, io_done, NULL); 2147 CU_ASSERT(rc == 0); 2148 CU_ASSERT(g_io_done == false); 2149 2150 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 2151 stub_complete_io(1); 2152 CU_ASSERT(g_io_done == false); 2153 2154 /* Next round */ 2155 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 2156 stub_complete_io(1); 2157 CU_ASSERT(g_io_done == true); 2158 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 2159 2160 /* This case is similar to the previous one, but the io composed of 2161 * the last few entries of child iov is not enough for a blocklen, so they 2162 * cannot be put into this IO, but wait until the next time. 2163 */ 2164 bdev->max_segment_size = 512; 2165 bdev->max_num_segments = BDEV_IO_NUM_CHILD_IOV; 2166 g_io_done = false; 2167 2168 for (i = 0; i < BDEV_IO_NUM_CHILD_IOV - 2; i++) { 2169 iov[i].iov_base = (void *)((i + 1) * 0x10000); 2170 iov[i].iov_len = 512; 2171 } 2172 2173 for (i = BDEV_IO_NUM_CHILD_IOV - 2; i < BDEV_IO_NUM_CHILD_IOV + 2; i++) { 2174 iov[i].iov_base = (void *)((i + 1) * 0x10000); 2175 iov[i].iov_len = 128; 2176 } 2177 2178 /* First child iovcnt is't BDEV_IO_NUM_CHILD_IOV but BDEV_IO_NUM_CHILD_IOV - 2. 2179 * Because the left 2 iov is not enough for a blocklen. 2180 */ 2181 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 0, 2182 BDEV_IO_NUM_CHILD_IOV - 2, BDEV_IO_NUM_CHILD_IOV - 2); 2183 for (i = 0; i < BDEV_IO_NUM_CHILD_IOV - 2; i++) { 2184 ut_expected_io_set_iov(expected_io, i, iov[i].iov_base, iov[i].iov_len); 2185 } 2186 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2187 2188 /* The second child io waits until the end of the first child io before executing. 2189 * Because the iovcnt of the two IOs exceeds the child iovcnt of the parent IO. 2190 * BDEV_IO_NUM_CHILD_IOV - 2 to BDEV_IO_NUM_CHILD_IOV + 2 2191 */ 2192 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, BDEV_IO_NUM_CHILD_IOV - 2, 2193 1, 4); 2194 ut_expected_io_set_iov(expected_io, 0, iov[i].iov_base, iov[i].iov_len); 2195 ut_expected_io_set_iov(expected_io, 1, iov[i + 1].iov_base, iov[i + 1].iov_len); 2196 ut_expected_io_set_iov(expected_io, 2, iov[i + 2].iov_base, iov[i + 2].iov_len); 2197 ut_expected_io_set_iov(expected_io, 3, iov[i + 3].iov_base, iov[i + 3].iov_len); 2198 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2199 2200 rc = spdk_bdev_readv_blocks(desc, io_ch, iov, BDEV_IO_NUM_CHILD_IOV + 2, 0, 2201 BDEV_IO_NUM_CHILD_IOV - 1, io_done, NULL); 2202 CU_ASSERT(rc == 0); 2203 CU_ASSERT(g_io_done == false); 2204 2205 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 2206 stub_complete_io(1); 2207 CU_ASSERT(g_io_done == false); 2208 2209 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 2210 stub_complete_io(1); 2211 CU_ASSERT(g_io_done == true); 2212 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 2213 2214 /* A very complicated case. Each sg entry exceeds max_segment_size and 2215 * needs to be split. At the same time, child io must be a multiple of blocklen. 2216 * At the same time, child iovcnt exceeds parent iovcnt. 2217 */ 2218 bdev->max_segment_size = 512 + 128; 2219 bdev->max_num_segments = 3; 2220 g_io_done = false; 2221 2222 for (i = 0; i < BDEV_IO_NUM_CHILD_IOV - 2; i++) { 2223 iov[i].iov_base = (void *)((i + 1) * 0x10000); 2224 iov[i].iov_len = 512 + 256; 2225 } 2226 2227 for (i = BDEV_IO_NUM_CHILD_IOV - 2; i < BDEV_IO_NUM_CHILD_IOV + 2; i++) { 2228 iov[i].iov_base = (void *)((i + 1) * 0x10000); 2229 iov[i].iov_len = 512 + 128; 2230 } 2231 2232 /* Child IOs use 9 entries per for() round and 3 * 9 = 27 child iov entries. 2233 * Consume 4 parent IO iov entries per for() round and 6 block size. 2234 * Generate 9 child IOs. 2235 */ 2236 for (i = 0; i < 3; i++) { 2237 uint32_t j = i * 4; 2238 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, i * 6, 2, 3); 2239 ut_expected_io_set_iov(expected_io, 0, iov[j].iov_base, 640); 2240 ut_expected_io_set_iov(expected_io, 1, iov[j].iov_base + 640, 128); 2241 ut_expected_io_set_iov(expected_io, 2, iov[j + 1].iov_base, 256); 2242 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2243 2244 /* Child io must be a multiple of blocklen 2245 * iov[j + 2] must be split. If the third entry is also added, 2246 * the multiple of blocklen cannot be guaranteed. But it still 2247 * occupies one iov entry of the parent child iov. 2248 */ 2249 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, i * 6 + 2, 2, 2); 2250 ut_expected_io_set_iov(expected_io, 0, iov[j + 1].iov_base + 256, 512); 2251 ut_expected_io_set_iov(expected_io, 1, iov[j + 2].iov_base, 512); 2252 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2253 2254 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, i * 6 + 4, 2, 3); 2255 ut_expected_io_set_iov(expected_io, 0, iov[j + 2].iov_base + 512, 256); 2256 ut_expected_io_set_iov(expected_io, 1, iov[j + 3].iov_base, 640); 2257 ut_expected_io_set_iov(expected_io, 2, iov[j + 3].iov_base + 640, 128); 2258 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2259 } 2260 2261 /* Child iov position at 27, the 10th child IO 2262 * iov entry index is 3 * 4 and offset is 3 * 6 2263 */ 2264 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 18, 2, 3); 2265 ut_expected_io_set_iov(expected_io, 0, iov[12].iov_base, 640); 2266 ut_expected_io_set_iov(expected_io, 1, iov[12].iov_base + 640, 128); 2267 ut_expected_io_set_iov(expected_io, 2, iov[13].iov_base, 256); 2268 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2269 2270 /* Child iov position at 30, the 11th child IO */ 2271 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 20, 2, 2); 2272 ut_expected_io_set_iov(expected_io, 0, iov[13].iov_base + 256, 512); 2273 ut_expected_io_set_iov(expected_io, 1, iov[14].iov_base, 512); 2274 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2275 2276 /* The 2nd split round and iovpos is 0, the 12th child IO */ 2277 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 22, 2, 3); 2278 ut_expected_io_set_iov(expected_io, 0, iov[14].iov_base + 512, 256); 2279 ut_expected_io_set_iov(expected_io, 1, iov[15].iov_base, 640); 2280 ut_expected_io_set_iov(expected_io, 2, iov[15].iov_base + 640, 128); 2281 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2282 2283 /* Consume 9 child IOs and 27 child iov entries. 2284 * Consume 4 parent IO iov entries per for() round and 6 block size. 2285 * Parent IO iov index start from 16 and block offset start from 24 2286 */ 2287 for (i = 0; i < 3; i++) { 2288 uint32_t j = i * 4 + 16; 2289 uint32_t offset = i * 6 + 24; 2290 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, offset, 2, 3); 2291 ut_expected_io_set_iov(expected_io, 0, iov[j].iov_base, 640); 2292 ut_expected_io_set_iov(expected_io, 1, iov[j].iov_base + 640, 128); 2293 ut_expected_io_set_iov(expected_io, 2, iov[j + 1].iov_base, 256); 2294 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2295 2296 /* Child io must be a multiple of blocklen 2297 * iov[j + 2] must be split. If the third entry is also added, 2298 * the multiple of blocklen cannot be guaranteed. But it still 2299 * occupies one iov entry of the parent child iov. 2300 */ 2301 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, offset + 2, 2, 2); 2302 ut_expected_io_set_iov(expected_io, 0, iov[j + 1].iov_base + 256, 512); 2303 ut_expected_io_set_iov(expected_io, 1, iov[j + 2].iov_base, 512); 2304 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2305 2306 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, offset + 4, 2, 3); 2307 ut_expected_io_set_iov(expected_io, 0, iov[j + 2].iov_base + 512, 256); 2308 ut_expected_io_set_iov(expected_io, 1, iov[j + 3].iov_base, 640); 2309 ut_expected_io_set_iov(expected_io, 2, iov[j + 3].iov_base + 640, 128); 2310 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2311 } 2312 2313 /* The 22th child IO, child iov position at 30 */ 2314 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 42, 1, 1); 2315 ut_expected_io_set_iov(expected_io, 0, iov[28].iov_base, 512); 2316 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2317 2318 /* The third round */ 2319 /* Here is the 23nd child IO and child iovpos is 0 */ 2320 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 43, 2, 3); 2321 ut_expected_io_set_iov(expected_io, 0, iov[28].iov_base + 512, 256); 2322 ut_expected_io_set_iov(expected_io, 1, iov[29].iov_base, 640); 2323 ut_expected_io_set_iov(expected_io, 2, iov[29].iov_base + 640, 128); 2324 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2325 2326 /* The 24th child IO */ 2327 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 45, 3, 3); 2328 ut_expected_io_set_iov(expected_io, 0, iov[30].iov_base, 640); 2329 ut_expected_io_set_iov(expected_io, 1, iov[31].iov_base, 640); 2330 ut_expected_io_set_iov(expected_io, 2, iov[32].iov_base, 256); 2331 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2332 2333 /* The 25th child IO */ 2334 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 48, 2, 2); 2335 ut_expected_io_set_iov(expected_io, 0, iov[32].iov_base + 256, 384); 2336 ut_expected_io_set_iov(expected_io, 1, iov[33].iov_base, 640); 2337 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2338 2339 rc = spdk_bdev_readv_blocks(desc, io_ch, iov, BDEV_IO_NUM_CHILD_IOV + 2, 0, 2340 50, io_done, NULL); 2341 CU_ASSERT(rc == 0); 2342 CU_ASSERT(g_io_done == false); 2343 2344 /* Parent IO supports up to 32 child iovs, so it is calculated that 2345 * a maximum of 11 IOs can be split at a time, and the 2346 * splitting will continue after the first batch is over. 2347 */ 2348 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 11); 2349 stub_complete_io(11); 2350 CU_ASSERT(g_io_done == false); 2351 2352 /* The 2nd round */ 2353 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 11); 2354 stub_complete_io(11); 2355 CU_ASSERT(g_io_done == false); 2356 2357 /* The last round */ 2358 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 3); 2359 stub_complete_io(3); 2360 CU_ASSERT(g_io_done == true); 2361 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 2362 2363 /* Test an WRITE_ZEROES. This should also not be split. */ 2364 bdev->max_segment_size = 512; 2365 bdev->max_num_segments = 1; 2366 g_io_done = false; 2367 2368 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE_ZEROES, 9, 36, 0); 2369 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2370 2371 rc = spdk_bdev_write_zeroes_blocks(desc, io_ch, 9, 36, io_done, NULL); 2372 CU_ASSERT(rc == 0); 2373 CU_ASSERT(g_io_done == false); 2374 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 2375 stub_complete_io(1); 2376 CU_ASSERT(g_io_done == true); 2377 2378 /* Test an UNMAP. This should also not be split. */ 2379 g_io_done = false; 2380 2381 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_UNMAP, 15, 4, 0); 2382 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2383 2384 rc = spdk_bdev_unmap_blocks(desc, io_ch, 15, 4, io_done, NULL); 2385 CU_ASSERT(rc == 0); 2386 CU_ASSERT(g_io_done == false); 2387 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 2388 stub_complete_io(1); 2389 CU_ASSERT(g_io_done == true); 2390 2391 /* Test a FLUSH. This should also not be split. */ 2392 g_io_done = false; 2393 2394 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_FLUSH, 15, 4, 0); 2395 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2396 2397 rc = spdk_bdev_flush_blocks(desc, io_ch, 15, 2, io_done, NULL); 2398 CU_ASSERT(rc == 0); 2399 CU_ASSERT(g_io_done == false); 2400 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 2401 stub_complete_io(1); 2402 CU_ASSERT(g_io_done == true); 2403 2404 spdk_put_io_channel(io_ch); 2405 spdk_bdev_close(desc); 2406 free_bdev(bdev); 2407 spdk_bdev_finish(bdev_fini_cb, NULL); 2408 poll_threads(); 2409 } 2410 2411 static void 2412 bdev_io_mix_split_test(void) 2413 { 2414 struct spdk_bdev *bdev; 2415 struct spdk_bdev_desc *desc = NULL; 2416 struct spdk_io_channel *io_ch; 2417 struct spdk_bdev_opts bdev_opts = {}; 2418 struct iovec iov[BDEV_IO_NUM_CHILD_IOV * 2]; 2419 struct ut_expected_io *expected_io; 2420 uint64_t i; 2421 int rc; 2422 2423 spdk_bdev_get_opts(&bdev_opts, sizeof(bdev_opts)); 2424 bdev_opts.bdev_io_pool_size = 512; 2425 bdev_opts.bdev_io_cache_size = 64; 2426 2427 rc = spdk_bdev_set_opts(&bdev_opts); 2428 CU_ASSERT(rc == 0); 2429 spdk_bdev_initialize(bdev_init_cb, NULL); 2430 2431 bdev = allocate_bdev("bdev0"); 2432 2433 rc = spdk_bdev_open_ext(bdev->name, true, bdev_ut_event_cb, NULL, &desc); 2434 CU_ASSERT(rc == 0); 2435 SPDK_CU_ASSERT_FATAL(desc != NULL); 2436 io_ch = spdk_bdev_get_io_channel(desc); 2437 CU_ASSERT(io_ch != NULL); 2438 2439 /* First case optimal_io_boundary == max_segment_size * max_num_segments */ 2440 bdev->split_on_optimal_io_boundary = true; 2441 bdev->optimal_io_boundary = 16; 2442 2443 bdev->max_segment_size = 512; 2444 bdev->max_num_segments = 16; 2445 g_io_done = false; 2446 2447 /* IO crossing the IO boundary requires split 2448 * Total 2 child IOs. 2449 */ 2450 2451 /* The 1st child IO split the segment_size to multiple segment entry */ 2452 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 14, 2, 2); 2453 ut_expected_io_set_iov(expected_io, 0, (void *)0xF000, 512); 2454 ut_expected_io_set_iov(expected_io, 1, (void *)(0xF000 + 512), 512); 2455 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2456 2457 /* The 2nd child IO split the segment_size to multiple segment entry */ 2458 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 16, 2, 2); 2459 ut_expected_io_set_iov(expected_io, 0, (void *)(0xF000 + 2 * 512), 512); 2460 ut_expected_io_set_iov(expected_io, 1, (void *)(0xF000 + 3 * 512), 512); 2461 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2462 2463 rc = spdk_bdev_read_blocks(desc, io_ch, (void *)0xF000, 14, 4, io_done, NULL); 2464 CU_ASSERT(rc == 0); 2465 CU_ASSERT(g_io_done == false); 2466 2467 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 2); 2468 stub_complete_io(2); 2469 CU_ASSERT(g_io_done == true); 2470 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 2471 2472 /* Second case optimal_io_boundary > max_segment_size * max_num_segments */ 2473 bdev->max_segment_size = 15 * 512; 2474 bdev->max_num_segments = 1; 2475 g_io_done = false; 2476 2477 /* IO crossing the IO boundary requires split. 2478 * The 1st child IO segment size exceeds the max_segment_size, 2479 * So 1st child IO will be splitted to multiple segment entry. 2480 * Then it split to 2 child IOs because of the max_num_segments. 2481 * Total 3 child IOs. 2482 */ 2483 2484 /* The first 2 IOs are in an IO boundary. 2485 * Because the optimal_io_boundary > max_segment_size * max_num_segments 2486 * So it split to the first 2 IOs. 2487 */ 2488 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 0, 15, 1); 2489 ut_expected_io_set_iov(expected_io, 0, (void *)0xF000, 512 * 15); 2490 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2491 2492 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 15, 1, 1); 2493 ut_expected_io_set_iov(expected_io, 0, (void *)(0xF000 + 512 * 15), 512); 2494 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2495 2496 /* The 3rd Child IO is because of the io boundary */ 2497 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 16, 2, 1); 2498 ut_expected_io_set_iov(expected_io, 0, (void *)(0xF000 + 512 * 16), 512 * 2); 2499 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2500 2501 rc = spdk_bdev_read_blocks(desc, io_ch, (void *)0xF000, 0, 18, io_done, NULL); 2502 CU_ASSERT(rc == 0); 2503 CU_ASSERT(g_io_done == false); 2504 2505 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 3); 2506 stub_complete_io(3); 2507 CU_ASSERT(g_io_done == true); 2508 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 2509 2510 /* Third case optimal_io_boundary < max_segment_size * max_num_segments */ 2511 bdev->max_segment_size = 17 * 512; 2512 bdev->max_num_segments = 1; 2513 g_io_done = false; 2514 2515 /* IO crossing the IO boundary requires split. 2516 * Child IO does not split. 2517 * Total 2 child IOs. 2518 */ 2519 2520 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 0, 16, 1); 2521 ut_expected_io_set_iov(expected_io, 0, (void *)0xF000, 512 * 16); 2522 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2523 2524 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 16, 2, 1); 2525 ut_expected_io_set_iov(expected_io, 0, (void *)(0xF000 + 512 * 16), 512 * 2); 2526 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2527 2528 rc = spdk_bdev_read_blocks(desc, io_ch, (void *)0xF000, 0, 18, io_done, NULL); 2529 CU_ASSERT(rc == 0); 2530 CU_ASSERT(g_io_done == false); 2531 2532 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 2); 2533 stub_complete_io(2); 2534 CU_ASSERT(g_io_done == true); 2535 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 2536 2537 /* Now set up a more complex, multi-vector command that needs to be split, 2538 * including splitting iovecs. 2539 * optimal_io_boundary < max_segment_size * max_num_segments 2540 */ 2541 bdev->max_segment_size = 3 * 512; 2542 bdev->max_num_segments = 6; 2543 g_io_done = false; 2544 2545 iov[0].iov_base = (void *)0x10000; 2546 iov[0].iov_len = 4 * 512; 2547 iov[1].iov_base = (void *)0x20000; 2548 iov[1].iov_len = 4 * 512; 2549 iov[2].iov_base = (void *)0x30000; 2550 iov[2].iov_len = 10 * 512; 2551 2552 /* IO crossing the IO boundary requires split. 2553 * The 1st child IO segment size exceeds the max_segment_size and after 2554 * splitting segment_size, the num_segments exceeds max_num_segments. 2555 * So 1st child IO will be splitted to 2 child IOs. 2556 * Total 3 child IOs. 2557 */ 2558 2559 /* The first 2 IOs are in an IO boundary. 2560 * After splitting segment size the segment num exceeds. 2561 * So it splits to 2 child IOs. 2562 */ 2563 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 0, 14, 6); 2564 ut_expected_io_set_iov(expected_io, 0, iov[0].iov_base, 512 * 3); 2565 ut_expected_io_set_iov(expected_io, 1, iov[0].iov_base + 512 * 3, 512); 2566 ut_expected_io_set_iov(expected_io, 2, iov[1].iov_base, 512 * 3); 2567 ut_expected_io_set_iov(expected_io, 3, iov[1].iov_base + 512 * 3, 512); 2568 ut_expected_io_set_iov(expected_io, 4, iov[2].iov_base, 512 * 3); 2569 ut_expected_io_set_iov(expected_io, 5, iov[2].iov_base + 512 * 3, 512 * 3); 2570 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2571 2572 /* The 2nd child IO has the left segment entry */ 2573 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 14, 2, 1); 2574 ut_expected_io_set_iov(expected_io, 0, iov[2].iov_base + 512 * 6, 512 * 2); 2575 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2576 2577 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 16, 2, 1); 2578 ut_expected_io_set_iov(expected_io, 0, iov[2].iov_base + 512 * 8, 512 * 2); 2579 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2580 2581 rc = spdk_bdev_writev_blocks(desc, io_ch, iov, 3, 0, 18, io_done, NULL); 2582 CU_ASSERT(rc == 0); 2583 CU_ASSERT(g_io_done == false); 2584 2585 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 3); 2586 stub_complete_io(3); 2587 CU_ASSERT(g_io_done == true); 2588 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 2589 2590 /* A very complicated case. Each sg entry exceeds max_segment_size 2591 * and split on io boundary. 2592 * optimal_io_boundary < max_segment_size * max_num_segments 2593 */ 2594 bdev->max_segment_size = 3 * 512; 2595 bdev->max_num_segments = BDEV_IO_NUM_CHILD_IOV; 2596 g_io_done = false; 2597 2598 for (i = 0; i < 20; i++) { 2599 iov[i].iov_base = (void *)((i + 1) * 0x10000); 2600 iov[i].iov_len = 512 * 4; 2601 } 2602 2603 /* IO crossing the IO boundary requires split. 2604 * 80 block length can split 5 child IOs base on offset and IO boundary. 2605 * Each iov entry needs to be splitted to 2 entries because of max_segment_size 2606 * Total 5 child IOs. 2607 */ 2608 2609 /* 4 iov entries are in an IO boundary and each iov entry splits to 2. 2610 * So each child IO occupies 8 child iov entries. 2611 */ 2612 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 0, 16, 8); 2613 for (i = 0; i < 4; i++) { 2614 int iovcnt = i * 2; 2615 ut_expected_io_set_iov(expected_io, iovcnt, iov[i].iov_base, 512 * 3); 2616 ut_expected_io_set_iov(expected_io, iovcnt + 1, iov[i].iov_base + 512 * 3, 512); 2617 } 2618 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2619 2620 /* 2nd child IO and total 16 child iov entries of parent IO */ 2621 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 16, 16, 8); 2622 for (i = 4; i < 8; i++) { 2623 int iovcnt = (i - 4) * 2; 2624 ut_expected_io_set_iov(expected_io, iovcnt, iov[i].iov_base, 512 * 3); 2625 ut_expected_io_set_iov(expected_io, iovcnt + 1, iov[i].iov_base + 512 * 3, 512); 2626 } 2627 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2628 2629 /* 3rd child IO and total 24 child iov entries of parent IO */ 2630 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 32, 16, 8); 2631 for (i = 8; i < 12; i++) { 2632 int iovcnt = (i - 8) * 2; 2633 ut_expected_io_set_iov(expected_io, iovcnt, iov[i].iov_base, 512 * 3); 2634 ut_expected_io_set_iov(expected_io, iovcnt + 1, iov[i].iov_base + 512 * 3, 512); 2635 } 2636 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2637 2638 /* 4th child IO and total 32 child iov entries of parent IO */ 2639 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 48, 16, 8); 2640 for (i = 12; i < 16; i++) { 2641 int iovcnt = (i - 12) * 2; 2642 ut_expected_io_set_iov(expected_io, iovcnt, iov[i].iov_base, 512 * 3); 2643 ut_expected_io_set_iov(expected_io, iovcnt + 1, iov[i].iov_base + 512 * 3, 512); 2644 } 2645 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2646 2647 /* 5th child IO and because of the child iov entry it should be splitted 2648 * in next round. 2649 */ 2650 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 64, 16, 8); 2651 for (i = 16; i < 20; i++) { 2652 int iovcnt = (i - 16) * 2; 2653 ut_expected_io_set_iov(expected_io, iovcnt, iov[i].iov_base, 512 * 3); 2654 ut_expected_io_set_iov(expected_io, iovcnt + 1, iov[i].iov_base + 512 * 3, 512); 2655 } 2656 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2657 2658 rc = spdk_bdev_writev_blocks(desc, io_ch, iov, 20, 0, 80, io_done, NULL); 2659 CU_ASSERT(rc == 0); 2660 CU_ASSERT(g_io_done == false); 2661 2662 /* First split round */ 2663 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 4); 2664 stub_complete_io(4); 2665 CU_ASSERT(g_io_done == false); 2666 2667 /* Second split round */ 2668 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 2669 stub_complete_io(1); 2670 CU_ASSERT(g_io_done == true); 2671 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 2672 2673 spdk_put_io_channel(io_ch); 2674 spdk_bdev_close(desc); 2675 free_bdev(bdev); 2676 spdk_bdev_finish(bdev_fini_cb, NULL); 2677 poll_threads(); 2678 } 2679 2680 static void 2681 bdev_io_split_with_io_wait(void) 2682 { 2683 struct spdk_bdev *bdev; 2684 struct spdk_bdev_desc *desc = NULL; 2685 struct spdk_io_channel *io_ch; 2686 struct spdk_bdev_channel *channel; 2687 struct spdk_bdev_mgmt_channel *mgmt_ch; 2688 struct spdk_bdev_opts bdev_opts = {}; 2689 struct iovec iov[3]; 2690 struct ut_expected_io *expected_io; 2691 int rc; 2692 2693 spdk_bdev_get_opts(&bdev_opts, sizeof(bdev_opts)); 2694 bdev_opts.bdev_io_pool_size = 2; 2695 bdev_opts.bdev_io_cache_size = 1; 2696 2697 rc = spdk_bdev_set_opts(&bdev_opts); 2698 CU_ASSERT(rc == 0); 2699 spdk_bdev_initialize(bdev_init_cb, NULL); 2700 2701 bdev = allocate_bdev("bdev0"); 2702 2703 rc = spdk_bdev_open_ext("bdev0", true, bdev_ut_event_cb, NULL, &desc); 2704 CU_ASSERT(rc == 0); 2705 CU_ASSERT(desc != NULL); 2706 CU_ASSERT(bdev == spdk_bdev_desc_get_bdev(desc)); 2707 io_ch = spdk_bdev_get_io_channel(desc); 2708 CU_ASSERT(io_ch != NULL); 2709 channel = spdk_io_channel_get_ctx(io_ch); 2710 mgmt_ch = channel->shared_resource->mgmt_ch; 2711 2712 bdev->optimal_io_boundary = 16; 2713 bdev->split_on_optimal_io_boundary = true; 2714 2715 rc = spdk_bdev_read_blocks(desc, io_ch, NULL, 0, 1, io_done, NULL); 2716 CU_ASSERT(rc == 0); 2717 2718 /* Now test that a single-vector command is split correctly. 2719 * Offset 14, length 8, payload 0xF000 2720 * Child - Offset 14, length 2, payload 0xF000 2721 * Child - Offset 16, length 6, payload 0xF000 + 2 * 512 2722 * 2723 * Set up the expected values before calling spdk_bdev_read_blocks 2724 */ 2725 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 14, 2, 1); 2726 ut_expected_io_set_iov(expected_io, 0, (void *)0xF000, 2 * 512); 2727 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2728 2729 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 16, 6, 1); 2730 ut_expected_io_set_iov(expected_io, 0, (void *)(0xF000 + 2 * 512), 6 * 512); 2731 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2732 2733 /* The following children will be submitted sequentially due to the capacity of 2734 * spdk_bdev_io. 2735 */ 2736 2737 /* The first child I/O will be queued to wait until an spdk_bdev_io becomes available */ 2738 rc = spdk_bdev_read_blocks(desc, io_ch, (void *)0xF000, 14, 8, io_done, NULL); 2739 CU_ASSERT(rc == 0); 2740 CU_ASSERT(!TAILQ_EMPTY(&mgmt_ch->io_wait_queue)); 2741 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 2742 2743 /* Completing the first read I/O will submit the first child */ 2744 stub_complete_io(1); 2745 CU_ASSERT(TAILQ_EMPTY(&mgmt_ch->io_wait_queue)); 2746 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 2747 2748 /* Completing the first child will submit the second child */ 2749 stub_complete_io(1); 2750 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 2751 2752 /* Complete the second child I/O. This should result in our callback getting 2753 * invoked since the parent I/O is now complete. 2754 */ 2755 stub_complete_io(1); 2756 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 2757 2758 /* Now set up a more complex, multi-vector command that needs to be split, 2759 * including splitting iovecs. 2760 */ 2761 iov[0].iov_base = (void *)0x10000; 2762 iov[0].iov_len = 512; 2763 iov[1].iov_base = (void *)0x20000; 2764 iov[1].iov_len = 20 * 512; 2765 iov[2].iov_base = (void *)0x30000; 2766 iov[2].iov_len = 11 * 512; 2767 2768 g_io_done = false; 2769 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 14, 2, 2); 2770 ut_expected_io_set_iov(expected_io, 0, (void *)0x10000, 512); 2771 ut_expected_io_set_iov(expected_io, 1, (void *)0x20000, 512); 2772 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2773 2774 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 16, 16, 1); 2775 ut_expected_io_set_iov(expected_io, 0, (void *)(0x20000 + 512), 16 * 512); 2776 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2777 2778 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 32, 14, 2); 2779 ut_expected_io_set_iov(expected_io, 0, (void *)(0x20000 + 17 * 512), 3 * 512); 2780 ut_expected_io_set_iov(expected_io, 1, (void *)0x30000, 11 * 512); 2781 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2782 2783 rc = spdk_bdev_writev_blocks(desc, io_ch, iov, 3, 14, 32, io_done, NULL); 2784 CU_ASSERT(rc == 0); 2785 CU_ASSERT(g_io_done == false); 2786 2787 /* The following children will be submitted sequentially due to the capacity of 2788 * spdk_bdev_io. 2789 */ 2790 2791 /* Completing the first child will submit the second child */ 2792 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 2793 stub_complete_io(1); 2794 CU_ASSERT(g_io_done == false); 2795 2796 /* Completing the second child will submit the third child */ 2797 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 2798 stub_complete_io(1); 2799 CU_ASSERT(g_io_done == false); 2800 2801 /* Completing the third child will result in our callback getting invoked 2802 * since the parent I/O is now complete. 2803 */ 2804 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 2805 stub_complete_io(1); 2806 CU_ASSERT(g_io_done == true); 2807 2808 CU_ASSERT(TAILQ_EMPTY(&g_bdev_ut_channel->expected_io)); 2809 2810 spdk_put_io_channel(io_ch); 2811 spdk_bdev_close(desc); 2812 free_bdev(bdev); 2813 spdk_bdev_finish(bdev_fini_cb, NULL); 2814 poll_threads(); 2815 } 2816 2817 static void 2818 bdev_io_alignment(void) 2819 { 2820 struct spdk_bdev *bdev; 2821 struct spdk_bdev_desc *desc = NULL; 2822 struct spdk_io_channel *io_ch; 2823 struct spdk_bdev_opts bdev_opts = {}; 2824 int rc; 2825 void *buf = NULL; 2826 struct iovec iovs[2]; 2827 int iovcnt; 2828 uint64_t alignment; 2829 2830 spdk_bdev_get_opts(&bdev_opts, sizeof(bdev_opts)); 2831 bdev_opts.bdev_io_pool_size = 20; 2832 bdev_opts.bdev_io_cache_size = 2; 2833 2834 rc = spdk_bdev_set_opts(&bdev_opts); 2835 CU_ASSERT(rc == 0); 2836 spdk_bdev_initialize(bdev_init_cb, NULL); 2837 2838 fn_table.submit_request = stub_submit_request_get_buf; 2839 bdev = allocate_bdev("bdev0"); 2840 2841 rc = spdk_bdev_open_ext("bdev0", true, bdev_ut_event_cb, NULL, &desc); 2842 CU_ASSERT(rc == 0); 2843 CU_ASSERT(desc != NULL); 2844 CU_ASSERT(bdev == spdk_bdev_desc_get_bdev(desc)); 2845 io_ch = spdk_bdev_get_io_channel(desc); 2846 CU_ASSERT(io_ch != NULL); 2847 2848 /* Create aligned buffer */ 2849 rc = posix_memalign(&buf, 4096, 8192); 2850 SPDK_CU_ASSERT_FATAL(rc == 0); 2851 2852 /* Pass aligned single buffer with no alignment required */ 2853 alignment = 1; 2854 bdev->required_alignment = spdk_u32log2(alignment); 2855 2856 rc = spdk_bdev_write_blocks(desc, io_ch, buf, 0, 1, io_done, NULL); 2857 CU_ASSERT(rc == 0); 2858 stub_complete_io(1); 2859 CU_ASSERT(_are_iovs_aligned(g_bdev_io->u.bdev.iovs, g_bdev_io->u.bdev.iovcnt, 2860 alignment)); 2861 2862 rc = spdk_bdev_read_blocks(desc, io_ch, buf, 0, 1, io_done, NULL); 2863 CU_ASSERT(rc == 0); 2864 stub_complete_io(1); 2865 CU_ASSERT(_are_iovs_aligned(g_bdev_io->u.bdev.iovs, g_bdev_io->u.bdev.iovcnt, 2866 alignment)); 2867 2868 /* Pass unaligned single buffer with no alignment required */ 2869 alignment = 1; 2870 bdev->required_alignment = spdk_u32log2(alignment); 2871 2872 rc = spdk_bdev_write_blocks(desc, io_ch, buf + 4, 0, 1, io_done, NULL); 2873 CU_ASSERT(rc == 0); 2874 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 0); 2875 CU_ASSERT(g_bdev_io->u.bdev.iovs[0].iov_base == buf + 4); 2876 stub_complete_io(1); 2877 2878 rc = spdk_bdev_read_blocks(desc, io_ch, buf + 4, 0, 1, io_done, NULL); 2879 CU_ASSERT(rc == 0); 2880 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 0); 2881 CU_ASSERT(g_bdev_io->u.bdev.iovs[0].iov_base == buf + 4); 2882 stub_complete_io(1); 2883 2884 /* Pass unaligned single buffer with 512 alignment required */ 2885 alignment = 512; 2886 bdev->required_alignment = spdk_u32log2(alignment); 2887 2888 rc = spdk_bdev_write_blocks(desc, io_ch, buf + 4, 0, 1, io_done, NULL); 2889 CU_ASSERT(rc == 0); 2890 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 1); 2891 CU_ASSERT(g_bdev_io->u.bdev.iovs == &g_bdev_io->internal.bounce_iov); 2892 CU_ASSERT(_are_iovs_aligned(g_bdev_io->u.bdev.iovs, g_bdev_io->u.bdev.iovcnt, 2893 alignment)); 2894 stub_complete_io(1); 2895 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 0); 2896 2897 rc = spdk_bdev_read_blocks(desc, io_ch, buf + 4, 0, 1, io_done, NULL); 2898 CU_ASSERT(rc == 0); 2899 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 1); 2900 CU_ASSERT(g_bdev_io->u.bdev.iovs == &g_bdev_io->internal.bounce_iov); 2901 CU_ASSERT(_are_iovs_aligned(g_bdev_io->u.bdev.iovs, g_bdev_io->u.bdev.iovcnt, 2902 alignment)); 2903 stub_complete_io(1); 2904 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 0); 2905 2906 /* Pass unaligned single buffer with 4096 alignment required */ 2907 alignment = 4096; 2908 bdev->required_alignment = spdk_u32log2(alignment); 2909 2910 rc = spdk_bdev_write_blocks(desc, io_ch, buf + 8, 0, 1, io_done, NULL); 2911 CU_ASSERT(rc == 0); 2912 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 1); 2913 CU_ASSERT(g_bdev_io->u.bdev.iovs == &g_bdev_io->internal.bounce_iov); 2914 CU_ASSERT(_are_iovs_aligned(g_bdev_io->u.bdev.iovs, g_bdev_io->u.bdev.iovcnt, 2915 alignment)); 2916 stub_complete_io(1); 2917 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 0); 2918 2919 rc = spdk_bdev_read_blocks(desc, io_ch, buf + 8, 0, 1, io_done, NULL); 2920 CU_ASSERT(rc == 0); 2921 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 1); 2922 CU_ASSERT(g_bdev_io->u.bdev.iovs == &g_bdev_io->internal.bounce_iov); 2923 CU_ASSERT(_are_iovs_aligned(g_bdev_io->u.bdev.iovs, g_bdev_io->u.bdev.iovcnt, 2924 alignment)); 2925 stub_complete_io(1); 2926 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 0); 2927 2928 /* Pass aligned iovs with no alignment required */ 2929 alignment = 1; 2930 bdev->required_alignment = spdk_u32log2(alignment); 2931 2932 iovcnt = 1; 2933 iovs[0].iov_base = buf; 2934 iovs[0].iov_len = 512; 2935 2936 rc = spdk_bdev_writev(desc, io_ch, iovs, iovcnt, 0, 512, io_done, NULL); 2937 CU_ASSERT(rc == 0); 2938 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 0); 2939 stub_complete_io(1); 2940 CU_ASSERT(g_bdev_io->u.bdev.iovs[0].iov_base == iovs[0].iov_base); 2941 2942 rc = spdk_bdev_readv(desc, io_ch, iovs, iovcnt, 0, 512, io_done, NULL); 2943 CU_ASSERT(rc == 0); 2944 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 0); 2945 stub_complete_io(1); 2946 CU_ASSERT(g_bdev_io->u.bdev.iovs[0].iov_base == iovs[0].iov_base); 2947 2948 /* Pass unaligned iovs with no alignment required */ 2949 alignment = 1; 2950 bdev->required_alignment = spdk_u32log2(alignment); 2951 2952 iovcnt = 2; 2953 iovs[0].iov_base = buf + 16; 2954 iovs[0].iov_len = 256; 2955 iovs[1].iov_base = buf + 16 + 256 + 32; 2956 iovs[1].iov_len = 256; 2957 2958 rc = spdk_bdev_writev(desc, io_ch, iovs, iovcnt, 0, 512, io_done, NULL); 2959 CU_ASSERT(rc == 0); 2960 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 0); 2961 stub_complete_io(1); 2962 CU_ASSERT(g_bdev_io->u.bdev.iovs[0].iov_base == iovs[0].iov_base); 2963 2964 rc = spdk_bdev_readv(desc, io_ch, iovs, iovcnt, 0, 512, io_done, NULL); 2965 CU_ASSERT(rc == 0); 2966 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 0); 2967 stub_complete_io(1); 2968 CU_ASSERT(g_bdev_io->u.bdev.iovs[0].iov_base == iovs[0].iov_base); 2969 2970 /* Pass unaligned iov with 2048 alignment required */ 2971 alignment = 2048; 2972 bdev->required_alignment = spdk_u32log2(alignment); 2973 2974 iovcnt = 2; 2975 iovs[0].iov_base = buf + 16; 2976 iovs[0].iov_len = 256; 2977 iovs[1].iov_base = buf + 16 + 256 + 32; 2978 iovs[1].iov_len = 256; 2979 2980 rc = spdk_bdev_writev(desc, io_ch, iovs, iovcnt, 0, 512, io_done, NULL); 2981 CU_ASSERT(rc == 0); 2982 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == iovcnt); 2983 CU_ASSERT(g_bdev_io->u.bdev.iovs == &g_bdev_io->internal.bounce_iov); 2984 CU_ASSERT(_are_iovs_aligned(g_bdev_io->u.bdev.iovs, g_bdev_io->u.bdev.iovcnt, 2985 alignment)); 2986 stub_complete_io(1); 2987 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 0); 2988 2989 rc = spdk_bdev_readv(desc, io_ch, iovs, iovcnt, 0, 512, io_done, NULL); 2990 CU_ASSERT(rc == 0); 2991 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == iovcnt); 2992 CU_ASSERT(g_bdev_io->u.bdev.iovs == &g_bdev_io->internal.bounce_iov); 2993 CU_ASSERT(_are_iovs_aligned(g_bdev_io->u.bdev.iovs, g_bdev_io->u.bdev.iovcnt, 2994 alignment)); 2995 stub_complete_io(1); 2996 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 0); 2997 2998 /* Pass iov without allocated buffer without alignment required */ 2999 alignment = 1; 3000 bdev->required_alignment = spdk_u32log2(alignment); 3001 3002 iovcnt = 1; 3003 iovs[0].iov_base = NULL; 3004 iovs[0].iov_len = 0; 3005 3006 rc = spdk_bdev_readv(desc, io_ch, iovs, iovcnt, 0, 512, io_done, NULL); 3007 CU_ASSERT(rc == 0); 3008 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 0); 3009 CU_ASSERT(_are_iovs_aligned(g_bdev_io->u.bdev.iovs, g_bdev_io->u.bdev.iovcnt, 3010 alignment)); 3011 stub_complete_io(1); 3012 3013 /* Pass iov without allocated buffer with 1024 alignment required */ 3014 alignment = 1024; 3015 bdev->required_alignment = spdk_u32log2(alignment); 3016 3017 iovcnt = 1; 3018 iovs[0].iov_base = NULL; 3019 iovs[0].iov_len = 0; 3020 3021 rc = spdk_bdev_readv(desc, io_ch, iovs, iovcnt, 0, 512, io_done, NULL); 3022 CU_ASSERT(rc == 0); 3023 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 0); 3024 CU_ASSERT(_are_iovs_aligned(g_bdev_io->u.bdev.iovs, g_bdev_io->u.bdev.iovcnt, 3025 alignment)); 3026 stub_complete_io(1); 3027 3028 spdk_put_io_channel(io_ch); 3029 spdk_bdev_close(desc); 3030 free_bdev(bdev); 3031 fn_table.submit_request = stub_submit_request; 3032 spdk_bdev_finish(bdev_fini_cb, NULL); 3033 poll_threads(); 3034 3035 free(buf); 3036 } 3037 3038 static void 3039 bdev_io_alignment_with_boundary(void) 3040 { 3041 struct spdk_bdev *bdev; 3042 struct spdk_bdev_desc *desc = NULL; 3043 struct spdk_io_channel *io_ch; 3044 struct spdk_bdev_opts bdev_opts = {}; 3045 int rc; 3046 void *buf = NULL; 3047 struct iovec iovs[2]; 3048 int iovcnt; 3049 uint64_t alignment; 3050 3051 spdk_bdev_get_opts(&bdev_opts, sizeof(bdev_opts)); 3052 bdev_opts.bdev_io_pool_size = 20; 3053 bdev_opts.bdev_io_cache_size = 2; 3054 3055 bdev_opts.opts_size = sizeof(bdev_opts); 3056 rc = spdk_bdev_set_opts(&bdev_opts); 3057 CU_ASSERT(rc == 0); 3058 spdk_bdev_initialize(bdev_init_cb, NULL); 3059 3060 fn_table.submit_request = stub_submit_request_get_buf; 3061 bdev = allocate_bdev("bdev0"); 3062 3063 rc = spdk_bdev_open_ext("bdev0", true, bdev_ut_event_cb, NULL, &desc); 3064 CU_ASSERT(rc == 0); 3065 CU_ASSERT(desc != NULL); 3066 CU_ASSERT(bdev == spdk_bdev_desc_get_bdev(desc)); 3067 io_ch = spdk_bdev_get_io_channel(desc); 3068 CU_ASSERT(io_ch != NULL); 3069 3070 /* Create aligned buffer */ 3071 rc = posix_memalign(&buf, 4096, 131072); 3072 SPDK_CU_ASSERT_FATAL(rc == 0); 3073 g_io_exp_status = SPDK_BDEV_IO_STATUS_SUCCESS; 3074 3075 /* 512 * 3 with 2 IO boundary, allocate small data buffer from bdev layer */ 3076 alignment = 512; 3077 bdev->required_alignment = spdk_u32log2(alignment); 3078 bdev->optimal_io_boundary = 2; 3079 bdev->split_on_optimal_io_boundary = true; 3080 3081 iovcnt = 1; 3082 iovs[0].iov_base = NULL; 3083 iovs[0].iov_len = 512 * 3; 3084 3085 rc = spdk_bdev_readv_blocks(desc, io_ch, iovs, iovcnt, 1, 3, io_done, NULL); 3086 CU_ASSERT(rc == 0); 3087 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 2); 3088 stub_complete_io(2); 3089 3090 /* 8KiB with 16 IO boundary, allocate large data buffer from bdev layer */ 3091 alignment = 512; 3092 bdev->required_alignment = spdk_u32log2(alignment); 3093 bdev->optimal_io_boundary = 16; 3094 bdev->split_on_optimal_io_boundary = true; 3095 3096 iovcnt = 1; 3097 iovs[0].iov_base = NULL; 3098 iovs[0].iov_len = 512 * 16; 3099 3100 rc = spdk_bdev_readv_blocks(desc, io_ch, iovs, iovcnt, 1, 16, io_done, NULL); 3101 CU_ASSERT(rc == 0); 3102 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 2); 3103 stub_complete_io(2); 3104 3105 /* 512 * 160 with 128 IO boundary, 63.5KiB + 16.5KiB for the two children requests */ 3106 alignment = 512; 3107 bdev->required_alignment = spdk_u32log2(alignment); 3108 bdev->optimal_io_boundary = 128; 3109 bdev->split_on_optimal_io_boundary = true; 3110 3111 iovcnt = 1; 3112 iovs[0].iov_base = buf + 16; 3113 iovs[0].iov_len = 512 * 160; 3114 rc = spdk_bdev_readv_blocks(desc, io_ch, iovs, iovcnt, 1, 160, io_done, NULL); 3115 CU_ASSERT(rc == 0); 3116 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 2); 3117 stub_complete_io(2); 3118 3119 /* 512 * 3 with 2 IO boundary */ 3120 alignment = 512; 3121 bdev->required_alignment = spdk_u32log2(alignment); 3122 bdev->optimal_io_boundary = 2; 3123 bdev->split_on_optimal_io_boundary = true; 3124 3125 iovcnt = 2; 3126 iovs[0].iov_base = buf + 16; 3127 iovs[0].iov_len = 512; 3128 iovs[1].iov_base = buf + 16 + 512 + 32; 3129 iovs[1].iov_len = 1024; 3130 3131 rc = spdk_bdev_writev_blocks(desc, io_ch, iovs, iovcnt, 1, 3, io_done, NULL); 3132 CU_ASSERT(rc == 0); 3133 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 2); 3134 stub_complete_io(2); 3135 3136 rc = spdk_bdev_readv_blocks(desc, io_ch, iovs, iovcnt, 1, 3, io_done, NULL); 3137 CU_ASSERT(rc == 0); 3138 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 2); 3139 stub_complete_io(2); 3140 3141 /* 512 * 64 with 32 IO boundary */ 3142 bdev->optimal_io_boundary = 32; 3143 iovcnt = 2; 3144 iovs[0].iov_base = buf + 16; 3145 iovs[0].iov_len = 16384; 3146 iovs[1].iov_base = buf + 16 + 16384 + 32; 3147 iovs[1].iov_len = 16384; 3148 3149 rc = spdk_bdev_writev_blocks(desc, io_ch, iovs, iovcnt, 1, 64, io_done, NULL); 3150 CU_ASSERT(rc == 0); 3151 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 3); 3152 stub_complete_io(3); 3153 3154 rc = spdk_bdev_readv_blocks(desc, io_ch, iovs, iovcnt, 1, 64, io_done, NULL); 3155 CU_ASSERT(rc == 0); 3156 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 3); 3157 stub_complete_io(3); 3158 3159 /* 512 * 160 with 32 IO boundary */ 3160 iovcnt = 1; 3161 iovs[0].iov_base = buf + 16; 3162 iovs[0].iov_len = 16384 + 65536; 3163 3164 rc = spdk_bdev_writev_blocks(desc, io_ch, iovs, iovcnt, 1, 160, io_done, NULL); 3165 CU_ASSERT(rc == 0); 3166 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 6); 3167 stub_complete_io(6); 3168 3169 spdk_put_io_channel(io_ch); 3170 spdk_bdev_close(desc); 3171 free_bdev(bdev); 3172 fn_table.submit_request = stub_submit_request; 3173 spdk_bdev_finish(bdev_fini_cb, NULL); 3174 poll_threads(); 3175 3176 free(buf); 3177 } 3178 3179 static void 3180 histogram_status_cb(void *cb_arg, int status) 3181 { 3182 g_status = status; 3183 } 3184 3185 static void 3186 histogram_data_cb(void *cb_arg, int status, struct spdk_histogram_data *histogram) 3187 { 3188 g_status = status; 3189 g_histogram = histogram; 3190 } 3191 3192 static void 3193 histogram_io_count(void *ctx, uint64_t start, uint64_t end, uint64_t count, 3194 uint64_t total, uint64_t so_far) 3195 { 3196 g_count += count; 3197 } 3198 3199 static void 3200 bdev_histograms(void) 3201 { 3202 struct spdk_bdev *bdev; 3203 struct spdk_bdev_desc *desc = NULL; 3204 struct spdk_io_channel *ch; 3205 struct spdk_histogram_data *histogram; 3206 uint8_t buf[4096]; 3207 int rc; 3208 3209 spdk_bdev_initialize(bdev_init_cb, NULL); 3210 3211 bdev = allocate_bdev("bdev"); 3212 3213 rc = spdk_bdev_open_ext("bdev", true, bdev_ut_event_cb, NULL, &desc); 3214 CU_ASSERT(rc == 0); 3215 CU_ASSERT(desc != NULL); 3216 CU_ASSERT(bdev == spdk_bdev_desc_get_bdev(desc)); 3217 3218 ch = spdk_bdev_get_io_channel(desc); 3219 CU_ASSERT(ch != NULL); 3220 3221 /* Enable histogram */ 3222 g_status = -1; 3223 spdk_bdev_histogram_enable(bdev, histogram_status_cb, NULL, true); 3224 poll_threads(); 3225 CU_ASSERT(g_status == 0); 3226 CU_ASSERT(bdev->internal.histogram_enabled == true); 3227 3228 /* Allocate histogram */ 3229 histogram = spdk_histogram_data_alloc(); 3230 SPDK_CU_ASSERT_FATAL(histogram != NULL); 3231 3232 /* Check if histogram is zeroed */ 3233 spdk_bdev_histogram_get(bdev, histogram, histogram_data_cb, NULL); 3234 poll_threads(); 3235 CU_ASSERT(g_status == 0); 3236 SPDK_CU_ASSERT_FATAL(g_histogram != NULL); 3237 3238 g_count = 0; 3239 spdk_histogram_data_iterate(g_histogram, histogram_io_count, NULL); 3240 3241 CU_ASSERT(g_count == 0); 3242 3243 rc = spdk_bdev_write_blocks(desc, ch, buf, 0, 1, io_done, NULL); 3244 CU_ASSERT(rc == 0); 3245 3246 spdk_delay_us(10); 3247 stub_complete_io(1); 3248 poll_threads(); 3249 3250 rc = spdk_bdev_read_blocks(desc, ch, buf, 0, 1, io_done, NULL); 3251 CU_ASSERT(rc == 0); 3252 3253 spdk_delay_us(10); 3254 stub_complete_io(1); 3255 poll_threads(); 3256 3257 /* Check if histogram gathered data from all I/O channels */ 3258 g_histogram = NULL; 3259 spdk_bdev_histogram_get(bdev, histogram, histogram_data_cb, NULL); 3260 poll_threads(); 3261 CU_ASSERT(g_status == 0); 3262 CU_ASSERT(bdev->internal.histogram_enabled == true); 3263 SPDK_CU_ASSERT_FATAL(g_histogram != NULL); 3264 3265 g_count = 0; 3266 spdk_histogram_data_iterate(g_histogram, histogram_io_count, NULL); 3267 CU_ASSERT(g_count == 2); 3268 3269 /* Disable histogram */ 3270 spdk_bdev_histogram_enable(bdev, histogram_status_cb, NULL, false); 3271 poll_threads(); 3272 CU_ASSERT(g_status == 0); 3273 CU_ASSERT(bdev->internal.histogram_enabled == false); 3274 3275 /* Try to run histogram commands on disabled bdev */ 3276 spdk_bdev_histogram_get(bdev, histogram, histogram_data_cb, NULL); 3277 poll_threads(); 3278 CU_ASSERT(g_status == -EFAULT); 3279 3280 spdk_histogram_data_free(histogram); 3281 spdk_put_io_channel(ch); 3282 spdk_bdev_close(desc); 3283 free_bdev(bdev); 3284 spdk_bdev_finish(bdev_fini_cb, NULL); 3285 poll_threads(); 3286 } 3287 3288 static void 3289 _bdev_compare(bool emulated) 3290 { 3291 struct spdk_bdev *bdev; 3292 struct spdk_bdev_desc *desc = NULL; 3293 struct spdk_io_channel *ioch; 3294 struct ut_expected_io *expected_io; 3295 uint64_t offset, num_blocks; 3296 uint32_t num_completed; 3297 char aa_buf[512]; 3298 char bb_buf[512]; 3299 struct iovec compare_iov; 3300 uint8_t io_type; 3301 int rc; 3302 3303 if (emulated) { 3304 io_type = SPDK_BDEV_IO_TYPE_READ; 3305 } else { 3306 io_type = SPDK_BDEV_IO_TYPE_COMPARE; 3307 } 3308 3309 memset(aa_buf, 0xaa, sizeof(aa_buf)); 3310 memset(bb_buf, 0xbb, sizeof(bb_buf)); 3311 3312 g_io_types_supported[SPDK_BDEV_IO_TYPE_COMPARE] = !emulated; 3313 3314 spdk_bdev_initialize(bdev_init_cb, NULL); 3315 fn_table.submit_request = stub_submit_request_get_buf; 3316 bdev = allocate_bdev("bdev"); 3317 3318 rc = spdk_bdev_open_ext("bdev", true, bdev_ut_event_cb, NULL, &desc); 3319 CU_ASSERT_EQUAL(rc, 0); 3320 SPDK_CU_ASSERT_FATAL(desc != NULL); 3321 CU_ASSERT(bdev == spdk_bdev_desc_get_bdev(desc)); 3322 ioch = spdk_bdev_get_io_channel(desc); 3323 SPDK_CU_ASSERT_FATAL(ioch != NULL); 3324 3325 fn_table.submit_request = stub_submit_request_get_buf; 3326 g_io_exp_status = SPDK_BDEV_IO_STATUS_SUCCESS; 3327 3328 offset = 50; 3329 num_blocks = 1; 3330 compare_iov.iov_base = aa_buf; 3331 compare_iov.iov_len = sizeof(aa_buf); 3332 3333 expected_io = ut_alloc_expected_io(io_type, offset, num_blocks, 0); 3334 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 3335 3336 g_io_done = false; 3337 g_compare_read_buf = aa_buf; 3338 g_compare_read_buf_len = sizeof(aa_buf); 3339 rc = spdk_bdev_comparev_blocks(desc, ioch, &compare_iov, 1, offset, num_blocks, io_done, NULL); 3340 CU_ASSERT_EQUAL(rc, 0); 3341 num_completed = stub_complete_io(1); 3342 CU_ASSERT_EQUAL(num_completed, 1); 3343 CU_ASSERT(g_io_done == true); 3344 CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_SUCCESS); 3345 3346 expected_io = ut_alloc_expected_io(io_type, offset, num_blocks, 0); 3347 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 3348 3349 g_io_done = false; 3350 g_compare_read_buf = bb_buf; 3351 g_compare_read_buf_len = sizeof(bb_buf); 3352 rc = spdk_bdev_comparev_blocks(desc, ioch, &compare_iov, 1, offset, num_blocks, io_done, NULL); 3353 CU_ASSERT_EQUAL(rc, 0); 3354 num_completed = stub_complete_io(1); 3355 CU_ASSERT_EQUAL(num_completed, 1); 3356 CU_ASSERT(g_io_done == true); 3357 CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_MISCOMPARE); 3358 3359 spdk_put_io_channel(ioch); 3360 spdk_bdev_close(desc); 3361 free_bdev(bdev); 3362 fn_table.submit_request = stub_submit_request; 3363 spdk_bdev_finish(bdev_fini_cb, NULL); 3364 poll_threads(); 3365 3366 g_io_types_supported[SPDK_BDEV_IO_TYPE_COMPARE] = true; 3367 3368 g_compare_read_buf = NULL; 3369 } 3370 3371 static void 3372 bdev_compare(void) 3373 { 3374 _bdev_compare(true); 3375 _bdev_compare(false); 3376 } 3377 3378 static void 3379 bdev_compare_and_write(void) 3380 { 3381 struct spdk_bdev *bdev; 3382 struct spdk_bdev_desc *desc = NULL; 3383 struct spdk_io_channel *ioch; 3384 struct ut_expected_io *expected_io; 3385 uint64_t offset, num_blocks; 3386 uint32_t num_completed; 3387 char aa_buf[512]; 3388 char bb_buf[512]; 3389 char cc_buf[512]; 3390 char write_buf[512]; 3391 struct iovec compare_iov; 3392 struct iovec write_iov; 3393 int rc; 3394 3395 memset(aa_buf, 0xaa, sizeof(aa_buf)); 3396 memset(bb_buf, 0xbb, sizeof(bb_buf)); 3397 memset(cc_buf, 0xcc, sizeof(cc_buf)); 3398 3399 g_io_types_supported[SPDK_BDEV_IO_TYPE_COMPARE] = false; 3400 3401 spdk_bdev_initialize(bdev_init_cb, NULL); 3402 fn_table.submit_request = stub_submit_request_get_buf; 3403 bdev = allocate_bdev("bdev"); 3404 3405 rc = spdk_bdev_open_ext("bdev", true, bdev_ut_event_cb, NULL, &desc); 3406 CU_ASSERT_EQUAL(rc, 0); 3407 SPDK_CU_ASSERT_FATAL(desc != NULL); 3408 CU_ASSERT(bdev == spdk_bdev_desc_get_bdev(desc)); 3409 ioch = spdk_bdev_get_io_channel(desc); 3410 SPDK_CU_ASSERT_FATAL(ioch != NULL); 3411 3412 fn_table.submit_request = stub_submit_request_get_buf; 3413 g_io_exp_status = SPDK_BDEV_IO_STATUS_SUCCESS; 3414 3415 offset = 50; 3416 num_blocks = 1; 3417 compare_iov.iov_base = aa_buf; 3418 compare_iov.iov_len = sizeof(aa_buf); 3419 write_iov.iov_base = bb_buf; 3420 write_iov.iov_len = sizeof(bb_buf); 3421 3422 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, offset, num_blocks, 0); 3423 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 3424 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, offset, num_blocks, 0); 3425 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 3426 3427 g_io_done = false; 3428 g_compare_read_buf = aa_buf; 3429 g_compare_read_buf_len = sizeof(aa_buf); 3430 memset(write_buf, 0, sizeof(write_buf)); 3431 g_compare_write_buf = write_buf; 3432 g_compare_write_buf_len = sizeof(write_buf); 3433 rc = spdk_bdev_comparev_and_writev_blocks(desc, ioch, &compare_iov, 1, &write_iov, 1, 3434 offset, num_blocks, io_done, NULL); 3435 /* Trigger range locking */ 3436 poll_threads(); 3437 CU_ASSERT_EQUAL(rc, 0); 3438 num_completed = stub_complete_io(1); 3439 CU_ASSERT_EQUAL(num_completed, 1); 3440 CU_ASSERT(g_io_done == false); 3441 num_completed = stub_complete_io(1); 3442 /* Trigger range unlocking */ 3443 poll_threads(); 3444 CU_ASSERT_EQUAL(num_completed, 1); 3445 CU_ASSERT(g_io_done == true); 3446 CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_SUCCESS); 3447 CU_ASSERT(memcmp(write_buf, bb_buf, sizeof(write_buf)) == 0); 3448 3449 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, offset, num_blocks, 0); 3450 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 3451 3452 g_io_done = false; 3453 g_compare_read_buf = cc_buf; 3454 g_compare_read_buf_len = sizeof(cc_buf); 3455 memset(write_buf, 0, sizeof(write_buf)); 3456 g_compare_write_buf = write_buf; 3457 g_compare_write_buf_len = sizeof(write_buf); 3458 rc = spdk_bdev_comparev_and_writev_blocks(desc, ioch, &compare_iov, 1, &write_iov, 1, 3459 offset, num_blocks, io_done, NULL); 3460 /* Trigger range locking */ 3461 poll_threads(); 3462 CU_ASSERT_EQUAL(rc, 0); 3463 num_completed = stub_complete_io(1); 3464 /* Trigger range unlocking earlier because we expect error here */ 3465 poll_threads(); 3466 CU_ASSERT_EQUAL(num_completed, 1); 3467 CU_ASSERT(g_io_done == true); 3468 CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_MISCOMPARE); 3469 num_completed = stub_complete_io(1); 3470 CU_ASSERT_EQUAL(num_completed, 0); 3471 3472 spdk_put_io_channel(ioch); 3473 spdk_bdev_close(desc); 3474 free_bdev(bdev); 3475 fn_table.submit_request = stub_submit_request; 3476 spdk_bdev_finish(bdev_fini_cb, NULL); 3477 poll_threads(); 3478 3479 g_io_types_supported[SPDK_BDEV_IO_TYPE_COMPARE] = true; 3480 3481 g_compare_read_buf = NULL; 3482 g_compare_write_buf = NULL; 3483 } 3484 3485 static void 3486 bdev_write_zeroes(void) 3487 { 3488 struct spdk_bdev *bdev; 3489 struct spdk_bdev_desc *desc = NULL; 3490 struct spdk_io_channel *ioch; 3491 struct ut_expected_io *expected_io; 3492 uint64_t offset, num_io_blocks, num_blocks; 3493 uint32_t num_completed, num_requests; 3494 int rc; 3495 3496 spdk_bdev_initialize(bdev_init_cb, NULL); 3497 bdev = allocate_bdev("bdev"); 3498 3499 rc = spdk_bdev_open_ext("bdev", true, bdev_ut_event_cb, NULL, &desc); 3500 CU_ASSERT_EQUAL(rc, 0); 3501 SPDK_CU_ASSERT_FATAL(desc != NULL); 3502 CU_ASSERT(bdev == spdk_bdev_desc_get_bdev(desc)); 3503 ioch = spdk_bdev_get_io_channel(desc); 3504 SPDK_CU_ASSERT_FATAL(ioch != NULL); 3505 3506 fn_table.submit_request = stub_submit_request; 3507 g_io_exp_status = SPDK_BDEV_IO_STATUS_SUCCESS; 3508 3509 /* First test that if the bdev supports write_zeroes, the request won't be split */ 3510 bdev->md_len = 0; 3511 bdev->blocklen = 4096; 3512 num_blocks = (ZERO_BUFFER_SIZE / bdev->blocklen) * 2; 3513 3514 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE_ZEROES, 0, num_blocks, 0); 3515 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 3516 rc = spdk_bdev_write_zeroes_blocks(desc, ioch, 0, num_blocks, io_done, NULL); 3517 CU_ASSERT_EQUAL(rc, 0); 3518 num_completed = stub_complete_io(1); 3519 CU_ASSERT_EQUAL(num_completed, 1); 3520 3521 /* Check that if write zeroes is not supported it'll be replaced by regular writes */ 3522 ut_enable_io_type(SPDK_BDEV_IO_TYPE_WRITE_ZEROES, false); 3523 num_io_blocks = ZERO_BUFFER_SIZE / bdev->blocklen; 3524 num_requests = 2; 3525 num_blocks = (ZERO_BUFFER_SIZE / bdev->blocklen) * num_requests; 3526 3527 for (offset = 0; offset < num_requests; ++offset) { 3528 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 3529 offset * num_io_blocks, num_io_blocks, 0); 3530 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 3531 } 3532 3533 rc = spdk_bdev_write_zeroes_blocks(desc, ioch, 0, num_blocks, io_done, NULL); 3534 CU_ASSERT_EQUAL(rc, 0); 3535 num_completed = stub_complete_io(num_requests); 3536 CU_ASSERT_EQUAL(num_completed, num_requests); 3537 3538 /* Check that the splitting is correct if bdev has interleaved metadata */ 3539 bdev->md_interleave = true; 3540 bdev->md_len = 64; 3541 bdev->blocklen = 4096 + 64; 3542 num_blocks = (ZERO_BUFFER_SIZE / bdev->blocklen) * 2; 3543 3544 num_requests = offset = 0; 3545 while (offset < num_blocks) { 3546 num_io_blocks = spdk_min(ZERO_BUFFER_SIZE / bdev->blocklen, num_blocks - offset); 3547 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 3548 offset, num_io_blocks, 0); 3549 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 3550 offset += num_io_blocks; 3551 num_requests++; 3552 } 3553 3554 rc = spdk_bdev_write_zeroes_blocks(desc, ioch, 0, num_blocks, io_done, NULL); 3555 CU_ASSERT_EQUAL(rc, 0); 3556 num_completed = stub_complete_io(num_requests); 3557 CU_ASSERT_EQUAL(num_completed, num_requests); 3558 num_completed = stub_complete_io(num_requests); 3559 assert(num_completed == 0); 3560 3561 /* Check the the same for separate metadata buffer */ 3562 bdev->md_interleave = false; 3563 bdev->md_len = 64; 3564 bdev->blocklen = 4096; 3565 3566 num_requests = offset = 0; 3567 while (offset < num_blocks) { 3568 num_io_blocks = spdk_min(ZERO_BUFFER_SIZE / (bdev->blocklen + bdev->md_len), num_blocks); 3569 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 3570 offset, num_io_blocks, 0); 3571 expected_io->md_buf = (char *)g_bdev_mgr.zero_buffer + num_io_blocks * bdev->blocklen; 3572 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 3573 offset += num_io_blocks; 3574 num_requests++; 3575 } 3576 3577 rc = spdk_bdev_write_zeroes_blocks(desc, ioch, 0, num_blocks, io_done, NULL); 3578 CU_ASSERT_EQUAL(rc, 0); 3579 num_completed = stub_complete_io(num_requests); 3580 CU_ASSERT_EQUAL(num_completed, num_requests); 3581 3582 ut_enable_io_type(SPDK_BDEV_IO_TYPE_WRITE_ZEROES, true); 3583 spdk_put_io_channel(ioch); 3584 spdk_bdev_close(desc); 3585 free_bdev(bdev); 3586 spdk_bdev_finish(bdev_fini_cb, NULL); 3587 poll_threads(); 3588 } 3589 3590 static void 3591 bdev_zcopy_write(void) 3592 { 3593 struct spdk_bdev *bdev; 3594 struct spdk_bdev_desc *desc = NULL; 3595 struct spdk_io_channel *ioch; 3596 struct ut_expected_io *expected_io; 3597 uint64_t offset, num_blocks; 3598 uint32_t num_completed; 3599 char aa_buf[512]; 3600 struct iovec iov; 3601 int rc; 3602 const bool populate = false; 3603 const bool commit = true; 3604 3605 memset(aa_buf, 0xaa, sizeof(aa_buf)); 3606 3607 spdk_bdev_initialize(bdev_init_cb, NULL); 3608 bdev = allocate_bdev("bdev"); 3609 3610 rc = spdk_bdev_open_ext("bdev", true, bdev_ut_event_cb, NULL, &desc); 3611 CU_ASSERT_EQUAL(rc, 0); 3612 SPDK_CU_ASSERT_FATAL(desc != NULL); 3613 CU_ASSERT(bdev == spdk_bdev_desc_get_bdev(desc)); 3614 ioch = spdk_bdev_get_io_channel(desc); 3615 SPDK_CU_ASSERT_FATAL(ioch != NULL); 3616 3617 g_io_exp_status = SPDK_BDEV_IO_STATUS_SUCCESS; 3618 3619 offset = 50; 3620 num_blocks = 1; 3621 iov.iov_base = NULL; 3622 iov.iov_len = 0; 3623 3624 g_zcopy_read_buf = (void *) 0x1122334455667788UL; 3625 g_zcopy_read_buf_len = (uint32_t) -1; 3626 /* Do a zcopy start for a write (populate=false) */ 3627 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_ZCOPY, offset, num_blocks, 0); 3628 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 3629 g_io_done = false; 3630 g_zcopy_write_buf = aa_buf; 3631 g_zcopy_write_buf_len = sizeof(aa_buf); 3632 g_zcopy_bdev_io = NULL; 3633 rc = spdk_bdev_zcopy_start(desc, ioch, &iov, 1, offset, num_blocks, populate, io_done, NULL); 3634 CU_ASSERT_EQUAL(rc, 0); 3635 num_completed = stub_complete_io(1); 3636 CU_ASSERT_EQUAL(num_completed, 1); 3637 CU_ASSERT(g_io_done == true); 3638 CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_SUCCESS); 3639 /* Check that the iov has been set up */ 3640 CU_ASSERT(iov.iov_base == g_zcopy_write_buf); 3641 CU_ASSERT(iov.iov_len == g_zcopy_write_buf_len); 3642 /* Check that the bdev_io has been saved */ 3643 CU_ASSERT(g_zcopy_bdev_io != NULL); 3644 /* Now do the zcopy end for a write (commit=true) */ 3645 g_io_done = false; 3646 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_ZCOPY, offset, num_blocks, 0); 3647 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 3648 rc = spdk_bdev_zcopy_end(g_zcopy_bdev_io, commit, io_done, NULL); 3649 CU_ASSERT_EQUAL(rc, 0); 3650 num_completed = stub_complete_io(1); 3651 CU_ASSERT_EQUAL(num_completed, 1); 3652 CU_ASSERT(g_io_done == true); 3653 CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_SUCCESS); 3654 /* Check the g_zcopy are reset by io_done */ 3655 CU_ASSERT(g_zcopy_write_buf == NULL); 3656 CU_ASSERT(g_zcopy_write_buf_len == 0); 3657 /* Check that io_done has freed the g_zcopy_bdev_io */ 3658 CU_ASSERT(g_zcopy_bdev_io == NULL); 3659 3660 /* Check the zcopy read buffer has not been touched which 3661 * ensures that the correct buffers were used. 3662 */ 3663 CU_ASSERT(g_zcopy_read_buf == (void *) 0x1122334455667788UL); 3664 CU_ASSERT(g_zcopy_read_buf_len == (uint32_t) -1); 3665 3666 spdk_put_io_channel(ioch); 3667 spdk_bdev_close(desc); 3668 free_bdev(bdev); 3669 spdk_bdev_finish(bdev_fini_cb, NULL); 3670 poll_threads(); 3671 } 3672 3673 static void 3674 bdev_zcopy_read(void) 3675 { 3676 struct spdk_bdev *bdev; 3677 struct spdk_bdev_desc *desc = NULL; 3678 struct spdk_io_channel *ioch; 3679 struct ut_expected_io *expected_io; 3680 uint64_t offset, num_blocks; 3681 uint32_t num_completed; 3682 char aa_buf[512]; 3683 struct iovec iov; 3684 int rc; 3685 const bool populate = true; 3686 const bool commit = false; 3687 3688 memset(aa_buf, 0xaa, sizeof(aa_buf)); 3689 3690 spdk_bdev_initialize(bdev_init_cb, NULL); 3691 bdev = allocate_bdev("bdev"); 3692 3693 rc = spdk_bdev_open_ext("bdev", true, bdev_ut_event_cb, NULL, &desc); 3694 CU_ASSERT_EQUAL(rc, 0); 3695 SPDK_CU_ASSERT_FATAL(desc != NULL); 3696 CU_ASSERT(bdev == spdk_bdev_desc_get_bdev(desc)); 3697 ioch = spdk_bdev_get_io_channel(desc); 3698 SPDK_CU_ASSERT_FATAL(ioch != NULL); 3699 3700 g_io_exp_status = SPDK_BDEV_IO_STATUS_SUCCESS; 3701 3702 offset = 50; 3703 num_blocks = 1; 3704 iov.iov_base = NULL; 3705 iov.iov_len = 0; 3706 3707 g_zcopy_write_buf = (void *) 0x1122334455667788UL; 3708 g_zcopy_write_buf_len = (uint32_t) -1; 3709 3710 /* Do a zcopy start for a read (populate=true) */ 3711 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_ZCOPY, offset, num_blocks, 0); 3712 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 3713 g_io_done = false; 3714 g_zcopy_read_buf = aa_buf; 3715 g_zcopy_read_buf_len = sizeof(aa_buf); 3716 g_zcopy_bdev_io = NULL; 3717 rc = spdk_bdev_zcopy_start(desc, ioch, &iov, 1, offset, num_blocks, populate, io_done, NULL); 3718 CU_ASSERT_EQUAL(rc, 0); 3719 num_completed = stub_complete_io(1); 3720 CU_ASSERT_EQUAL(num_completed, 1); 3721 CU_ASSERT(g_io_done == true); 3722 CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_SUCCESS); 3723 /* Check that the iov has been set up */ 3724 CU_ASSERT(iov.iov_base == g_zcopy_read_buf); 3725 CU_ASSERT(iov.iov_len == g_zcopy_read_buf_len); 3726 /* Check that the bdev_io has been saved */ 3727 CU_ASSERT(g_zcopy_bdev_io != NULL); 3728 3729 /* Now do the zcopy end for a read (commit=false) */ 3730 g_io_done = false; 3731 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_ZCOPY, offset, num_blocks, 0); 3732 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 3733 rc = spdk_bdev_zcopy_end(g_zcopy_bdev_io, commit, io_done, NULL); 3734 CU_ASSERT_EQUAL(rc, 0); 3735 num_completed = stub_complete_io(1); 3736 CU_ASSERT_EQUAL(num_completed, 1); 3737 CU_ASSERT(g_io_done == true); 3738 CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_SUCCESS); 3739 /* Check the g_zcopy are reset by io_done */ 3740 CU_ASSERT(g_zcopy_read_buf == NULL); 3741 CU_ASSERT(g_zcopy_read_buf_len == 0); 3742 /* Check that io_done has freed the g_zcopy_bdev_io */ 3743 CU_ASSERT(g_zcopy_bdev_io == NULL); 3744 3745 /* Check the zcopy write buffer has not been touched which 3746 * ensures that the correct buffers were used. 3747 */ 3748 CU_ASSERT(g_zcopy_write_buf == (void *) 0x1122334455667788UL); 3749 CU_ASSERT(g_zcopy_write_buf_len == (uint32_t) -1); 3750 3751 spdk_put_io_channel(ioch); 3752 spdk_bdev_close(desc); 3753 free_bdev(bdev); 3754 spdk_bdev_finish(bdev_fini_cb, NULL); 3755 poll_threads(); 3756 } 3757 3758 static void 3759 bdev_open_while_hotremove(void) 3760 { 3761 struct spdk_bdev *bdev; 3762 struct spdk_bdev_desc *desc[2] = {}; 3763 int rc; 3764 3765 bdev = allocate_bdev("bdev"); 3766 3767 rc = spdk_bdev_open_ext("bdev", false, bdev_ut_event_cb, NULL, &desc[0]); 3768 CU_ASSERT(rc == 0); 3769 SPDK_CU_ASSERT_FATAL(desc[0] != NULL); 3770 CU_ASSERT(bdev == spdk_bdev_desc_get_bdev(desc[0])); 3771 3772 spdk_bdev_unregister(bdev, NULL, NULL); 3773 3774 rc = spdk_bdev_open_ext("bdev", false, bdev_ut_event_cb, NULL, &desc[1]); 3775 CU_ASSERT(rc == -ENODEV); 3776 SPDK_CU_ASSERT_FATAL(desc[1] == NULL); 3777 3778 spdk_bdev_close(desc[0]); 3779 free_bdev(bdev); 3780 } 3781 3782 static void 3783 bdev_close_while_hotremove(void) 3784 { 3785 struct spdk_bdev *bdev; 3786 struct spdk_bdev_desc *desc = NULL; 3787 int rc = 0; 3788 3789 bdev = allocate_bdev("bdev"); 3790 3791 rc = spdk_bdev_open_ext("bdev", true, bdev_open_cb1, &desc, &desc); 3792 CU_ASSERT_EQUAL(rc, 0); 3793 SPDK_CU_ASSERT_FATAL(desc != NULL); 3794 CU_ASSERT(bdev == spdk_bdev_desc_get_bdev(desc)); 3795 3796 /* Simulate hot-unplug by unregistering bdev */ 3797 g_event_type1 = 0xFF; 3798 g_unregister_arg = NULL; 3799 g_unregister_rc = -1; 3800 spdk_bdev_unregister(bdev, bdev_unregister_cb, (void *)0x12345678); 3801 /* Close device while remove event is in flight */ 3802 spdk_bdev_close(desc); 3803 3804 /* Ensure that unregister callback is delayed */ 3805 CU_ASSERT_EQUAL(g_unregister_arg, NULL); 3806 CU_ASSERT_EQUAL(g_unregister_rc, -1); 3807 3808 poll_threads(); 3809 3810 /* Event callback shall not be issued because device was closed */ 3811 CU_ASSERT_EQUAL(g_event_type1, 0xFF); 3812 /* Unregister callback is issued */ 3813 CU_ASSERT_EQUAL(g_unregister_arg, (void *)0x12345678); 3814 CU_ASSERT_EQUAL(g_unregister_rc, 0); 3815 3816 free_bdev(bdev); 3817 } 3818 3819 static void 3820 bdev_open_ext(void) 3821 { 3822 struct spdk_bdev *bdev; 3823 struct spdk_bdev_desc *desc1 = NULL; 3824 struct spdk_bdev_desc *desc2 = NULL; 3825 int rc = 0; 3826 3827 bdev = allocate_bdev("bdev"); 3828 3829 rc = spdk_bdev_open_ext("bdev", true, NULL, NULL, &desc1); 3830 CU_ASSERT_EQUAL(rc, -EINVAL); 3831 3832 rc = spdk_bdev_open_ext("bdev", true, bdev_open_cb1, &desc1, &desc1); 3833 CU_ASSERT_EQUAL(rc, 0); 3834 3835 rc = spdk_bdev_open_ext("bdev", true, bdev_open_cb2, &desc2, &desc2); 3836 CU_ASSERT_EQUAL(rc, 0); 3837 3838 g_event_type1 = 0xFF; 3839 g_event_type2 = 0xFF; 3840 3841 /* Simulate hot-unplug by unregistering bdev */ 3842 spdk_bdev_unregister(bdev, NULL, NULL); 3843 poll_threads(); 3844 3845 /* Check if correct events have been triggered in event callback fn */ 3846 CU_ASSERT_EQUAL(g_event_type1, SPDK_BDEV_EVENT_REMOVE); 3847 CU_ASSERT_EQUAL(g_event_type2, SPDK_BDEV_EVENT_REMOVE); 3848 3849 free_bdev(bdev); 3850 poll_threads(); 3851 } 3852 3853 struct timeout_io_cb_arg { 3854 struct iovec iov; 3855 uint8_t type; 3856 }; 3857 3858 static int 3859 bdev_channel_count_submitted_io(struct spdk_bdev_channel *ch) 3860 { 3861 struct spdk_bdev_io *bdev_io; 3862 int n = 0; 3863 3864 if (!ch) { 3865 return -1; 3866 } 3867 3868 TAILQ_FOREACH(bdev_io, &ch->io_submitted, internal.ch_link) { 3869 n++; 3870 } 3871 3872 return n; 3873 } 3874 3875 static void 3876 bdev_channel_io_timeout_cb(void *cb_arg, struct spdk_bdev_io *bdev_io) 3877 { 3878 struct timeout_io_cb_arg *ctx = cb_arg; 3879 3880 ctx->type = bdev_io->type; 3881 ctx->iov.iov_base = bdev_io->iov.iov_base; 3882 ctx->iov.iov_len = bdev_io->iov.iov_len; 3883 } 3884 3885 static void 3886 bdev_set_io_timeout(void) 3887 { 3888 struct spdk_bdev *bdev; 3889 struct spdk_bdev_desc *desc = NULL; 3890 struct spdk_io_channel *io_ch = NULL; 3891 struct spdk_bdev_channel *bdev_ch = NULL; 3892 struct timeout_io_cb_arg cb_arg; 3893 3894 spdk_bdev_initialize(bdev_init_cb, NULL); 3895 3896 bdev = allocate_bdev("bdev"); 3897 3898 CU_ASSERT(spdk_bdev_open_ext("bdev", true, bdev_ut_event_cb, NULL, &desc) == 0); 3899 SPDK_CU_ASSERT_FATAL(desc != NULL); 3900 CU_ASSERT(bdev == spdk_bdev_desc_get_bdev(desc)); 3901 3902 io_ch = spdk_bdev_get_io_channel(desc); 3903 CU_ASSERT(io_ch != NULL); 3904 3905 bdev_ch = spdk_io_channel_get_ctx(io_ch); 3906 CU_ASSERT(TAILQ_EMPTY(&bdev_ch->io_submitted)); 3907 3908 /* This is the part1. 3909 * We will check the bdev_ch->io_submitted list 3910 * TO make sure that it can link IOs and only the user submitted IOs 3911 */ 3912 CU_ASSERT(spdk_bdev_read(desc, io_ch, (void *)0x1000, 0, 4096, io_done, NULL) == 0); 3913 CU_ASSERT(bdev_channel_count_submitted_io(bdev_ch) == 1); 3914 CU_ASSERT(spdk_bdev_write(desc, io_ch, (void *)0x2000, 0, 4096, io_done, NULL) == 0); 3915 CU_ASSERT(bdev_channel_count_submitted_io(bdev_ch) == 2); 3916 stub_complete_io(1); 3917 CU_ASSERT(bdev_channel_count_submitted_io(bdev_ch) == 1); 3918 stub_complete_io(1); 3919 CU_ASSERT(bdev_channel_count_submitted_io(bdev_ch) == 0); 3920 3921 /* Split IO */ 3922 bdev->optimal_io_boundary = 16; 3923 bdev->split_on_optimal_io_boundary = true; 3924 3925 /* Now test that a single-vector command is split correctly. 3926 * Offset 14, length 8, payload 0xF000 3927 * Child - Offset 14, length 2, payload 0xF000 3928 * Child - Offset 16, length 6, payload 0xF000 + 2 * 512 3929 * 3930 * Set up the expected values before calling spdk_bdev_read_blocks 3931 */ 3932 CU_ASSERT(spdk_bdev_read_blocks(desc, io_ch, (void *)0xF000, 14, 8, io_done, NULL) == 0); 3933 /* We count all submitted IOs including IO that are generated by splitting. */ 3934 CU_ASSERT(bdev_channel_count_submitted_io(bdev_ch) == 3); 3935 stub_complete_io(1); 3936 CU_ASSERT(bdev_channel_count_submitted_io(bdev_ch) == 2); 3937 stub_complete_io(1); 3938 CU_ASSERT(bdev_channel_count_submitted_io(bdev_ch) == 0); 3939 3940 /* Also include the reset IO */ 3941 CU_ASSERT(spdk_bdev_reset(desc, io_ch, io_done, NULL) == 0); 3942 CU_ASSERT(bdev_channel_count_submitted_io(bdev_ch) == 1); 3943 poll_threads(); 3944 stub_complete_io(1); 3945 poll_threads(); 3946 CU_ASSERT(bdev_channel_count_submitted_io(bdev_ch) == 0); 3947 3948 /* This is part2 3949 * Test the desc timeout poller register 3950 */ 3951 3952 /* Successfully set the timeout */ 3953 CU_ASSERT(spdk_bdev_set_timeout(desc, 30, bdev_channel_io_timeout_cb, &cb_arg) == 0); 3954 CU_ASSERT(desc->io_timeout_poller != NULL); 3955 CU_ASSERT(desc->timeout_in_sec == 30); 3956 CU_ASSERT(desc->cb_fn == bdev_channel_io_timeout_cb); 3957 CU_ASSERT(desc->cb_arg == &cb_arg); 3958 3959 /* Change the timeout limit */ 3960 CU_ASSERT(spdk_bdev_set_timeout(desc, 20, bdev_channel_io_timeout_cb, &cb_arg) == 0); 3961 CU_ASSERT(desc->io_timeout_poller != NULL); 3962 CU_ASSERT(desc->timeout_in_sec == 20); 3963 CU_ASSERT(desc->cb_fn == bdev_channel_io_timeout_cb); 3964 CU_ASSERT(desc->cb_arg == &cb_arg); 3965 3966 /* Disable the timeout */ 3967 CU_ASSERT(spdk_bdev_set_timeout(desc, 0, NULL, NULL) == 0); 3968 CU_ASSERT(desc->io_timeout_poller == NULL); 3969 3970 /* This the part3 3971 * We will test to catch timeout IO and check whether the IO is 3972 * the submitted one. 3973 */ 3974 memset(&cb_arg, 0, sizeof(cb_arg)); 3975 CU_ASSERT(spdk_bdev_set_timeout(desc, 30, bdev_channel_io_timeout_cb, &cb_arg) == 0); 3976 CU_ASSERT(spdk_bdev_write_blocks(desc, io_ch, (void *)0x1000, 0, 1, io_done, NULL) == 0); 3977 3978 /* Don't reach the limit */ 3979 spdk_delay_us(15 * spdk_get_ticks_hz()); 3980 poll_threads(); 3981 CU_ASSERT(cb_arg.type == 0); 3982 CU_ASSERT(cb_arg.iov.iov_base == (void *)0x0); 3983 CU_ASSERT(cb_arg.iov.iov_len == 0); 3984 3985 /* 15 + 15 = 30 reach the limit */ 3986 spdk_delay_us(15 * spdk_get_ticks_hz()); 3987 poll_threads(); 3988 CU_ASSERT(cb_arg.type == SPDK_BDEV_IO_TYPE_WRITE); 3989 CU_ASSERT(cb_arg.iov.iov_base == (void *)0x1000); 3990 CU_ASSERT(cb_arg.iov.iov_len == 1 * bdev->blocklen); 3991 stub_complete_io(1); 3992 3993 /* Use the same split IO above and check the IO */ 3994 memset(&cb_arg, 0, sizeof(cb_arg)); 3995 CU_ASSERT(spdk_bdev_write_blocks(desc, io_ch, (void *)0xF000, 14, 8, io_done, NULL) == 0); 3996 3997 /* The first child complete in time */ 3998 spdk_delay_us(15 * spdk_get_ticks_hz()); 3999 poll_threads(); 4000 stub_complete_io(1); 4001 CU_ASSERT(cb_arg.type == 0); 4002 CU_ASSERT(cb_arg.iov.iov_base == (void *)0x0); 4003 CU_ASSERT(cb_arg.iov.iov_len == 0); 4004 4005 /* The second child reach the limit */ 4006 spdk_delay_us(15 * spdk_get_ticks_hz()); 4007 poll_threads(); 4008 CU_ASSERT(cb_arg.type == SPDK_BDEV_IO_TYPE_WRITE); 4009 CU_ASSERT(cb_arg.iov.iov_base == (void *)0xF000); 4010 CU_ASSERT(cb_arg.iov.iov_len == 8 * bdev->blocklen); 4011 stub_complete_io(1); 4012 4013 /* Also include the reset IO */ 4014 memset(&cb_arg, 0, sizeof(cb_arg)); 4015 CU_ASSERT(spdk_bdev_reset(desc, io_ch, io_done, NULL) == 0); 4016 spdk_delay_us(30 * spdk_get_ticks_hz()); 4017 poll_threads(); 4018 CU_ASSERT(cb_arg.type == SPDK_BDEV_IO_TYPE_RESET); 4019 stub_complete_io(1); 4020 poll_threads(); 4021 4022 spdk_put_io_channel(io_ch); 4023 spdk_bdev_close(desc); 4024 free_bdev(bdev); 4025 spdk_bdev_finish(bdev_fini_cb, NULL); 4026 poll_threads(); 4027 } 4028 4029 static void 4030 lba_range_overlap(void) 4031 { 4032 struct lba_range r1, r2; 4033 4034 r1.offset = 100; 4035 r1.length = 50; 4036 4037 r2.offset = 0; 4038 r2.length = 1; 4039 CU_ASSERT(!bdev_lba_range_overlapped(&r1, &r2)); 4040 4041 r2.offset = 0; 4042 r2.length = 100; 4043 CU_ASSERT(!bdev_lba_range_overlapped(&r1, &r2)); 4044 4045 r2.offset = 0; 4046 r2.length = 110; 4047 CU_ASSERT(bdev_lba_range_overlapped(&r1, &r2)); 4048 4049 r2.offset = 100; 4050 r2.length = 10; 4051 CU_ASSERT(bdev_lba_range_overlapped(&r1, &r2)); 4052 4053 r2.offset = 110; 4054 r2.length = 20; 4055 CU_ASSERT(bdev_lba_range_overlapped(&r1, &r2)); 4056 4057 r2.offset = 140; 4058 r2.length = 150; 4059 CU_ASSERT(bdev_lba_range_overlapped(&r1, &r2)); 4060 4061 r2.offset = 130; 4062 r2.length = 200; 4063 CU_ASSERT(bdev_lba_range_overlapped(&r1, &r2)); 4064 4065 r2.offset = 150; 4066 r2.length = 100; 4067 CU_ASSERT(!bdev_lba_range_overlapped(&r1, &r2)); 4068 4069 r2.offset = 110; 4070 r2.length = 0; 4071 CU_ASSERT(!bdev_lba_range_overlapped(&r1, &r2)); 4072 } 4073 4074 static bool g_lock_lba_range_done; 4075 static bool g_unlock_lba_range_done; 4076 4077 static void 4078 lock_lba_range_done(void *ctx, int status) 4079 { 4080 g_lock_lba_range_done = true; 4081 } 4082 4083 static void 4084 unlock_lba_range_done(void *ctx, int status) 4085 { 4086 g_unlock_lba_range_done = true; 4087 } 4088 4089 static void 4090 lock_lba_range_check_ranges(void) 4091 { 4092 struct spdk_bdev *bdev; 4093 struct spdk_bdev_desc *desc = NULL; 4094 struct spdk_io_channel *io_ch; 4095 struct spdk_bdev_channel *channel; 4096 struct lba_range *range; 4097 int ctx1; 4098 int rc; 4099 4100 spdk_bdev_initialize(bdev_init_cb, NULL); 4101 4102 bdev = allocate_bdev("bdev0"); 4103 4104 rc = spdk_bdev_open_ext("bdev0", true, bdev_ut_event_cb, NULL, &desc); 4105 CU_ASSERT(rc == 0); 4106 CU_ASSERT(desc != NULL); 4107 CU_ASSERT(bdev == spdk_bdev_desc_get_bdev(desc)); 4108 io_ch = spdk_bdev_get_io_channel(desc); 4109 CU_ASSERT(io_ch != NULL); 4110 channel = spdk_io_channel_get_ctx(io_ch); 4111 4112 g_lock_lba_range_done = false; 4113 rc = bdev_lock_lba_range(desc, io_ch, 20, 10, lock_lba_range_done, &ctx1); 4114 CU_ASSERT(rc == 0); 4115 poll_threads(); 4116 4117 CU_ASSERT(g_lock_lba_range_done == true); 4118 range = TAILQ_FIRST(&channel->locked_ranges); 4119 SPDK_CU_ASSERT_FATAL(range != NULL); 4120 CU_ASSERT(range->offset == 20); 4121 CU_ASSERT(range->length == 10); 4122 CU_ASSERT(range->owner_ch == channel); 4123 4124 /* Unlocks must exactly match a lock. */ 4125 g_unlock_lba_range_done = false; 4126 rc = bdev_unlock_lba_range(desc, io_ch, 20, 1, unlock_lba_range_done, &ctx1); 4127 CU_ASSERT(rc == -EINVAL); 4128 CU_ASSERT(g_unlock_lba_range_done == false); 4129 4130 rc = bdev_unlock_lba_range(desc, io_ch, 20, 10, unlock_lba_range_done, &ctx1); 4131 CU_ASSERT(rc == 0); 4132 spdk_delay_us(100); 4133 poll_threads(); 4134 4135 CU_ASSERT(g_unlock_lba_range_done == true); 4136 CU_ASSERT(TAILQ_EMPTY(&channel->locked_ranges)); 4137 4138 spdk_put_io_channel(io_ch); 4139 spdk_bdev_close(desc); 4140 free_bdev(bdev); 4141 spdk_bdev_finish(bdev_fini_cb, NULL); 4142 poll_threads(); 4143 } 4144 4145 static void 4146 lock_lba_range_with_io_outstanding(void) 4147 { 4148 struct spdk_bdev *bdev; 4149 struct spdk_bdev_desc *desc = NULL; 4150 struct spdk_io_channel *io_ch; 4151 struct spdk_bdev_channel *channel; 4152 struct lba_range *range; 4153 char buf[4096]; 4154 int ctx1; 4155 int rc; 4156 4157 spdk_bdev_initialize(bdev_init_cb, NULL); 4158 4159 bdev = allocate_bdev("bdev0"); 4160 4161 rc = spdk_bdev_open_ext("bdev0", true, bdev_ut_event_cb, NULL, &desc); 4162 CU_ASSERT(rc == 0); 4163 CU_ASSERT(desc != NULL); 4164 CU_ASSERT(bdev == spdk_bdev_desc_get_bdev(desc)); 4165 io_ch = spdk_bdev_get_io_channel(desc); 4166 CU_ASSERT(io_ch != NULL); 4167 channel = spdk_io_channel_get_ctx(io_ch); 4168 4169 g_io_done = false; 4170 rc = spdk_bdev_read_blocks(desc, io_ch, buf, 20, 1, io_done, &ctx1); 4171 CU_ASSERT(rc == 0); 4172 4173 g_lock_lba_range_done = false; 4174 rc = bdev_lock_lba_range(desc, io_ch, 20, 10, lock_lba_range_done, &ctx1); 4175 CU_ASSERT(rc == 0); 4176 poll_threads(); 4177 4178 /* The lock should immediately become valid, since there are no outstanding 4179 * write I/O. 4180 */ 4181 CU_ASSERT(g_io_done == false); 4182 CU_ASSERT(g_lock_lba_range_done == true); 4183 range = TAILQ_FIRST(&channel->locked_ranges); 4184 SPDK_CU_ASSERT_FATAL(range != NULL); 4185 CU_ASSERT(range->offset == 20); 4186 CU_ASSERT(range->length == 10); 4187 CU_ASSERT(range->owner_ch == channel); 4188 CU_ASSERT(range->locked_ctx == &ctx1); 4189 4190 rc = bdev_unlock_lba_range(desc, io_ch, 20, 10, lock_lba_range_done, &ctx1); 4191 CU_ASSERT(rc == 0); 4192 stub_complete_io(1); 4193 spdk_delay_us(100); 4194 poll_threads(); 4195 4196 CU_ASSERT(TAILQ_EMPTY(&channel->locked_ranges)); 4197 4198 /* Now try again, but with a write I/O. */ 4199 g_io_done = false; 4200 rc = spdk_bdev_write_blocks(desc, io_ch, buf, 20, 1, io_done, &ctx1); 4201 CU_ASSERT(rc == 0); 4202 4203 g_lock_lba_range_done = false; 4204 rc = bdev_lock_lba_range(desc, io_ch, 20, 10, lock_lba_range_done, &ctx1); 4205 CU_ASSERT(rc == 0); 4206 poll_threads(); 4207 4208 /* The lock should not be fully valid yet, since a write I/O is outstanding. 4209 * But note that the range should be on the channel's locked_list, to make sure no 4210 * new write I/O are started. 4211 */ 4212 CU_ASSERT(g_io_done == false); 4213 CU_ASSERT(g_lock_lba_range_done == false); 4214 range = TAILQ_FIRST(&channel->locked_ranges); 4215 SPDK_CU_ASSERT_FATAL(range != NULL); 4216 CU_ASSERT(range->offset == 20); 4217 CU_ASSERT(range->length == 10); 4218 4219 /* Complete the write I/O. This should make the lock valid (checked by confirming 4220 * our callback was invoked). 4221 */ 4222 stub_complete_io(1); 4223 spdk_delay_us(100); 4224 poll_threads(); 4225 CU_ASSERT(g_io_done == true); 4226 CU_ASSERT(g_lock_lba_range_done == true); 4227 4228 rc = bdev_unlock_lba_range(desc, io_ch, 20, 10, unlock_lba_range_done, &ctx1); 4229 CU_ASSERT(rc == 0); 4230 poll_threads(); 4231 4232 CU_ASSERT(TAILQ_EMPTY(&channel->locked_ranges)); 4233 4234 spdk_put_io_channel(io_ch); 4235 spdk_bdev_close(desc); 4236 free_bdev(bdev); 4237 spdk_bdev_finish(bdev_fini_cb, NULL); 4238 poll_threads(); 4239 } 4240 4241 static void 4242 lock_lba_range_overlapped(void) 4243 { 4244 struct spdk_bdev *bdev; 4245 struct spdk_bdev_desc *desc = NULL; 4246 struct spdk_io_channel *io_ch; 4247 struct spdk_bdev_channel *channel; 4248 struct lba_range *range; 4249 int ctx1; 4250 int rc; 4251 4252 spdk_bdev_initialize(bdev_init_cb, NULL); 4253 4254 bdev = allocate_bdev("bdev0"); 4255 4256 rc = spdk_bdev_open_ext("bdev0", true, bdev_ut_event_cb, NULL, &desc); 4257 CU_ASSERT(rc == 0); 4258 CU_ASSERT(desc != NULL); 4259 CU_ASSERT(bdev == spdk_bdev_desc_get_bdev(desc)); 4260 io_ch = spdk_bdev_get_io_channel(desc); 4261 CU_ASSERT(io_ch != NULL); 4262 channel = spdk_io_channel_get_ctx(io_ch); 4263 4264 /* Lock range 20-29. */ 4265 g_lock_lba_range_done = false; 4266 rc = bdev_lock_lba_range(desc, io_ch, 20, 10, lock_lba_range_done, &ctx1); 4267 CU_ASSERT(rc == 0); 4268 poll_threads(); 4269 4270 CU_ASSERT(g_lock_lba_range_done == true); 4271 range = TAILQ_FIRST(&channel->locked_ranges); 4272 SPDK_CU_ASSERT_FATAL(range != NULL); 4273 CU_ASSERT(range->offset == 20); 4274 CU_ASSERT(range->length == 10); 4275 4276 /* Try to lock range 25-39. It should not lock immediately, since it overlaps with 4277 * 20-29. 4278 */ 4279 g_lock_lba_range_done = false; 4280 rc = bdev_lock_lba_range(desc, io_ch, 25, 15, lock_lba_range_done, &ctx1); 4281 CU_ASSERT(rc == 0); 4282 poll_threads(); 4283 4284 CU_ASSERT(g_lock_lba_range_done == false); 4285 range = TAILQ_FIRST(&bdev->internal.pending_locked_ranges); 4286 SPDK_CU_ASSERT_FATAL(range != NULL); 4287 CU_ASSERT(range->offset == 25); 4288 CU_ASSERT(range->length == 15); 4289 4290 /* Unlock 20-29. This should result in range 25-39 now getting locked since it 4291 * no longer overlaps with an active lock. 4292 */ 4293 g_unlock_lba_range_done = false; 4294 rc = bdev_unlock_lba_range(desc, io_ch, 20, 10, unlock_lba_range_done, &ctx1); 4295 CU_ASSERT(rc == 0); 4296 poll_threads(); 4297 4298 CU_ASSERT(g_unlock_lba_range_done == true); 4299 CU_ASSERT(TAILQ_EMPTY(&bdev->internal.pending_locked_ranges)); 4300 range = TAILQ_FIRST(&channel->locked_ranges); 4301 SPDK_CU_ASSERT_FATAL(range != NULL); 4302 CU_ASSERT(range->offset == 25); 4303 CU_ASSERT(range->length == 15); 4304 4305 /* Lock 40-59. This should immediately lock since it does not overlap with the 4306 * currently active 25-39 lock. 4307 */ 4308 g_lock_lba_range_done = false; 4309 rc = bdev_lock_lba_range(desc, io_ch, 40, 20, lock_lba_range_done, &ctx1); 4310 CU_ASSERT(rc == 0); 4311 poll_threads(); 4312 4313 CU_ASSERT(g_lock_lba_range_done == true); 4314 range = TAILQ_FIRST(&bdev->internal.locked_ranges); 4315 SPDK_CU_ASSERT_FATAL(range != NULL); 4316 range = TAILQ_NEXT(range, tailq); 4317 SPDK_CU_ASSERT_FATAL(range != NULL); 4318 CU_ASSERT(range->offset == 40); 4319 CU_ASSERT(range->length == 20); 4320 4321 /* Try to lock 35-44. Note that this overlaps with both 25-39 and 40-59. */ 4322 g_lock_lba_range_done = false; 4323 rc = bdev_lock_lba_range(desc, io_ch, 35, 10, lock_lba_range_done, &ctx1); 4324 CU_ASSERT(rc == 0); 4325 poll_threads(); 4326 4327 CU_ASSERT(g_lock_lba_range_done == false); 4328 range = TAILQ_FIRST(&bdev->internal.pending_locked_ranges); 4329 SPDK_CU_ASSERT_FATAL(range != NULL); 4330 CU_ASSERT(range->offset == 35); 4331 CU_ASSERT(range->length == 10); 4332 4333 /* Unlock 25-39. Make sure that 35-44 is still in the pending list, since 4334 * the 40-59 lock is still active. 4335 */ 4336 g_unlock_lba_range_done = false; 4337 rc = bdev_unlock_lba_range(desc, io_ch, 25, 15, unlock_lba_range_done, &ctx1); 4338 CU_ASSERT(rc == 0); 4339 poll_threads(); 4340 4341 CU_ASSERT(g_unlock_lba_range_done == true); 4342 CU_ASSERT(g_lock_lba_range_done == false); 4343 range = TAILQ_FIRST(&bdev->internal.pending_locked_ranges); 4344 SPDK_CU_ASSERT_FATAL(range != NULL); 4345 CU_ASSERT(range->offset == 35); 4346 CU_ASSERT(range->length == 10); 4347 4348 /* Unlock 40-59. This should result in 35-44 now getting locked, since there are 4349 * no longer any active overlapping locks. 4350 */ 4351 g_unlock_lba_range_done = false; 4352 rc = bdev_unlock_lba_range(desc, io_ch, 40, 20, unlock_lba_range_done, &ctx1); 4353 CU_ASSERT(rc == 0); 4354 poll_threads(); 4355 4356 CU_ASSERT(g_unlock_lba_range_done == true); 4357 CU_ASSERT(g_lock_lba_range_done == true); 4358 CU_ASSERT(TAILQ_EMPTY(&bdev->internal.pending_locked_ranges)); 4359 range = TAILQ_FIRST(&bdev->internal.locked_ranges); 4360 SPDK_CU_ASSERT_FATAL(range != NULL); 4361 CU_ASSERT(range->offset == 35); 4362 CU_ASSERT(range->length == 10); 4363 4364 /* Finally, unlock 35-44. */ 4365 g_unlock_lba_range_done = false; 4366 rc = bdev_unlock_lba_range(desc, io_ch, 35, 10, unlock_lba_range_done, &ctx1); 4367 CU_ASSERT(rc == 0); 4368 poll_threads(); 4369 4370 CU_ASSERT(g_unlock_lba_range_done == true); 4371 CU_ASSERT(TAILQ_EMPTY(&bdev->internal.locked_ranges)); 4372 4373 spdk_put_io_channel(io_ch); 4374 spdk_bdev_close(desc); 4375 free_bdev(bdev); 4376 spdk_bdev_finish(bdev_fini_cb, NULL); 4377 poll_threads(); 4378 } 4379 4380 static void 4381 abort_done(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg) 4382 { 4383 g_abort_done = true; 4384 g_abort_status = bdev_io->internal.status; 4385 spdk_bdev_free_io(bdev_io); 4386 } 4387 4388 static void 4389 bdev_io_abort(void) 4390 { 4391 struct spdk_bdev *bdev; 4392 struct spdk_bdev_desc *desc = NULL; 4393 struct spdk_io_channel *io_ch; 4394 struct spdk_bdev_channel *channel; 4395 struct spdk_bdev_mgmt_channel *mgmt_ch; 4396 struct spdk_bdev_opts bdev_opts = {}; 4397 struct iovec iov[BDEV_IO_NUM_CHILD_IOV * 2]; 4398 uint64_t io_ctx1 = 0, io_ctx2 = 0, i; 4399 int rc; 4400 4401 spdk_bdev_get_opts(&bdev_opts, sizeof(bdev_opts)); 4402 bdev_opts.bdev_io_pool_size = 7; 4403 bdev_opts.bdev_io_cache_size = 2; 4404 4405 rc = spdk_bdev_set_opts(&bdev_opts); 4406 CU_ASSERT(rc == 0); 4407 spdk_bdev_initialize(bdev_init_cb, NULL); 4408 4409 bdev = allocate_bdev("bdev0"); 4410 4411 rc = spdk_bdev_open_ext("bdev0", true, bdev_ut_event_cb, NULL, &desc); 4412 CU_ASSERT(rc == 0); 4413 CU_ASSERT(desc != NULL); 4414 CU_ASSERT(bdev == spdk_bdev_desc_get_bdev(desc)); 4415 io_ch = spdk_bdev_get_io_channel(desc); 4416 CU_ASSERT(io_ch != NULL); 4417 channel = spdk_io_channel_get_ctx(io_ch); 4418 mgmt_ch = channel->shared_resource->mgmt_ch; 4419 4420 g_abort_done = false; 4421 4422 ut_enable_io_type(SPDK_BDEV_IO_TYPE_ABORT, false); 4423 4424 rc = spdk_bdev_abort(desc, io_ch, &io_ctx1, abort_done, NULL); 4425 CU_ASSERT(rc == -ENOTSUP); 4426 4427 ut_enable_io_type(SPDK_BDEV_IO_TYPE_ABORT, true); 4428 4429 rc = spdk_bdev_abort(desc, io_ch, &io_ctx2, abort_done, NULL); 4430 CU_ASSERT(rc == 0); 4431 CU_ASSERT(g_abort_done == true); 4432 CU_ASSERT(g_abort_status == SPDK_BDEV_IO_STATUS_FAILED); 4433 4434 /* Test the case that the target I/O was successfully aborted. */ 4435 g_io_done = false; 4436 4437 rc = spdk_bdev_read_blocks(desc, io_ch, NULL, 0, 1, io_done, &io_ctx1); 4438 CU_ASSERT(rc == 0); 4439 CU_ASSERT(g_io_done == false); 4440 4441 g_abort_done = false; 4442 g_io_exp_status = SPDK_BDEV_IO_STATUS_SUCCESS; 4443 4444 rc = spdk_bdev_abort(desc, io_ch, &io_ctx1, abort_done, NULL); 4445 CU_ASSERT(rc == 0); 4446 CU_ASSERT(g_io_done == true); 4447 CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_FAILED); 4448 stub_complete_io(1); 4449 CU_ASSERT(g_abort_done == true); 4450 CU_ASSERT(g_abort_status == SPDK_BDEV_IO_STATUS_SUCCESS); 4451 4452 /* Test the case that the target I/O was not aborted because it completed 4453 * in the middle of execution of the abort. 4454 */ 4455 g_io_done = false; 4456 4457 rc = spdk_bdev_read_blocks(desc, io_ch, NULL, 0, 1, io_done, &io_ctx1); 4458 CU_ASSERT(rc == 0); 4459 CU_ASSERT(g_io_done == false); 4460 4461 g_abort_done = false; 4462 g_io_exp_status = SPDK_BDEV_IO_STATUS_FAILED; 4463 4464 rc = spdk_bdev_abort(desc, io_ch, &io_ctx1, abort_done, NULL); 4465 CU_ASSERT(rc == 0); 4466 CU_ASSERT(g_io_done == false); 4467 4468 g_io_exp_status = SPDK_BDEV_IO_STATUS_SUCCESS; 4469 stub_complete_io(1); 4470 CU_ASSERT(g_io_done == true); 4471 CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_SUCCESS); 4472 4473 g_io_exp_status = SPDK_BDEV_IO_STATUS_FAILED; 4474 stub_complete_io(1); 4475 CU_ASSERT(g_abort_done == true); 4476 CU_ASSERT(g_abort_status == SPDK_BDEV_IO_STATUS_SUCCESS); 4477 4478 g_io_exp_status = SPDK_BDEV_IO_STATUS_SUCCESS; 4479 4480 bdev->optimal_io_boundary = 16; 4481 bdev->split_on_optimal_io_boundary = true; 4482 4483 /* Test that a single-vector command which is split is aborted correctly. 4484 * Offset 14, length 8, payload 0xF000 4485 * Child - Offset 14, length 2, payload 0xF000 4486 * Child - Offset 16, length 6, payload 0xF000 + 2 * 512 4487 */ 4488 g_io_done = false; 4489 4490 rc = spdk_bdev_read_blocks(desc, io_ch, (void *)0xF000, 14, 8, io_done, &io_ctx1); 4491 CU_ASSERT(rc == 0); 4492 CU_ASSERT(g_io_done == false); 4493 4494 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 2); 4495 4496 g_io_exp_status = SPDK_BDEV_IO_STATUS_SUCCESS; 4497 4498 rc = spdk_bdev_abort(desc, io_ch, &io_ctx1, abort_done, NULL); 4499 CU_ASSERT(rc == 0); 4500 CU_ASSERT(g_io_done == true); 4501 CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_FAILED); 4502 stub_complete_io(2); 4503 CU_ASSERT(g_abort_done == true); 4504 CU_ASSERT(g_abort_status == SPDK_BDEV_IO_STATUS_SUCCESS); 4505 4506 /* Test that a multi-vector command that needs to be split by strip and then 4507 * needs to be split is aborted correctly. Abort is requested before the second 4508 * child I/O was submitted. The parent I/O should complete with failure without 4509 * submitting the second child I/O. 4510 */ 4511 for (i = 0; i < BDEV_IO_NUM_CHILD_IOV * 2; i++) { 4512 iov[i].iov_base = (void *)((i + 1) * 0x10000); 4513 iov[i].iov_len = 512; 4514 } 4515 4516 bdev->optimal_io_boundary = BDEV_IO_NUM_CHILD_IOV; 4517 g_io_done = false; 4518 rc = spdk_bdev_readv_blocks(desc, io_ch, iov, BDEV_IO_NUM_CHILD_IOV * 2, 0, 4519 BDEV_IO_NUM_CHILD_IOV * 2, io_done, &io_ctx1); 4520 CU_ASSERT(rc == 0); 4521 CU_ASSERT(g_io_done == false); 4522 4523 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 4524 4525 g_io_exp_status = SPDK_BDEV_IO_STATUS_SUCCESS; 4526 4527 rc = spdk_bdev_abort(desc, io_ch, &io_ctx1, abort_done, NULL); 4528 CU_ASSERT(rc == 0); 4529 CU_ASSERT(g_io_done == true); 4530 CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_FAILED); 4531 stub_complete_io(1); 4532 CU_ASSERT(g_abort_done == true); 4533 CU_ASSERT(g_abort_status == SPDK_BDEV_IO_STATUS_SUCCESS); 4534 4535 g_io_exp_status = SPDK_BDEV_IO_STATUS_SUCCESS; 4536 4537 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 4538 4539 bdev->optimal_io_boundary = 16; 4540 g_io_done = false; 4541 4542 /* Test that a ingle-vector command which is split is aborted correctly. 4543 * Differently from the above, the child abort request will be submitted 4544 * sequentially due to the capacity of spdk_bdev_io. 4545 */ 4546 rc = spdk_bdev_read_blocks(desc, io_ch, (void *)0xF000, 14, 50, io_done, &io_ctx1); 4547 CU_ASSERT(rc == 0); 4548 CU_ASSERT(g_io_done == false); 4549 4550 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 4); 4551 4552 g_abort_done = false; 4553 g_io_exp_status = SPDK_BDEV_IO_STATUS_SUCCESS; 4554 4555 rc = spdk_bdev_abort(desc, io_ch, &io_ctx1, abort_done, NULL); 4556 CU_ASSERT(rc == 0); 4557 CU_ASSERT(!TAILQ_EMPTY(&mgmt_ch->io_wait_queue)); 4558 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 4); 4559 4560 stub_complete_io(1); 4561 CU_ASSERT(g_io_done == true); 4562 CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_FAILED); 4563 stub_complete_io(3); 4564 CU_ASSERT(g_abort_done == true); 4565 CU_ASSERT(g_abort_status == SPDK_BDEV_IO_STATUS_SUCCESS); 4566 4567 g_io_exp_status = SPDK_BDEV_IO_STATUS_SUCCESS; 4568 4569 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 4570 4571 spdk_put_io_channel(io_ch); 4572 spdk_bdev_close(desc); 4573 free_bdev(bdev); 4574 spdk_bdev_finish(bdev_fini_cb, NULL); 4575 poll_threads(); 4576 } 4577 4578 static void 4579 bdev_unmap(void) 4580 { 4581 struct spdk_bdev *bdev; 4582 struct spdk_bdev_desc *desc = NULL; 4583 struct spdk_io_channel *ioch; 4584 struct spdk_bdev_channel *bdev_ch; 4585 struct ut_expected_io *expected_io; 4586 struct spdk_bdev_opts bdev_opts = {}; 4587 uint32_t i, num_outstanding; 4588 uint64_t offset, num_blocks, max_unmap_blocks, num_children; 4589 int rc; 4590 4591 spdk_bdev_get_opts(&bdev_opts, sizeof(bdev_opts)); 4592 bdev_opts.bdev_io_pool_size = 512; 4593 bdev_opts.bdev_io_cache_size = 64; 4594 rc = spdk_bdev_set_opts(&bdev_opts); 4595 CU_ASSERT(rc == 0); 4596 4597 spdk_bdev_initialize(bdev_init_cb, NULL); 4598 bdev = allocate_bdev("bdev"); 4599 4600 rc = spdk_bdev_open_ext("bdev", true, bdev_ut_event_cb, NULL, &desc); 4601 CU_ASSERT_EQUAL(rc, 0); 4602 SPDK_CU_ASSERT_FATAL(desc != NULL); 4603 CU_ASSERT(bdev == spdk_bdev_desc_get_bdev(desc)); 4604 ioch = spdk_bdev_get_io_channel(desc); 4605 SPDK_CU_ASSERT_FATAL(ioch != NULL); 4606 bdev_ch = spdk_io_channel_get_ctx(ioch); 4607 CU_ASSERT(TAILQ_EMPTY(&bdev_ch->io_submitted)); 4608 4609 fn_table.submit_request = stub_submit_request; 4610 g_io_exp_status = SPDK_BDEV_IO_STATUS_SUCCESS; 4611 4612 /* Case 1: First test the request won't be split */ 4613 num_blocks = 32; 4614 4615 g_io_done = false; 4616 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_UNMAP, 0, num_blocks, 0); 4617 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 4618 rc = spdk_bdev_unmap_blocks(desc, ioch, 0, num_blocks, io_done, NULL); 4619 CU_ASSERT_EQUAL(rc, 0); 4620 CU_ASSERT(g_io_done == false); 4621 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 4622 stub_complete_io(1); 4623 CU_ASSERT(g_io_done == true); 4624 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 4625 4626 /* Case 2: Test the split with 2 children requests */ 4627 bdev->max_unmap = 8; 4628 bdev->max_unmap_segments = 2; 4629 max_unmap_blocks = bdev->max_unmap * bdev->max_unmap_segments; 4630 num_blocks = max_unmap_blocks * 2; 4631 offset = 0; 4632 4633 g_io_done = false; 4634 for (i = 0; i < 2; i++) { 4635 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_UNMAP, offset, max_unmap_blocks, 0); 4636 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 4637 offset += max_unmap_blocks; 4638 } 4639 4640 rc = spdk_bdev_unmap_blocks(desc, ioch, 0, num_blocks, io_done, NULL); 4641 CU_ASSERT_EQUAL(rc, 0); 4642 CU_ASSERT(g_io_done == false); 4643 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 2); 4644 stub_complete_io(2); 4645 CU_ASSERT(g_io_done == true); 4646 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 4647 4648 /* Case 3: Test the split with 15 children requests, will finish 8 requests first */ 4649 num_children = 15; 4650 num_blocks = max_unmap_blocks * num_children; 4651 g_io_done = false; 4652 offset = 0; 4653 for (i = 0; i < num_children; i++) { 4654 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_UNMAP, offset, max_unmap_blocks, 0); 4655 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 4656 offset += max_unmap_blocks; 4657 } 4658 4659 rc = spdk_bdev_unmap_blocks(desc, ioch, 0, num_blocks, io_done, NULL); 4660 CU_ASSERT_EQUAL(rc, 0); 4661 CU_ASSERT(g_io_done == false); 4662 4663 while (num_children > 0) { 4664 num_outstanding = spdk_min(num_children, SPDK_BDEV_MAX_CHILDREN_UNMAP_WRITE_ZEROES_REQS); 4665 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == num_outstanding); 4666 stub_complete_io(num_outstanding); 4667 num_children -= num_outstanding; 4668 } 4669 CU_ASSERT(g_io_done == true); 4670 4671 spdk_put_io_channel(ioch); 4672 spdk_bdev_close(desc); 4673 free_bdev(bdev); 4674 spdk_bdev_finish(bdev_fini_cb, NULL); 4675 poll_threads(); 4676 } 4677 4678 static void 4679 bdev_write_zeroes_split_test(void) 4680 { 4681 struct spdk_bdev *bdev; 4682 struct spdk_bdev_desc *desc = NULL; 4683 struct spdk_io_channel *ioch; 4684 struct spdk_bdev_channel *bdev_ch; 4685 struct ut_expected_io *expected_io; 4686 struct spdk_bdev_opts bdev_opts = {}; 4687 uint32_t i, num_outstanding; 4688 uint64_t offset, num_blocks, max_write_zeroes_blocks, num_children; 4689 int rc; 4690 4691 spdk_bdev_get_opts(&bdev_opts, sizeof(bdev_opts)); 4692 bdev_opts.bdev_io_pool_size = 512; 4693 bdev_opts.bdev_io_cache_size = 64; 4694 rc = spdk_bdev_set_opts(&bdev_opts); 4695 CU_ASSERT(rc == 0); 4696 4697 spdk_bdev_initialize(bdev_init_cb, NULL); 4698 bdev = allocate_bdev("bdev"); 4699 4700 rc = spdk_bdev_open_ext("bdev", true, bdev_ut_event_cb, NULL, &desc); 4701 CU_ASSERT_EQUAL(rc, 0); 4702 SPDK_CU_ASSERT_FATAL(desc != NULL); 4703 CU_ASSERT(bdev == spdk_bdev_desc_get_bdev(desc)); 4704 ioch = spdk_bdev_get_io_channel(desc); 4705 SPDK_CU_ASSERT_FATAL(ioch != NULL); 4706 bdev_ch = spdk_io_channel_get_ctx(ioch); 4707 CU_ASSERT(TAILQ_EMPTY(&bdev_ch->io_submitted)); 4708 4709 fn_table.submit_request = stub_submit_request; 4710 g_io_exp_status = SPDK_BDEV_IO_STATUS_SUCCESS; 4711 4712 /* Case 1: First test the request won't be split */ 4713 num_blocks = 32; 4714 4715 g_io_done = false; 4716 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE_ZEROES, 0, num_blocks, 0); 4717 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 4718 rc = spdk_bdev_write_zeroes_blocks(desc, ioch, 0, num_blocks, io_done, NULL); 4719 CU_ASSERT_EQUAL(rc, 0); 4720 CU_ASSERT(g_io_done == false); 4721 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 4722 stub_complete_io(1); 4723 CU_ASSERT(g_io_done == true); 4724 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 4725 4726 /* Case 2: Test the split with 2 children requests */ 4727 max_write_zeroes_blocks = 8; 4728 bdev->max_write_zeroes = max_write_zeroes_blocks; 4729 num_blocks = max_write_zeroes_blocks * 2; 4730 offset = 0; 4731 4732 g_io_done = false; 4733 for (i = 0; i < 2; i++) { 4734 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE_ZEROES, offset, max_write_zeroes_blocks, 4735 0); 4736 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 4737 offset += max_write_zeroes_blocks; 4738 } 4739 4740 rc = spdk_bdev_write_zeroes_blocks(desc, ioch, 0, num_blocks, io_done, NULL); 4741 CU_ASSERT_EQUAL(rc, 0); 4742 CU_ASSERT(g_io_done == false); 4743 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 2); 4744 stub_complete_io(2); 4745 CU_ASSERT(g_io_done == true); 4746 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 4747 4748 /* Case 3: Test the split with 15 children requests, will finish 8 requests first */ 4749 num_children = 15; 4750 num_blocks = max_write_zeroes_blocks * num_children; 4751 g_io_done = false; 4752 offset = 0; 4753 for (i = 0; i < num_children; i++) { 4754 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE_ZEROES, offset, max_write_zeroes_blocks, 4755 0); 4756 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 4757 offset += max_write_zeroes_blocks; 4758 } 4759 4760 rc = spdk_bdev_write_zeroes_blocks(desc, ioch, 0, num_blocks, io_done, NULL); 4761 CU_ASSERT_EQUAL(rc, 0); 4762 CU_ASSERT(g_io_done == false); 4763 4764 while (num_children > 0) { 4765 num_outstanding = spdk_min(num_children, SPDK_BDEV_MAX_CHILDREN_UNMAP_WRITE_ZEROES_REQS); 4766 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == num_outstanding); 4767 stub_complete_io(num_outstanding); 4768 num_children -= num_outstanding; 4769 } 4770 CU_ASSERT(g_io_done == true); 4771 4772 spdk_put_io_channel(ioch); 4773 spdk_bdev_close(desc); 4774 free_bdev(bdev); 4775 spdk_bdev_finish(bdev_fini_cb, NULL); 4776 poll_threads(); 4777 } 4778 4779 static void 4780 bdev_set_options_test(void) 4781 { 4782 struct spdk_bdev_opts bdev_opts = {}; 4783 int rc; 4784 4785 /* Case1: Do not set opts_size */ 4786 rc = spdk_bdev_set_opts(&bdev_opts); 4787 CU_ASSERT(rc == -1); 4788 4789 spdk_bdev_get_opts(&bdev_opts, sizeof(bdev_opts)); 4790 bdev_opts.bdev_io_pool_size = 4; 4791 bdev_opts.bdev_io_cache_size = 2; 4792 bdev_opts.small_buf_pool_size = 4; 4793 4794 /* Case 2: Do not set valid small_buf_pool_size and large_buf_pool_size */ 4795 rc = spdk_bdev_set_opts(&bdev_opts); 4796 CU_ASSERT(rc == -1); 4797 4798 /* Case 3: Do not set valid large_buf_pool_size */ 4799 bdev_opts.small_buf_pool_size = BUF_SMALL_POOL_SIZE; 4800 bdev_opts.large_buf_pool_size = BUF_LARGE_POOL_SIZE - 1; 4801 rc = spdk_bdev_set_opts(&bdev_opts); 4802 CU_ASSERT(rc == -1); 4803 4804 /* Case4: set valid large buf_pool_size */ 4805 bdev_opts.large_buf_pool_size = BUF_LARGE_POOL_SIZE; 4806 rc = spdk_bdev_set_opts(&bdev_opts); 4807 CU_ASSERT(rc == 0); 4808 4809 /* Case5: Set different valid value for small and large buf pool */ 4810 bdev_opts.large_buf_pool_size = BUF_SMALL_POOL_SIZE + 3; 4811 bdev_opts.large_buf_pool_size = BUF_LARGE_POOL_SIZE + 3; 4812 rc = spdk_bdev_set_opts(&bdev_opts); 4813 CU_ASSERT(rc == 0); 4814 } 4815 4816 static uint64_t 4817 get_ns_time(void) 4818 { 4819 int rc; 4820 struct timespec ts; 4821 4822 rc = clock_gettime(CLOCK_MONOTONIC, &ts); 4823 CU_ASSERT(rc == 0); 4824 return ts.tv_sec * 1000 * 1000 * 1000 + ts.tv_nsec; 4825 } 4826 4827 static int 4828 rb_tree_get_height(struct spdk_bdev_name *bdev_name) 4829 { 4830 int h1, h2; 4831 4832 if (bdev_name == NULL) { 4833 return -1; 4834 } else { 4835 h1 = rb_tree_get_height(RB_LEFT(bdev_name, node)); 4836 h2 = rb_tree_get_height(RB_RIGHT(bdev_name, node)); 4837 4838 return spdk_max(h1, h2) + 1; 4839 } 4840 } 4841 4842 static void 4843 bdev_multi_allocation(void) 4844 { 4845 const int max_bdev_num = 1024 * 16; 4846 char name[max_bdev_num][16]; 4847 char noexist_name[] = "invalid_bdev"; 4848 struct spdk_bdev *bdev[max_bdev_num]; 4849 int i, j; 4850 uint64_t last_time; 4851 int bdev_num; 4852 int height; 4853 4854 for (j = 0; j < max_bdev_num; j++) { 4855 snprintf(name[j], sizeof(name[j]), "bdev%d", j); 4856 } 4857 4858 for (i = 0; i < 16; i++) { 4859 last_time = get_ns_time(); 4860 bdev_num = 1024 * (i + 1); 4861 for (j = 0; j < bdev_num; j++) { 4862 bdev[j] = allocate_bdev(name[j]); 4863 height = rb_tree_get_height(&bdev[j]->internal.bdev_name); 4864 CU_ASSERT(height <= (int)(spdk_u32log2(2 * j + 2))); 4865 } 4866 SPDK_NOTICELOG("alloc bdev num %d takes %" PRIu64 " ms\n", bdev_num, 4867 (get_ns_time() - last_time) / 1000 / 1000); 4868 for (j = 0; j < bdev_num; j++) { 4869 CU_ASSERT(spdk_bdev_get_by_name(name[j]) != NULL); 4870 } 4871 CU_ASSERT(spdk_bdev_get_by_name(noexist_name) == NULL); 4872 4873 for (j = 0; j < bdev_num; j++) { 4874 free_bdev(bdev[j]); 4875 } 4876 for (j = 0; j < bdev_num; j++) { 4877 CU_ASSERT(spdk_bdev_get_by_name(name[j]) == NULL); 4878 } 4879 } 4880 } 4881 4882 static struct spdk_memory_domain *g_bdev_memory_domain = (struct spdk_memory_domain *) 0xf00df00d; 4883 4884 static int 4885 test_bdev_get_supported_dma_device_types_op(void *ctx, struct spdk_memory_domain **domains, 4886 int array_size) 4887 { 4888 if (array_size > 0 && domains) { 4889 domains[0] = g_bdev_memory_domain; 4890 } 4891 4892 return 1; 4893 } 4894 4895 static void 4896 bdev_get_memory_domains(void) 4897 { 4898 struct spdk_bdev_fn_table fn_table = { 4899 .get_memory_domains = test_bdev_get_supported_dma_device_types_op 4900 }; 4901 struct spdk_bdev bdev = { .fn_table = &fn_table }; 4902 struct spdk_memory_domain *domains[2] = {}; 4903 int rc; 4904 4905 /* bdev is NULL */ 4906 rc = spdk_bdev_get_memory_domains(NULL, domains, 2); 4907 CU_ASSERT(rc == -EINVAL); 4908 4909 /* domains is NULL */ 4910 rc = spdk_bdev_get_memory_domains(&bdev, NULL, 2); 4911 CU_ASSERT(rc == 1); 4912 4913 /* array size is 0 */ 4914 rc = spdk_bdev_get_memory_domains(&bdev, domains, 0); 4915 CU_ASSERT(rc == 1); 4916 4917 /* get_supported_dma_device_types op is set */ 4918 rc = spdk_bdev_get_memory_domains(&bdev, domains, 2); 4919 CU_ASSERT(rc == 1); 4920 CU_ASSERT(domains[0] == g_bdev_memory_domain); 4921 4922 /* get_supported_dma_device_types op is not set */ 4923 fn_table.get_memory_domains = NULL; 4924 rc = spdk_bdev_get_memory_domains(&bdev, domains, 2); 4925 CU_ASSERT(rc == 0); 4926 } 4927 4928 static void 4929 bdev_writev_readv_ext(void) 4930 { 4931 struct spdk_bdev *bdev; 4932 struct spdk_bdev_desc *desc = NULL; 4933 struct spdk_io_channel *io_ch; 4934 char io_buf[512]; 4935 struct iovec iov = { .iov_base = io_buf, .iov_len = 512 }; 4936 struct ut_expected_io *expected_io; 4937 struct spdk_bdev_ext_io_opts ext_io_opts = { 4938 .metadata = (void *)0xFF000000, 4939 .size = sizeof(ext_io_opts) 4940 }; 4941 int rc; 4942 4943 spdk_bdev_initialize(bdev_init_cb, NULL); 4944 4945 bdev = allocate_bdev("bdev0"); 4946 bdev->md_interleave = false; 4947 bdev->md_len = 8; 4948 4949 rc = spdk_bdev_open_ext("bdev0", true, bdev_ut_event_cb, NULL, &desc); 4950 CU_ASSERT(rc == 0); 4951 SPDK_CU_ASSERT_FATAL(desc != NULL); 4952 CU_ASSERT(bdev == spdk_bdev_desc_get_bdev(desc)); 4953 io_ch = spdk_bdev_get_io_channel(desc); 4954 CU_ASSERT(io_ch != NULL); 4955 4956 /* Test 1, Simple test */ 4957 g_io_done = false; 4958 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 32, 14, 1); 4959 expected_io->md_buf = ext_io_opts.metadata; 4960 expected_io->ext_io_opts = &ext_io_opts; 4961 ut_expected_io_set_iov(expected_io, 0, iov.iov_base, iov.iov_len); 4962 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 4963 4964 rc = spdk_bdev_readv_blocks_ext(desc, io_ch, &iov, 1, 32, 14, io_done, NULL, &ext_io_opts); 4965 4966 CU_ASSERT(rc == 0); 4967 CU_ASSERT(g_io_done == false); 4968 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 4969 stub_complete_io(1); 4970 CU_ASSERT(g_io_done == true); 4971 4972 g_io_done = false; 4973 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 32, 14, 1); 4974 expected_io->md_buf = ext_io_opts.metadata; 4975 expected_io->ext_io_opts = &ext_io_opts; 4976 ut_expected_io_set_iov(expected_io, 0, iov.iov_base, iov.iov_len); 4977 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 4978 4979 rc = spdk_bdev_writev_blocks_ext(desc, io_ch, &iov, 1, 32, 14, io_done, NULL, &ext_io_opts); 4980 4981 CU_ASSERT(rc == 0); 4982 CU_ASSERT(g_io_done == false); 4983 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 4984 stub_complete_io(1); 4985 CU_ASSERT(g_io_done == true); 4986 4987 /* Test 2, invalid ext_opts size */ 4988 ext_io_opts.size = 0; 4989 rc = spdk_bdev_readv_blocks_ext(desc, io_ch, &iov, 1, 32, 14, io_done, NULL, &ext_io_opts); 4990 CU_ASSERT(rc != 0); 4991 rc = spdk_bdev_writev_blocks_ext(desc, io_ch, &iov, 1, 32, 14, io_done, NULL, &ext_io_opts); 4992 CU_ASSERT(rc != 0); 4993 4994 ext_io_opts.size = sizeof(ext_io_opts) * 2; 4995 rc = spdk_bdev_readv_blocks_ext(desc, io_ch, &iov, 1, 32, 14, io_done, NULL, &ext_io_opts); 4996 CU_ASSERT(rc != 0); 4997 rc = spdk_bdev_writev_blocks_ext(desc, io_ch, &iov, 1, 32, 14, io_done, NULL, &ext_io_opts); 4998 CU_ASSERT(rc != 0); 4999 5000 /* Test 3, Check that IO request with ext_opts and metadata is split correctly 5001 * Offset 14, length 8, payload 0xF000 5002 * Child - Offset 14, length 2, payload 0xF000 5003 * Child - Offset 16, length 6, payload 0xF000 + 2 * 512 5004 */ 5005 bdev->optimal_io_boundary = 16; 5006 bdev->split_on_optimal_io_boundary = true; 5007 bdev->md_interleave = false; 5008 bdev->md_len = 8; 5009 5010 iov.iov_base = (void *)0xF000; 5011 iov.iov_len = 4096; 5012 memset(&ext_io_opts, 0, sizeof(ext_io_opts)); 5013 ext_io_opts.metadata = (void *)0xFF000000; 5014 ext_io_opts.size = sizeof(ext_io_opts); 5015 g_io_done = false; 5016 5017 /* read */ 5018 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 14, 2, 1); 5019 expected_io->md_buf = ext_io_opts.metadata; 5020 ut_expected_io_set_iov(expected_io, 0, (void *)0xF000, 2 * 512); 5021 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 5022 5023 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 16, 6, 1); 5024 expected_io->md_buf = ext_io_opts.metadata + 2 * 8; 5025 ut_expected_io_set_iov(expected_io, 0, (void *)(0xF000 + 2 * 512), 6 * 512); 5026 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 5027 5028 rc = spdk_bdev_readv_blocks_ext(desc, io_ch, &iov, 1, 14, 8, io_done, NULL, &ext_io_opts); 5029 CU_ASSERT(rc == 0); 5030 CU_ASSERT(g_io_done == false); 5031 5032 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 2); 5033 stub_complete_io(2); 5034 CU_ASSERT(g_io_done == true); 5035 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 5036 5037 /* write */ 5038 g_io_done = false; 5039 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 14, 2, 1); 5040 expected_io->md_buf = ext_io_opts.metadata; 5041 ut_expected_io_set_iov(expected_io, 0, (void *)0xF000, 2 * 512); 5042 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 5043 5044 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 16, 6, 1); 5045 expected_io->md_buf = ext_io_opts.metadata + 2 * 8; 5046 ut_expected_io_set_iov(expected_io, 0, (void *)(0xF000 + 2 * 512), 6 * 512); 5047 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 5048 5049 rc = spdk_bdev_writev_blocks_ext(desc, io_ch, &iov, 1, 14, 8, io_done, NULL, &ext_io_opts); 5050 CU_ASSERT(rc == 0); 5051 CU_ASSERT(g_io_done == false); 5052 5053 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 2); 5054 stub_complete_io(2); 5055 CU_ASSERT(g_io_done == true); 5056 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 5057 5058 /* ext_opts contains metadata but ext_opts::size doesn't cover metadata pointer. 5059 * Check that IO request with ext_opts and metadata is split correctly - metadata pointer is not copied, so split 5060 * requests do not have metadata 5061 * Offset 14, length 8, payload 0xF000 5062 * Child - Offset 14, length 2, payload 0xF000 5063 * Child - Offset 16, length 6, payload 0xF000 + 2 * 512 5064 */ 5065 iov.iov_base = (void *)0xF000; 5066 iov.iov_len = 4096; 5067 memset(&ext_io_opts, 0, sizeof(ext_io_opts)); 5068 ext_io_opts.metadata = (void *)0xFF000000; 5069 ext_io_opts.size = offsetof(struct spdk_bdev_ext_io_opts, metadata);; 5070 g_io_done = false; 5071 5072 /* read */ 5073 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 14, 2, 1); 5074 /* Split request must not contain metadata pointer */ 5075 expected_io->md_buf = NULL; 5076 ut_expected_io_set_iov(expected_io, 0, (void *)0xF000, 2 * 512); 5077 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 5078 5079 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 16, 6, 1); 5080 expected_io->md_buf = NULL; 5081 ut_expected_io_set_iov(expected_io, 0, (void *)(0xF000 + 2 * 512), 6 * 512); 5082 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 5083 5084 rc = spdk_bdev_readv_blocks_ext(desc, io_ch, &iov, 1, 14, 8, io_done, NULL, &ext_io_opts); 5085 CU_ASSERT(rc == 0); 5086 CU_ASSERT(g_io_done == false); 5087 5088 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 2); 5089 stub_complete_io(2); 5090 CU_ASSERT(g_io_done == true); 5091 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 5092 5093 /* write */ 5094 g_io_done = false; 5095 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 14, 2, 1); 5096 expected_io->md_buf = NULL; 5097 ut_expected_io_set_iov(expected_io, 0, (void *)0xF000, 2 * 512); 5098 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 5099 5100 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 16, 6, 1); 5101 /* Split request must not contain metadata pointer */ 5102 expected_io->md_buf = NULL; 5103 ut_expected_io_set_iov(expected_io, 0, (void *)(0xF000 + 2 * 512), 6 * 512); 5104 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 5105 5106 rc = spdk_bdev_writev_blocks_ext(desc, io_ch, &iov, 1, 14, 8, io_done, NULL, &ext_io_opts); 5107 CU_ASSERT(rc == 0); 5108 CU_ASSERT(g_io_done == false); 5109 5110 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 2); 5111 stub_complete_io(2); 5112 CU_ASSERT(g_io_done == true); 5113 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 5114 5115 /* Test 4, Verify data pull/push 5116 * bdev doens't support memory domains, so buffers from bdev memory pool will be used */ 5117 ext_io_opts.memory_domain = (struct spdk_memory_domain *)0xdeadbeef; 5118 5119 g_io_done = false; 5120 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 32, 14, 1); 5121 ut_expected_io_set_iov(expected_io, 0, iov.iov_base, iov.iov_len); 5122 expected_io->ext_io_opts = &ext_io_opts; 5123 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 5124 5125 rc = spdk_bdev_readv_blocks_ext(desc, io_ch, &iov, 1, 32, 14, io_done, NULL, &ext_io_opts); 5126 5127 CU_ASSERT(rc == 0); 5128 CU_ASSERT(g_io_done == false); 5129 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 5130 stub_complete_io(1); 5131 CU_ASSERT(g_memory_domain_push_data_called == true); 5132 CU_ASSERT(g_io_done == true); 5133 5134 g_io_done = false; 5135 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 32, 14, 1); 5136 ut_expected_io_set_iov(expected_io, 0, iov.iov_base, iov.iov_len); 5137 expected_io->ext_io_opts = &ext_io_opts; 5138 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 5139 5140 rc = spdk_bdev_writev_blocks_ext(desc, io_ch, &iov, 1, 32, 14, io_done, NULL, &ext_io_opts); 5141 5142 CU_ASSERT(rc == 0); 5143 CU_ASSERT(g_memory_domain_pull_data_called == true); 5144 CU_ASSERT(g_io_done == false); 5145 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 5146 stub_complete_io(1); 5147 CU_ASSERT(g_io_done == true); 5148 5149 spdk_put_io_channel(io_ch); 5150 spdk_bdev_close(desc); 5151 free_bdev(bdev); 5152 spdk_bdev_finish(bdev_fini_cb, NULL); 5153 poll_threads(); 5154 } 5155 5156 static void 5157 bdev_register_uuid_alias(void) 5158 { 5159 struct spdk_bdev *bdev, *second; 5160 char uuid[SPDK_UUID_STRING_LEN]; 5161 int rc; 5162 5163 spdk_bdev_initialize(bdev_init_cb, NULL); 5164 bdev = allocate_bdev("bdev0"); 5165 5166 /* Make sure an UUID was generated */ 5167 CU_ASSERT_FALSE(spdk_mem_all_zero(&bdev->uuid, sizeof(bdev->uuid))); 5168 5169 /* Check that an UUID alias was registered */ 5170 spdk_uuid_fmt_lower(uuid, sizeof(uuid), &bdev->uuid); 5171 CU_ASSERT_EQUAL(spdk_bdev_get_by_name(uuid), bdev); 5172 5173 /* Unregister the bdev */ 5174 spdk_bdev_unregister(bdev, NULL, NULL); 5175 poll_threads(); 5176 CU_ASSERT_PTR_NULL(spdk_bdev_get_by_name(uuid)); 5177 5178 /* Check the same, but this time register the bdev with non-zero UUID */ 5179 rc = spdk_bdev_register(bdev); 5180 CU_ASSERT_EQUAL(rc, 0); 5181 CU_ASSERT_EQUAL(spdk_bdev_get_by_name(uuid), bdev); 5182 5183 /* Unregister the bdev */ 5184 spdk_bdev_unregister(bdev, NULL, NULL); 5185 poll_threads(); 5186 CU_ASSERT_PTR_NULL(spdk_bdev_get_by_name(uuid)); 5187 5188 /* Regiser the bdev using UUID as the name */ 5189 bdev->name = uuid; 5190 rc = spdk_bdev_register(bdev); 5191 CU_ASSERT_EQUAL(rc, 0); 5192 CU_ASSERT_EQUAL(spdk_bdev_get_by_name(uuid), bdev); 5193 5194 /* Unregister the bdev */ 5195 spdk_bdev_unregister(bdev, NULL, NULL); 5196 poll_threads(); 5197 CU_ASSERT_PTR_NULL(spdk_bdev_get_by_name(uuid)); 5198 5199 /* Check that it's not possible to register two bdevs with the same UUIDs */ 5200 bdev->name = "bdev0"; 5201 second = allocate_bdev("bdev1"); 5202 spdk_uuid_copy(&bdev->uuid, &second->uuid); 5203 rc = spdk_bdev_register(bdev); 5204 CU_ASSERT_EQUAL(rc, -EEXIST); 5205 5206 /* Regenerate the UUID and re-check */ 5207 spdk_uuid_generate(&bdev->uuid); 5208 rc = spdk_bdev_register(bdev); 5209 CU_ASSERT_EQUAL(rc, 0); 5210 5211 /* And check that both bdevs can be retrieved through their UUIDs */ 5212 spdk_uuid_fmt_lower(uuid, sizeof(uuid), &bdev->uuid); 5213 CU_ASSERT_EQUAL(spdk_bdev_get_by_name(uuid), bdev); 5214 spdk_uuid_fmt_lower(uuid, sizeof(uuid), &second->uuid); 5215 CU_ASSERT_EQUAL(spdk_bdev_get_by_name(uuid), second); 5216 5217 free_bdev(second); 5218 free_bdev(bdev); 5219 spdk_bdev_finish(bdev_fini_cb, NULL); 5220 poll_threads(); 5221 } 5222 5223 static void 5224 bdev_unregister_by_name(void) 5225 { 5226 struct spdk_bdev *bdev; 5227 int rc; 5228 5229 bdev = allocate_bdev("bdev"); 5230 5231 g_event_type1 = 0xFF; 5232 g_unregister_arg = NULL; 5233 g_unregister_rc = -1; 5234 5235 rc = spdk_bdev_unregister_by_name("bdev1", &bdev_ut_if, bdev_unregister_cb, (void *)0x12345678); 5236 CU_ASSERT(rc == -ENODEV); 5237 5238 rc = spdk_bdev_unregister_by_name("bdev", &vbdev_ut_if, bdev_unregister_cb, (void *)0x12345678); 5239 CU_ASSERT(rc == -ENODEV); 5240 5241 rc = spdk_bdev_unregister_by_name("bdev", &bdev_ut_if, bdev_unregister_cb, (void *)0x12345678); 5242 CU_ASSERT(rc == 0); 5243 5244 /* Check that unregister callback is delayed */ 5245 CU_ASSERT(g_unregister_arg == NULL); 5246 CU_ASSERT(g_unregister_rc == -1); 5247 5248 poll_threads(); 5249 5250 /* Event callback shall not be issued because device was closed */ 5251 CU_ASSERT(g_event_type1 == 0xFF); 5252 /* Unregister callback is issued */ 5253 CU_ASSERT(g_unregister_arg == (void *)0x12345678); 5254 CU_ASSERT(g_unregister_rc == 0); 5255 5256 free_bdev(bdev); 5257 } 5258 5259 int 5260 main(int argc, char **argv) 5261 { 5262 CU_pSuite suite = NULL; 5263 unsigned int num_failures; 5264 5265 CU_set_error_action(CUEA_ABORT); 5266 CU_initialize_registry(); 5267 5268 suite = CU_add_suite("bdev", null_init, null_clean); 5269 5270 CU_ADD_TEST(suite, bytes_to_blocks_test); 5271 CU_ADD_TEST(suite, num_blocks_test); 5272 CU_ADD_TEST(suite, io_valid_test); 5273 CU_ADD_TEST(suite, open_write_test); 5274 CU_ADD_TEST(suite, claim_test); 5275 CU_ADD_TEST(suite, alias_add_del_test); 5276 CU_ADD_TEST(suite, get_device_stat_test); 5277 CU_ADD_TEST(suite, bdev_io_types_test); 5278 CU_ADD_TEST(suite, bdev_io_wait_test); 5279 CU_ADD_TEST(suite, bdev_io_spans_split_test); 5280 CU_ADD_TEST(suite, bdev_io_boundary_split_test); 5281 CU_ADD_TEST(suite, bdev_io_max_size_and_segment_split_test); 5282 CU_ADD_TEST(suite, bdev_io_mix_split_test); 5283 CU_ADD_TEST(suite, bdev_io_split_with_io_wait); 5284 CU_ADD_TEST(suite, bdev_io_alignment_with_boundary); 5285 CU_ADD_TEST(suite, bdev_io_alignment); 5286 CU_ADD_TEST(suite, bdev_histograms); 5287 CU_ADD_TEST(suite, bdev_write_zeroes); 5288 CU_ADD_TEST(suite, bdev_compare_and_write); 5289 CU_ADD_TEST(suite, bdev_compare); 5290 CU_ADD_TEST(suite, bdev_zcopy_write); 5291 CU_ADD_TEST(suite, bdev_zcopy_read); 5292 CU_ADD_TEST(suite, bdev_open_while_hotremove); 5293 CU_ADD_TEST(suite, bdev_close_while_hotremove); 5294 CU_ADD_TEST(suite, bdev_open_ext); 5295 CU_ADD_TEST(suite, bdev_set_io_timeout); 5296 CU_ADD_TEST(suite, lba_range_overlap); 5297 CU_ADD_TEST(suite, lock_lba_range_check_ranges); 5298 CU_ADD_TEST(suite, lock_lba_range_with_io_outstanding); 5299 CU_ADD_TEST(suite, lock_lba_range_overlapped); 5300 CU_ADD_TEST(suite, bdev_io_abort); 5301 CU_ADD_TEST(suite, bdev_unmap); 5302 CU_ADD_TEST(suite, bdev_write_zeroes_split_test); 5303 CU_ADD_TEST(suite, bdev_set_options_test); 5304 CU_ADD_TEST(suite, bdev_multi_allocation); 5305 CU_ADD_TEST(suite, bdev_get_memory_domains); 5306 CU_ADD_TEST(suite, bdev_writev_readv_ext); 5307 CU_ADD_TEST(suite, bdev_register_uuid_alias); 5308 CU_ADD_TEST(suite, bdev_unregister_by_name); 5309 5310 allocate_cores(1); 5311 allocate_threads(1); 5312 set_thread(0); 5313 5314 CU_basic_set_mode(CU_BRM_VERBOSE); 5315 CU_basic_run_tests(); 5316 num_failures = CU_get_number_of_failures(); 5317 CU_cleanup_registry(); 5318 5319 free_threads(); 5320 free_cores(); 5321 5322 return num_failures; 5323 } 5324