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