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