1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "spdk_cunit.h" 35 36 #include "common/lib/ut_multithread.c" 37 #include "unit/lib/json_mock.c" 38 39 #include "spdk/config.h" 40 /* HACK: disable VTune integration so the unit test doesn't need VTune headers and libs to build */ 41 #undef SPDK_CONFIG_VTUNE 42 43 #include "bdev/bdev.c" 44 45 #define BDEV_UT_NUM_THREADS 3 46 47 DEFINE_STUB(spdk_conf_find_section, struct spdk_conf_section *, (struct spdk_conf *cp, 48 const char *name), NULL); 49 DEFINE_STUB(spdk_conf_section_get_nmval, char *, 50 (struct spdk_conf_section *sp, const char *key, int idx1, int idx2), NULL); 51 DEFINE_STUB(spdk_conf_section_get_intval, int, (struct spdk_conf_section *sp, const char *key), -1); 52 53 struct spdk_trace_histories *g_trace_histories; 54 DEFINE_STUB_V(spdk_trace_add_register_fn, (struct spdk_trace_register_fn *reg_fn)); 55 DEFINE_STUB_V(spdk_trace_register_owner, (uint8_t type, char id_prefix)); 56 DEFINE_STUB_V(spdk_trace_register_object, (uint8_t type, char id_prefix)); 57 DEFINE_STUB_V(spdk_trace_register_description, (const char *name, const char *short_name, 58 uint16_t tpoint_id, uint8_t owner_type, 59 uint8_t object_type, uint8_t new_object, 60 uint8_t arg1_type, const char *arg1_name)); 61 DEFINE_STUB_V(_spdk_trace_record, (uint64_t tsc, uint16_t tpoint_id, uint16_t poller_id, 62 uint32_t size, uint64_t object_id, uint64_t arg1)); 63 DEFINE_STUB(spdk_notify_send, uint64_t, (const char *type, const char *ctx), 0); 64 DEFINE_STUB(spdk_notify_type_register, struct spdk_notify_type *, (const char *type), NULL); 65 66 struct ut_bdev { 67 struct spdk_bdev bdev; 68 void *io_target; 69 }; 70 71 struct ut_bdev_channel { 72 TAILQ_HEAD(, spdk_bdev_io) outstanding_io; 73 uint32_t outstanding_cnt; 74 uint32_t avail_cnt; 75 }; 76 77 int g_io_device; 78 struct ut_bdev g_bdev; 79 struct spdk_bdev_desc *g_desc; 80 bool g_teardown_done = false; 81 bool g_get_io_channel = true; 82 bool g_create_ch = true; 83 bool g_init_complete_called = false; 84 bool g_fini_start_called = true; 85 int g_status = 0; 86 int g_count = 0; 87 struct spdk_histogram_data *g_histogram = NULL; 88 89 static int 90 stub_create_ch(void *io_device, void *ctx_buf) 91 { 92 struct ut_bdev_channel *ch = ctx_buf; 93 94 if (g_create_ch == false) { 95 return -1; 96 } 97 98 TAILQ_INIT(&ch->outstanding_io); 99 ch->outstanding_cnt = 0; 100 /* 101 * When avail gets to 0, the submit_request function will return ENOMEM. 102 * Most tests to not want ENOMEM to occur, so by default set this to a 103 * big value that won't get hit. The ENOMEM tests can then override this 104 * value to something much smaller to induce ENOMEM conditions. 105 */ 106 ch->avail_cnt = 2048; 107 return 0; 108 } 109 110 static void 111 stub_destroy_ch(void *io_device, void *ctx_buf) 112 { 113 } 114 115 static struct spdk_io_channel * 116 stub_get_io_channel(void *ctx) 117 { 118 struct ut_bdev *ut_bdev = ctx; 119 120 if (g_get_io_channel == true) { 121 return spdk_get_io_channel(ut_bdev->io_target); 122 } else { 123 return NULL; 124 } 125 } 126 127 static int 128 stub_destruct(void *ctx) 129 { 130 return 0; 131 } 132 133 static void 134 stub_submit_request(struct spdk_io_channel *_ch, struct spdk_bdev_io *bdev_io) 135 { 136 struct ut_bdev_channel *ch = spdk_io_channel_get_ctx(_ch); 137 138 if (bdev_io->type == SPDK_BDEV_IO_TYPE_RESET) { 139 struct spdk_bdev_io *io; 140 141 while (!TAILQ_EMPTY(&ch->outstanding_io)) { 142 io = TAILQ_FIRST(&ch->outstanding_io); 143 TAILQ_REMOVE(&ch->outstanding_io, io, module_link); 144 ch->outstanding_cnt--; 145 spdk_bdev_io_complete(io, SPDK_BDEV_IO_STATUS_FAILED); 146 ch->avail_cnt++; 147 } 148 } 149 150 if (ch->avail_cnt > 0) { 151 TAILQ_INSERT_TAIL(&ch->outstanding_io, bdev_io, module_link); 152 ch->outstanding_cnt++; 153 ch->avail_cnt--; 154 } else { 155 spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_NOMEM); 156 } 157 } 158 159 static uint32_t 160 stub_complete_io(void *io_target, uint32_t num_to_complete) 161 { 162 struct spdk_io_channel *_ch = spdk_get_io_channel(io_target); 163 struct ut_bdev_channel *ch = spdk_io_channel_get_ctx(_ch); 164 struct spdk_bdev_io *io; 165 bool complete_all = (num_to_complete == 0); 166 uint32_t num_completed = 0; 167 168 while (complete_all || num_completed < num_to_complete) { 169 if (TAILQ_EMPTY(&ch->outstanding_io)) { 170 break; 171 } 172 io = TAILQ_FIRST(&ch->outstanding_io); 173 TAILQ_REMOVE(&ch->outstanding_io, io, module_link); 174 ch->outstanding_cnt--; 175 spdk_bdev_io_complete(io, SPDK_BDEV_IO_STATUS_SUCCESS); 176 ch->avail_cnt++; 177 num_completed++; 178 } 179 180 spdk_put_io_channel(_ch); 181 return num_completed; 182 } 183 184 static struct spdk_bdev_fn_table fn_table = { 185 .get_io_channel = stub_get_io_channel, 186 .destruct = stub_destruct, 187 .submit_request = stub_submit_request, 188 }; 189 190 static int 191 module_init(void) 192 { 193 return 0; 194 } 195 196 static void 197 module_fini(void) 198 { 199 } 200 201 static void 202 init_complete(void) 203 { 204 g_init_complete_called = true; 205 } 206 207 static void 208 fini_start(void) 209 { 210 g_fini_start_called = true; 211 } 212 213 struct spdk_bdev_module bdev_ut_if = { 214 .name = "bdev_ut", 215 .module_init = module_init, 216 .module_fini = module_fini, 217 .init_complete = init_complete, 218 .fini_start = fini_start, 219 }; 220 221 SPDK_BDEV_MODULE_REGISTER(bdev_ut, &bdev_ut_if) 222 223 static void 224 register_bdev(struct ut_bdev *ut_bdev, char *name, void *io_target) 225 { 226 memset(ut_bdev, 0, sizeof(*ut_bdev)); 227 228 ut_bdev->io_target = io_target; 229 ut_bdev->bdev.ctxt = ut_bdev; 230 ut_bdev->bdev.name = name; 231 ut_bdev->bdev.fn_table = &fn_table; 232 ut_bdev->bdev.module = &bdev_ut_if; 233 ut_bdev->bdev.blocklen = 4096; 234 ut_bdev->bdev.blockcnt = 1024; 235 236 spdk_bdev_register(&ut_bdev->bdev); 237 } 238 239 static void 240 unregister_bdev(struct ut_bdev *ut_bdev) 241 { 242 /* Handle any deferred messages. */ 243 poll_threads(); 244 spdk_bdev_unregister(&ut_bdev->bdev, NULL, NULL); 245 } 246 247 static void 248 bdev_init_cb(void *done, int rc) 249 { 250 CU_ASSERT(rc == 0); 251 *(bool *)done = true; 252 } 253 254 static void 255 setup_test(void) 256 { 257 bool done = false; 258 259 allocate_threads(BDEV_UT_NUM_THREADS); 260 set_thread(0); 261 spdk_bdev_initialize(bdev_init_cb, &done); 262 spdk_io_device_register(&g_io_device, stub_create_ch, stub_destroy_ch, 263 sizeof(struct ut_bdev_channel), NULL); 264 register_bdev(&g_bdev, "ut_bdev", &g_io_device); 265 spdk_bdev_open(&g_bdev.bdev, true, NULL, NULL, &g_desc); 266 } 267 268 static void 269 finish_cb(void *cb_arg) 270 { 271 g_teardown_done = true; 272 } 273 274 static void 275 teardown_test(void) 276 { 277 set_thread(0); 278 g_teardown_done = false; 279 spdk_bdev_close(g_desc); 280 g_desc = NULL; 281 unregister_bdev(&g_bdev); 282 spdk_io_device_unregister(&g_io_device, NULL); 283 spdk_bdev_finish(finish_cb, NULL); 284 poll_threads(); 285 memset(&g_bdev, 0, sizeof(g_bdev)); 286 CU_ASSERT(g_teardown_done == true); 287 g_teardown_done = false; 288 free_threads(); 289 } 290 291 static uint32_t 292 bdev_io_tailq_cnt(bdev_io_tailq_t *tailq) 293 { 294 struct spdk_bdev_io *io; 295 uint32_t cnt = 0; 296 297 TAILQ_FOREACH(io, tailq, internal.link) { 298 cnt++; 299 } 300 301 return cnt; 302 } 303 304 static void 305 basic(void) 306 { 307 g_init_complete_called = false; 308 setup_test(); 309 CU_ASSERT(g_init_complete_called == true); 310 311 set_thread(0); 312 313 g_get_io_channel = false; 314 g_ut_threads[0].ch = spdk_bdev_get_io_channel(g_desc); 315 CU_ASSERT(g_ut_threads[0].ch == NULL); 316 317 g_get_io_channel = true; 318 g_create_ch = false; 319 g_ut_threads[0].ch = spdk_bdev_get_io_channel(g_desc); 320 CU_ASSERT(g_ut_threads[0].ch == NULL); 321 322 g_get_io_channel = true; 323 g_create_ch = true; 324 g_ut_threads[0].ch = spdk_bdev_get_io_channel(g_desc); 325 CU_ASSERT(g_ut_threads[0].ch != NULL); 326 spdk_put_io_channel(g_ut_threads[0].ch); 327 328 g_fini_start_called = false; 329 teardown_test(); 330 CU_ASSERT(g_fini_start_called == true); 331 } 332 333 static void 334 _bdev_removed(void *done) 335 { 336 *(bool *)done = true; 337 } 338 339 static void 340 _bdev_unregistered(void *done, int rc) 341 { 342 CU_ASSERT(rc == 0); 343 *(bool *)done = true; 344 } 345 346 static void 347 unregister_and_close(void) 348 { 349 bool done, remove_notify; 350 struct spdk_bdev_desc *desc; 351 352 setup_test(); 353 set_thread(0); 354 355 /* setup_test() automatically opens the bdev, 356 * but this test needs to do that in a different 357 * way. */ 358 spdk_bdev_close(g_desc); 359 poll_threads(); 360 361 /* Try hotremoving a bdev with descriptors which don't provide 362 * the notification callback */ 363 spdk_bdev_open(&g_bdev.bdev, true, NULL, NULL, &desc); 364 SPDK_CU_ASSERT_FATAL(desc != NULL); 365 366 /* There is an open descriptor on the device. Unregister it, 367 * which can't proceed until the descriptor is closed. */ 368 done = false; 369 spdk_bdev_unregister(&g_bdev.bdev, _bdev_unregistered, &done); 370 371 /* Poll the threads to allow all events to be processed */ 372 poll_threads(); 373 374 /* Make sure the bdev was not unregistered. We still have a 375 * descriptor open */ 376 CU_ASSERT(done == false); 377 378 spdk_bdev_close(desc); 379 poll_threads(); 380 381 /* The unregister should have completed */ 382 CU_ASSERT(done == true); 383 384 385 /* Register the bdev again */ 386 register_bdev(&g_bdev, "ut_bdev", &g_io_device); 387 388 remove_notify = false; 389 spdk_bdev_open(&g_bdev.bdev, true, _bdev_removed, &remove_notify, &desc); 390 SPDK_CU_ASSERT_FATAL(desc != NULL); 391 CU_ASSERT(remove_notify == false); 392 393 /* There is an open descriptor on the device. Unregister it, 394 * which can't proceed until the descriptor is closed. */ 395 done = false; 396 spdk_bdev_unregister(&g_bdev.bdev, _bdev_unregistered, &done); 397 /* No polling has occurred, so neither of these should execute */ 398 CU_ASSERT(remove_notify == false); 399 CU_ASSERT(done == false); 400 401 /* Prior to the unregister completing, close the descriptor */ 402 spdk_bdev_close(desc); 403 404 /* Poll the threads to allow all events to be processed */ 405 poll_threads(); 406 407 /* Remove notify should not have been called because the 408 * descriptor is already closed. */ 409 CU_ASSERT(remove_notify == false); 410 411 /* The unregister should have completed */ 412 CU_ASSERT(done == true); 413 414 /* Restore the original g_bdev so that we can use teardown_test(). */ 415 register_bdev(&g_bdev, "ut_bdev", &g_io_device); 416 spdk_bdev_open(&g_bdev.bdev, true, NULL, NULL, &g_desc); 417 teardown_test(); 418 } 419 420 static void 421 reset_done(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg) 422 { 423 bool *done = cb_arg; 424 425 CU_ASSERT(success == true); 426 *done = true; 427 spdk_bdev_free_io(bdev_io); 428 } 429 430 static void 431 put_channel_during_reset(void) 432 { 433 struct spdk_io_channel *io_ch; 434 bool done = false; 435 436 setup_test(); 437 438 set_thread(0); 439 io_ch = spdk_bdev_get_io_channel(g_desc); 440 CU_ASSERT(io_ch != NULL); 441 442 /* 443 * Start a reset, but then put the I/O channel before 444 * the deferred messages for the reset get a chance to 445 * execute. 446 */ 447 spdk_bdev_reset(g_desc, io_ch, reset_done, &done); 448 spdk_put_io_channel(io_ch); 449 poll_threads(); 450 stub_complete_io(g_bdev.io_target, 0); 451 452 teardown_test(); 453 } 454 455 static void 456 aborted_reset_done(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg) 457 { 458 enum spdk_bdev_io_status *status = cb_arg; 459 460 *status = success ? SPDK_BDEV_IO_STATUS_SUCCESS : SPDK_BDEV_IO_STATUS_FAILED; 461 spdk_bdev_free_io(bdev_io); 462 } 463 464 static void 465 aborted_reset(void) 466 { 467 struct spdk_io_channel *io_ch[2]; 468 enum spdk_bdev_io_status status1 = SPDK_BDEV_IO_STATUS_PENDING, 469 status2 = SPDK_BDEV_IO_STATUS_PENDING; 470 471 setup_test(); 472 473 set_thread(0); 474 io_ch[0] = spdk_bdev_get_io_channel(g_desc); 475 CU_ASSERT(io_ch[0] != NULL); 476 spdk_bdev_reset(g_desc, io_ch[0], aborted_reset_done, &status1); 477 poll_threads(); 478 CU_ASSERT(g_bdev.bdev.internal.reset_in_progress != NULL); 479 480 /* 481 * First reset has been submitted on ch0. Now submit a second 482 * reset on ch1 which will get queued since there is already a 483 * reset in progress. 484 */ 485 set_thread(1); 486 io_ch[1] = spdk_bdev_get_io_channel(g_desc); 487 CU_ASSERT(io_ch[1] != NULL); 488 spdk_bdev_reset(g_desc, io_ch[1], aborted_reset_done, &status2); 489 poll_threads(); 490 CU_ASSERT(g_bdev.bdev.internal.reset_in_progress != NULL); 491 492 /* 493 * Now destroy ch1. This will abort the queued reset. Check that 494 * the second reset was completed with failed status. Also check 495 * that bdev->internal.reset_in_progress != NULL, since the 496 * original reset has not been completed yet. This ensures that 497 * the bdev code is correctly noticing that the failed reset is 498 * *not* the one that had been submitted to the bdev module. 499 */ 500 set_thread(1); 501 spdk_put_io_channel(io_ch[1]); 502 poll_threads(); 503 CU_ASSERT(status2 == SPDK_BDEV_IO_STATUS_FAILED); 504 CU_ASSERT(g_bdev.bdev.internal.reset_in_progress != NULL); 505 506 /* 507 * Now complete the first reset, verify that it completed with SUCCESS 508 * status and that bdev->internal.reset_in_progress is also set back to NULL. 509 */ 510 set_thread(0); 511 spdk_put_io_channel(io_ch[0]); 512 stub_complete_io(g_bdev.io_target, 0); 513 poll_threads(); 514 CU_ASSERT(status1 == SPDK_BDEV_IO_STATUS_SUCCESS); 515 CU_ASSERT(g_bdev.bdev.internal.reset_in_progress == NULL); 516 517 teardown_test(); 518 } 519 520 static void 521 io_during_io_done(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg) 522 { 523 enum spdk_bdev_io_status *status = cb_arg; 524 525 *status = success ? SPDK_BDEV_IO_STATUS_SUCCESS : SPDK_BDEV_IO_STATUS_FAILED; 526 spdk_bdev_free_io(bdev_io); 527 } 528 529 static void 530 io_during_reset(void) 531 { 532 struct spdk_io_channel *io_ch[2]; 533 struct spdk_bdev_channel *bdev_ch[2]; 534 enum spdk_bdev_io_status status0, status1, status_reset; 535 int rc; 536 537 setup_test(); 538 539 /* 540 * First test normal case - submit an I/O on each of two channels (with no resets) 541 * and verify they complete successfully. 542 */ 543 set_thread(0); 544 io_ch[0] = spdk_bdev_get_io_channel(g_desc); 545 bdev_ch[0] = spdk_io_channel_get_ctx(io_ch[0]); 546 CU_ASSERT(bdev_ch[0]->flags == 0); 547 status0 = SPDK_BDEV_IO_STATUS_PENDING; 548 rc = spdk_bdev_read_blocks(g_desc, io_ch[0], NULL, 0, 1, io_during_io_done, &status0); 549 CU_ASSERT(rc == 0); 550 551 set_thread(1); 552 io_ch[1] = spdk_bdev_get_io_channel(g_desc); 553 bdev_ch[1] = spdk_io_channel_get_ctx(io_ch[1]); 554 CU_ASSERT(bdev_ch[1]->flags == 0); 555 status1 = SPDK_BDEV_IO_STATUS_PENDING; 556 rc = spdk_bdev_read_blocks(g_desc, io_ch[1], NULL, 0, 1, io_during_io_done, &status1); 557 CU_ASSERT(rc == 0); 558 559 poll_threads(); 560 CU_ASSERT(status0 == SPDK_BDEV_IO_STATUS_PENDING); 561 CU_ASSERT(status1 == SPDK_BDEV_IO_STATUS_PENDING); 562 563 set_thread(0); 564 stub_complete_io(g_bdev.io_target, 0); 565 CU_ASSERT(status0 == SPDK_BDEV_IO_STATUS_SUCCESS); 566 567 set_thread(1); 568 stub_complete_io(g_bdev.io_target, 0); 569 CU_ASSERT(status1 == SPDK_BDEV_IO_STATUS_SUCCESS); 570 571 /* 572 * Now submit a reset, and leave it pending while we submit I/O on two different 573 * channels. These I/O should be failed by the bdev layer since the reset is in 574 * progress. 575 */ 576 set_thread(0); 577 status_reset = SPDK_BDEV_IO_STATUS_PENDING; 578 rc = spdk_bdev_reset(g_desc, io_ch[0], io_during_io_done, &status_reset); 579 CU_ASSERT(rc == 0); 580 581 CU_ASSERT(bdev_ch[0]->flags == 0); 582 CU_ASSERT(bdev_ch[1]->flags == 0); 583 poll_threads(); 584 CU_ASSERT(bdev_ch[0]->flags == BDEV_CH_RESET_IN_PROGRESS); 585 CU_ASSERT(bdev_ch[1]->flags == BDEV_CH_RESET_IN_PROGRESS); 586 587 set_thread(0); 588 status0 = SPDK_BDEV_IO_STATUS_PENDING; 589 rc = spdk_bdev_read_blocks(g_desc, io_ch[0], NULL, 0, 1, io_during_io_done, &status0); 590 CU_ASSERT(rc == 0); 591 592 set_thread(1); 593 status1 = SPDK_BDEV_IO_STATUS_PENDING; 594 rc = spdk_bdev_read_blocks(g_desc, io_ch[1], NULL, 0, 1, io_during_io_done, &status1); 595 CU_ASSERT(rc == 0); 596 597 /* 598 * A reset is in progress so these read I/O should complete with failure. Note that we 599 * need to poll_threads() since I/O completed inline have their completion deferred. 600 */ 601 poll_threads(); 602 CU_ASSERT(status_reset == SPDK_BDEV_IO_STATUS_PENDING); 603 CU_ASSERT(status0 == SPDK_BDEV_IO_STATUS_FAILED); 604 CU_ASSERT(status1 == SPDK_BDEV_IO_STATUS_FAILED); 605 606 /* 607 * Complete the reset 608 */ 609 set_thread(0); 610 stub_complete_io(g_bdev.io_target, 0); 611 612 /* 613 * Only poll thread 0. We should not get a completion. 614 */ 615 poll_thread(0); 616 CU_ASSERT(status_reset == SPDK_BDEV_IO_STATUS_PENDING); 617 618 /* 619 * Poll both thread 0 and 1 so the messages can propagate and we 620 * get a completion. 621 */ 622 poll_threads(); 623 CU_ASSERT(status_reset == SPDK_BDEV_IO_STATUS_SUCCESS); 624 625 spdk_put_io_channel(io_ch[0]); 626 set_thread(1); 627 spdk_put_io_channel(io_ch[1]); 628 poll_threads(); 629 630 teardown_test(); 631 } 632 633 static void 634 basic_qos(void) 635 { 636 struct spdk_io_channel *io_ch[2]; 637 struct spdk_bdev_channel *bdev_ch[2]; 638 struct spdk_bdev *bdev; 639 enum spdk_bdev_io_status status; 640 int rc; 641 642 setup_test(); 643 644 /* Enable QoS */ 645 bdev = &g_bdev.bdev; 646 bdev->internal.qos = calloc(1, sizeof(*bdev->internal.qos)); 647 SPDK_CU_ASSERT_FATAL(bdev->internal.qos != NULL); 648 TAILQ_INIT(&bdev->internal.qos->queued); 649 /* 650 * Enable read/write IOPS, read only byte per second and 651 * read/write byte per second rate limits. 652 * In this case, all rate limits will take equal effect. 653 */ 654 /* 2000 read/write I/O per second, or 2 per millisecond */ 655 bdev->internal.qos->rate_limits[SPDK_BDEV_QOS_RW_IOPS_RATE_LIMIT].limit = 2000; 656 /* 8K read/write byte per millisecond with 4K block size */ 657 bdev->internal.qos->rate_limits[SPDK_BDEV_QOS_RW_BPS_RATE_LIMIT].limit = 8192000; 658 /* 8K read only byte per millisecond with 4K block size */ 659 bdev->internal.qos->rate_limits[SPDK_BDEV_QOS_R_BPS_RATE_LIMIT].limit = 8192000; 660 661 g_get_io_channel = true; 662 663 set_thread(0); 664 io_ch[0] = spdk_bdev_get_io_channel(g_desc); 665 bdev_ch[0] = spdk_io_channel_get_ctx(io_ch[0]); 666 CU_ASSERT(bdev_ch[0]->flags == BDEV_CH_QOS_ENABLED); 667 668 set_thread(1); 669 io_ch[1] = spdk_bdev_get_io_channel(g_desc); 670 bdev_ch[1] = spdk_io_channel_get_ctx(io_ch[1]); 671 CU_ASSERT(bdev_ch[1]->flags == BDEV_CH_QOS_ENABLED); 672 673 /* 674 * Send an I/O on thread 0, which is where the QoS thread is running. 675 */ 676 set_thread(0); 677 status = SPDK_BDEV_IO_STATUS_PENDING; 678 rc = spdk_bdev_read_blocks(g_desc, io_ch[0], NULL, 0, 1, io_during_io_done, &status); 679 CU_ASSERT(rc == 0); 680 CU_ASSERT(status == SPDK_BDEV_IO_STATUS_PENDING); 681 poll_threads(); 682 stub_complete_io(g_bdev.io_target, 0); 683 poll_threads(); 684 CU_ASSERT(status == SPDK_BDEV_IO_STATUS_SUCCESS); 685 686 /* Send an I/O on thread 1. The QoS thread is not running here. */ 687 status = SPDK_BDEV_IO_STATUS_PENDING; 688 set_thread(1); 689 rc = spdk_bdev_read_blocks(g_desc, io_ch[1], NULL, 0, 1, io_during_io_done, &status); 690 CU_ASSERT(rc == 0); 691 CU_ASSERT(status == SPDK_BDEV_IO_STATUS_PENDING); 692 poll_threads(); 693 /* Complete I/O on thread 1. This should not complete the I/O we submitted */ 694 stub_complete_io(g_bdev.io_target, 0); 695 poll_threads(); 696 CU_ASSERT(status == SPDK_BDEV_IO_STATUS_PENDING); 697 /* Now complete I/O on thread 0 */ 698 set_thread(0); 699 poll_threads(); 700 stub_complete_io(g_bdev.io_target, 0); 701 poll_threads(); 702 CU_ASSERT(status == SPDK_BDEV_IO_STATUS_SUCCESS); 703 704 /* 705 * Close the descriptor only, which should stop the qos channel as 706 * the last descriptor removed. 707 */ 708 spdk_bdev_close(g_desc); 709 poll_threads(); 710 CU_ASSERT(bdev->internal.qos->ch == NULL); 711 712 /* 713 * Open the bdev again which shall setup the qos channel as the 714 * channels are valid. 715 */ 716 spdk_bdev_open(bdev, true, NULL, NULL, &g_desc); 717 poll_threads(); 718 CU_ASSERT(bdev->internal.qos->ch != NULL); 719 720 /* Tear down the channels */ 721 set_thread(0); 722 spdk_put_io_channel(io_ch[0]); 723 set_thread(1); 724 spdk_put_io_channel(io_ch[1]); 725 poll_threads(); 726 set_thread(0); 727 728 /* Close the descriptor, which should stop the qos channel */ 729 spdk_bdev_close(g_desc); 730 poll_threads(); 731 CU_ASSERT(bdev->internal.qos->ch == NULL); 732 733 /* Open the bdev again, no qos channel setup without valid channels. */ 734 spdk_bdev_open(bdev, true, NULL, NULL, &g_desc); 735 poll_threads(); 736 CU_ASSERT(bdev->internal.qos->ch == NULL); 737 738 /* Create the channels in reverse order. */ 739 set_thread(1); 740 io_ch[1] = spdk_bdev_get_io_channel(g_desc); 741 bdev_ch[1] = spdk_io_channel_get_ctx(io_ch[1]); 742 CU_ASSERT(bdev_ch[1]->flags == BDEV_CH_QOS_ENABLED); 743 744 set_thread(0); 745 io_ch[0] = spdk_bdev_get_io_channel(g_desc); 746 bdev_ch[0] = spdk_io_channel_get_ctx(io_ch[0]); 747 CU_ASSERT(bdev_ch[0]->flags == BDEV_CH_QOS_ENABLED); 748 749 /* Confirm that the qos thread is now thread 1 */ 750 CU_ASSERT(bdev->internal.qos->ch == bdev_ch[1]); 751 752 /* Tear down the channels */ 753 set_thread(0); 754 spdk_put_io_channel(io_ch[0]); 755 set_thread(1); 756 spdk_put_io_channel(io_ch[1]); 757 poll_threads(); 758 759 set_thread(0); 760 761 teardown_test(); 762 } 763 764 static void 765 io_during_qos_queue(void) 766 { 767 struct spdk_io_channel *io_ch[2]; 768 struct spdk_bdev_channel *bdev_ch[2]; 769 struct spdk_bdev *bdev; 770 enum spdk_bdev_io_status status0, status1, status2; 771 int rc; 772 773 setup_test(); 774 MOCK_SET(spdk_get_ticks, 0); 775 776 /* Enable QoS */ 777 bdev = &g_bdev.bdev; 778 bdev->internal.qos = calloc(1, sizeof(*bdev->internal.qos)); 779 SPDK_CU_ASSERT_FATAL(bdev->internal.qos != NULL); 780 TAILQ_INIT(&bdev->internal.qos->queued); 781 /* 782 * Enable read/write IOPS, read only byte per sec, write only 783 * byte per sec and read/write byte per sec rate limits. 784 * In this case, both read only and write only byte per sec 785 * rate limit will take effect. 786 */ 787 /* 4000 read/write I/O per second, or 4 per millisecond */ 788 bdev->internal.qos->rate_limits[SPDK_BDEV_QOS_RW_IOPS_RATE_LIMIT].limit = 4000; 789 /* 8K byte per millisecond with 4K block size */ 790 bdev->internal.qos->rate_limits[SPDK_BDEV_QOS_RW_BPS_RATE_LIMIT].limit = 8192000; 791 /* 4K byte per millisecond with 4K block size */ 792 bdev->internal.qos->rate_limits[SPDK_BDEV_QOS_R_BPS_RATE_LIMIT].limit = 4096000; 793 /* 4K byte per millisecond with 4K block size */ 794 bdev->internal.qos->rate_limits[SPDK_BDEV_QOS_W_BPS_RATE_LIMIT].limit = 4096000; 795 796 g_get_io_channel = true; 797 798 /* Create channels */ 799 set_thread(0); 800 io_ch[0] = spdk_bdev_get_io_channel(g_desc); 801 bdev_ch[0] = spdk_io_channel_get_ctx(io_ch[0]); 802 CU_ASSERT(bdev_ch[0]->flags == BDEV_CH_QOS_ENABLED); 803 804 set_thread(1); 805 io_ch[1] = spdk_bdev_get_io_channel(g_desc); 806 bdev_ch[1] = spdk_io_channel_get_ctx(io_ch[1]); 807 CU_ASSERT(bdev_ch[1]->flags == BDEV_CH_QOS_ENABLED); 808 809 /* Send two read I/Os */ 810 status1 = SPDK_BDEV_IO_STATUS_PENDING; 811 rc = spdk_bdev_read_blocks(g_desc, io_ch[1], NULL, 0, 1, io_during_io_done, &status1); 812 CU_ASSERT(rc == 0); 813 CU_ASSERT(status1 == SPDK_BDEV_IO_STATUS_PENDING); 814 set_thread(0); 815 status0 = SPDK_BDEV_IO_STATUS_PENDING; 816 rc = spdk_bdev_read_blocks(g_desc, io_ch[0], NULL, 0, 1, io_during_io_done, &status0); 817 CU_ASSERT(rc == 0); 818 CU_ASSERT(status0 == SPDK_BDEV_IO_STATUS_PENDING); 819 /* Send one write I/O */ 820 status2 = SPDK_BDEV_IO_STATUS_PENDING; 821 rc = spdk_bdev_write_blocks(g_desc, io_ch[0], NULL, 0, 1, io_during_io_done, &status2); 822 CU_ASSERT(rc == 0); 823 CU_ASSERT(status2 == SPDK_BDEV_IO_STATUS_PENDING); 824 825 /* Complete any I/O that arrived at the disk */ 826 poll_threads(); 827 set_thread(1); 828 stub_complete_io(g_bdev.io_target, 0); 829 set_thread(0); 830 stub_complete_io(g_bdev.io_target, 0); 831 poll_threads(); 832 833 /* Only one of the two read I/Os should complete. (logical XOR) */ 834 if (status0 == SPDK_BDEV_IO_STATUS_SUCCESS) { 835 CU_ASSERT(status1 == SPDK_BDEV_IO_STATUS_PENDING); 836 } else { 837 CU_ASSERT(status1 == SPDK_BDEV_IO_STATUS_SUCCESS); 838 } 839 /* The write I/O should complete. */ 840 CU_ASSERT(status2 == SPDK_BDEV_IO_STATUS_SUCCESS); 841 842 /* Advance in time by a millisecond */ 843 spdk_delay_us(1000); 844 845 /* Complete more I/O */ 846 poll_threads(); 847 set_thread(1); 848 stub_complete_io(g_bdev.io_target, 0); 849 set_thread(0); 850 stub_complete_io(g_bdev.io_target, 0); 851 poll_threads(); 852 853 /* Now the second read I/O should be done */ 854 CU_ASSERT(status0 == SPDK_BDEV_IO_STATUS_SUCCESS); 855 CU_ASSERT(status1 == SPDK_BDEV_IO_STATUS_SUCCESS); 856 857 /* Tear down the channels */ 858 set_thread(1); 859 spdk_put_io_channel(io_ch[1]); 860 set_thread(0); 861 spdk_put_io_channel(io_ch[0]); 862 poll_threads(); 863 864 teardown_test(); 865 } 866 867 static void 868 io_during_qos_reset(void) 869 { 870 struct spdk_io_channel *io_ch[2]; 871 struct spdk_bdev_channel *bdev_ch[2]; 872 struct spdk_bdev *bdev; 873 enum spdk_bdev_io_status status0, status1, reset_status; 874 int rc; 875 876 setup_test(); 877 MOCK_SET(spdk_get_ticks, 0); 878 879 /* Enable QoS */ 880 bdev = &g_bdev.bdev; 881 bdev->internal.qos = calloc(1, sizeof(*bdev->internal.qos)); 882 SPDK_CU_ASSERT_FATAL(bdev->internal.qos != NULL); 883 TAILQ_INIT(&bdev->internal.qos->queued); 884 /* 885 * Enable read/write IOPS, write only byte per sec and 886 * read/write byte per second rate limits. 887 * In this case, read/write byte per second rate limit will 888 * take effect first. 889 */ 890 /* 2000 read/write I/O per second, or 2 per millisecond */ 891 bdev->internal.qos->rate_limits[SPDK_BDEV_QOS_RW_IOPS_RATE_LIMIT].limit = 2000; 892 /* 4K byte per millisecond with 4K block size */ 893 bdev->internal.qos->rate_limits[SPDK_BDEV_QOS_RW_BPS_RATE_LIMIT].limit = 4096000; 894 /* 8K byte per millisecond with 4K block size */ 895 bdev->internal.qos->rate_limits[SPDK_BDEV_QOS_W_BPS_RATE_LIMIT].limit = 8192000; 896 897 g_get_io_channel = true; 898 899 /* Create channels */ 900 set_thread(0); 901 io_ch[0] = spdk_bdev_get_io_channel(g_desc); 902 bdev_ch[0] = spdk_io_channel_get_ctx(io_ch[0]); 903 CU_ASSERT(bdev_ch[0]->flags == BDEV_CH_QOS_ENABLED); 904 905 set_thread(1); 906 io_ch[1] = spdk_bdev_get_io_channel(g_desc); 907 bdev_ch[1] = spdk_io_channel_get_ctx(io_ch[1]); 908 CU_ASSERT(bdev_ch[1]->flags == BDEV_CH_QOS_ENABLED); 909 910 /* Send two I/O. One of these gets queued by QoS. The other is sitting at the disk. */ 911 status1 = SPDK_BDEV_IO_STATUS_PENDING; 912 rc = spdk_bdev_write_blocks(g_desc, io_ch[1], NULL, 0, 1, io_during_io_done, &status1); 913 CU_ASSERT(rc == 0); 914 set_thread(0); 915 status0 = SPDK_BDEV_IO_STATUS_PENDING; 916 rc = spdk_bdev_write_blocks(g_desc, io_ch[0], NULL, 0, 1, io_during_io_done, &status0); 917 CU_ASSERT(rc == 0); 918 919 poll_threads(); 920 CU_ASSERT(status1 == SPDK_BDEV_IO_STATUS_PENDING); 921 CU_ASSERT(status0 == SPDK_BDEV_IO_STATUS_PENDING); 922 923 /* Reset the bdev. */ 924 reset_status = SPDK_BDEV_IO_STATUS_PENDING; 925 rc = spdk_bdev_reset(g_desc, io_ch[0], io_during_io_done, &reset_status); 926 CU_ASSERT(rc == 0); 927 928 /* Complete any I/O that arrived at the disk */ 929 poll_threads(); 930 set_thread(1); 931 stub_complete_io(g_bdev.io_target, 0); 932 set_thread(0); 933 stub_complete_io(g_bdev.io_target, 0); 934 poll_threads(); 935 936 CU_ASSERT(reset_status == SPDK_BDEV_IO_STATUS_SUCCESS); 937 CU_ASSERT(status0 == SPDK_BDEV_IO_STATUS_FAILED); 938 CU_ASSERT(status1 == SPDK_BDEV_IO_STATUS_FAILED); 939 940 /* Tear down the channels */ 941 set_thread(1); 942 spdk_put_io_channel(io_ch[1]); 943 set_thread(0); 944 spdk_put_io_channel(io_ch[0]); 945 poll_threads(); 946 947 teardown_test(); 948 } 949 950 static void 951 enomem_done(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg) 952 { 953 enum spdk_bdev_io_status *status = cb_arg; 954 955 *status = success ? SPDK_BDEV_IO_STATUS_SUCCESS : SPDK_BDEV_IO_STATUS_FAILED; 956 spdk_bdev_free_io(bdev_io); 957 } 958 959 static void 960 enomem(void) 961 { 962 struct spdk_io_channel *io_ch; 963 struct spdk_bdev_channel *bdev_ch; 964 struct spdk_bdev_shared_resource *shared_resource; 965 struct ut_bdev_channel *ut_ch; 966 const uint32_t IO_ARRAY_SIZE = 64; 967 const uint32_t AVAIL = 20; 968 enum spdk_bdev_io_status status[IO_ARRAY_SIZE], status_reset; 969 uint32_t nomem_cnt, i; 970 struct spdk_bdev_io *first_io; 971 int rc; 972 973 setup_test(); 974 975 set_thread(0); 976 io_ch = spdk_bdev_get_io_channel(g_desc); 977 bdev_ch = spdk_io_channel_get_ctx(io_ch); 978 shared_resource = bdev_ch->shared_resource; 979 ut_ch = spdk_io_channel_get_ctx(bdev_ch->channel); 980 ut_ch->avail_cnt = AVAIL; 981 982 /* First submit a number of IOs equal to what the channel can support. */ 983 for (i = 0; i < AVAIL; i++) { 984 status[i] = SPDK_BDEV_IO_STATUS_PENDING; 985 rc = spdk_bdev_read_blocks(g_desc, io_ch, NULL, 0, 1, enomem_done, &status[i]); 986 CU_ASSERT(rc == 0); 987 } 988 CU_ASSERT(TAILQ_EMPTY(&shared_resource->nomem_io)); 989 990 /* 991 * Next, submit one additional I/O. This one should fail with ENOMEM and then go onto 992 * the enomem_io list. 993 */ 994 status[AVAIL] = SPDK_BDEV_IO_STATUS_PENDING; 995 rc = spdk_bdev_read_blocks(g_desc, io_ch, NULL, 0, 1, enomem_done, &status[AVAIL]); 996 CU_ASSERT(rc == 0); 997 SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&shared_resource->nomem_io)); 998 first_io = TAILQ_FIRST(&shared_resource->nomem_io); 999 1000 /* 1001 * Now submit a bunch more I/O. These should all fail with ENOMEM and get queued behind 1002 * the first_io above. 1003 */ 1004 for (i = AVAIL + 1; i < IO_ARRAY_SIZE; i++) { 1005 status[i] = SPDK_BDEV_IO_STATUS_PENDING; 1006 rc = spdk_bdev_read_blocks(g_desc, io_ch, NULL, 0, 1, enomem_done, &status[i]); 1007 CU_ASSERT(rc == 0); 1008 } 1009 1010 /* Assert that first_io is still at the head of the list. */ 1011 CU_ASSERT(TAILQ_FIRST(&shared_resource->nomem_io) == first_io); 1012 CU_ASSERT(bdev_io_tailq_cnt(&shared_resource->nomem_io) == (IO_ARRAY_SIZE - AVAIL)); 1013 nomem_cnt = bdev_io_tailq_cnt(&shared_resource->nomem_io); 1014 CU_ASSERT(shared_resource->nomem_threshold == (AVAIL - NOMEM_THRESHOLD_COUNT)); 1015 1016 /* 1017 * Complete 1 I/O only. The key check here is bdev_io_tailq_cnt - this should not have 1018 * changed since completing just 1 I/O should not trigger retrying the queued nomem_io 1019 * list. 1020 */ 1021 stub_complete_io(g_bdev.io_target, 1); 1022 CU_ASSERT(bdev_io_tailq_cnt(&shared_resource->nomem_io) == nomem_cnt); 1023 1024 /* 1025 * Complete enough I/O to hit the nomem_theshold. This should trigger retrying nomem_io, 1026 * and we should see I/O get resubmitted to the test bdev module. 1027 */ 1028 stub_complete_io(g_bdev.io_target, NOMEM_THRESHOLD_COUNT - 1); 1029 CU_ASSERT(bdev_io_tailq_cnt(&shared_resource->nomem_io) < nomem_cnt); 1030 nomem_cnt = bdev_io_tailq_cnt(&shared_resource->nomem_io); 1031 1032 /* Complete 1 I/O only. This should not trigger retrying the queued nomem_io. */ 1033 stub_complete_io(g_bdev.io_target, 1); 1034 CU_ASSERT(bdev_io_tailq_cnt(&shared_resource->nomem_io) == nomem_cnt); 1035 1036 /* 1037 * Send a reset and confirm that all I/O are completed, including the ones that 1038 * were queued on the nomem_io list. 1039 */ 1040 status_reset = SPDK_BDEV_IO_STATUS_PENDING; 1041 rc = spdk_bdev_reset(g_desc, io_ch, enomem_done, &status_reset); 1042 poll_threads(); 1043 CU_ASSERT(rc == 0); 1044 /* This will complete the reset. */ 1045 stub_complete_io(g_bdev.io_target, 0); 1046 1047 CU_ASSERT(bdev_io_tailq_cnt(&shared_resource->nomem_io) == 0); 1048 CU_ASSERT(shared_resource->io_outstanding == 0); 1049 1050 spdk_put_io_channel(io_ch); 1051 poll_threads(); 1052 teardown_test(); 1053 } 1054 1055 static void 1056 enomem_multi_bdev(void) 1057 { 1058 struct spdk_io_channel *io_ch; 1059 struct spdk_bdev_channel *bdev_ch; 1060 struct spdk_bdev_shared_resource *shared_resource; 1061 struct ut_bdev_channel *ut_ch; 1062 const uint32_t IO_ARRAY_SIZE = 64; 1063 const uint32_t AVAIL = 20; 1064 enum spdk_bdev_io_status status[IO_ARRAY_SIZE]; 1065 uint32_t i; 1066 struct ut_bdev *second_bdev; 1067 struct spdk_bdev_desc *second_desc = NULL; 1068 struct spdk_bdev_channel *second_bdev_ch; 1069 struct spdk_io_channel *second_ch; 1070 int rc; 1071 1072 setup_test(); 1073 1074 /* Register second bdev with the same io_target */ 1075 second_bdev = calloc(1, sizeof(*second_bdev)); 1076 SPDK_CU_ASSERT_FATAL(second_bdev != NULL); 1077 register_bdev(second_bdev, "ut_bdev2", g_bdev.io_target); 1078 spdk_bdev_open(&second_bdev->bdev, true, NULL, NULL, &second_desc); 1079 SPDK_CU_ASSERT_FATAL(second_desc != NULL); 1080 1081 set_thread(0); 1082 io_ch = spdk_bdev_get_io_channel(g_desc); 1083 bdev_ch = spdk_io_channel_get_ctx(io_ch); 1084 shared_resource = bdev_ch->shared_resource; 1085 ut_ch = spdk_io_channel_get_ctx(bdev_ch->channel); 1086 ut_ch->avail_cnt = AVAIL; 1087 1088 second_ch = spdk_bdev_get_io_channel(second_desc); 1089 second_bdev_ch = spdk_io_channel_get_ctx(second_ch); 1090 SPDK_CU_ASSERT_FATAL(shared_resource == second_bdev_ch->shared_resource); 1091 1092 /* Saturate io_target through bdev A. */ 1093 for (i = 0; i < AVAIL; i++) { 1094 status[i] = SPDK_BDEV_IO_STATUS_PENDING; 1095 rc = spdk_bdev_read_blocks(g_desc, io_ch, NULL, 0, 1, enomem_done, &status[i]); 1096 CU_ASSERT(rc == 0); 1097 } 1098 CU_ASSERT(TAILQ_EMPTY(&shared_resource->nomem_io)); 1099 1100 /* 1101 * Now submit I/O through the second bdev. This should fail with ENOMEM 1102 * and then go onto the nomem_io list. 1103 */ 1104 status[AVAIL] = SPDK_BDEV_IO_STATUS_PENDING; 1105 rc = spdk_bdev_read_blocks(second_desc, second_ch, NULL, 0, 1, enomem_done, &status[AVAIL]); 1106 CU_ASSERT(rc == 0); 1107 SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&shared_resource->nomem_io)); 1108 1109 /* Complete first bdev's I/O. This should retry sending second bdev's nomem_io */ 1110 stub_complete_io(g_bdev.io_target, AVAIL); 1111 1112 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&shared_resource->nomem_io)); 1113 CU_ASSERT(shared_resource->io_outstanding == 1); 1114 1115 /* Now complete our retried I/O */ 1116 stub_complete_io(g_bdev.io_target, 1); 1117 SPDK_CU_ASSERT_FATAL(shared_resource->io_outstanding == 0); 1118 1119 spdk_put_io_channel(io_ch); 1120 spdk_put_io_channel(second_ch); 1121 spdk_bdev_close(second_desc); 1122 unregister_bdev(second_bdev); 1123 poll_threads(); 1124 free(second_bdev); 1125 teardown_test(); 1126 } 1127 1128 1129 static void 1130 enomem_multi_io_target(void) 1131 { 1132 struct spdk_io_channel *io_ch; 1133 struct spdk_bdev_channel *bdev_ch; 1134 struct ut_bdev_channel *ut_ch; 1135 const uint32_t IO_ARRAY_SIZE = 64; 1136 const uint32_t AVAIL = 20; 1137 enum spdk_bdev_io_status status[IO_ARRAY_SIZE]; 1138 uint32_t i; 1139 int new_io_device; 1140 struct ut_bdev *second_bdev; 1141 struct spdk_bdev_desc *second_desc = NULL; 1142 struct spdk_bdev_channel *second_bdev_ch; 1143 struct spdk_io_channel *second_ch; 1144 int rc; 1145 1146 setup_test(); 1147 1148 /* Create new io_target and a second bdev using it */ 1149 spdk_io_device_register(&new_io_device, stub_create_ch, stub_destroy_ch, 1150 sizeof(struct ut_bdev_channel), NULL); 1151 second_bdev = calloc(1, sizeof(*second_bdev)); 1152 SPDK_CU_ASSERT_FATAL(second_bdev != NULL); 1153 register_bdev(second_bdev, "ut_bdev2", &new_io_device); 1154 spdk_bdev_open(&second_bdev->bdev, true, NULL, NULL, &second_desc); 1155 SPDK_CU_ASSERT_FATAL(second_desc != NULL); 1156 1157 set_thread(0); 1158 io_ch = spdk_bdev_get_io_channel(g_desc); 1159 bdev_ch = spdk_io_channel_get_ctx(io_ch); 1160 ut_ch = spdk_io_channel_get_ctx(bdev_ch->channel); 1161 ut_ch->avail_cnt = AVAIL; 1162 1163 /* Different io_target should imply a different shared_resource */ 1164 second_ch = spdk_bdev_get_io_channel(second_desc); 1165 second_bdev_ch = spdk_io_channel_get_ctx(second_ch); 1166 SPDK_CU_ASSERT_FATAL(bdev_ch->shared_resource != second_bdev_ch->shared_resource); 1167 1168 /* Saturate io_target through bdev A. */ 1169 for (i = 0; i < AVAIL; i++) { 1170 status[i] = SPDK_BDEV_IO_STATUS_PENDING; 1171 rc = spdk_bdev_read_blocks(g_desc, io_ch, NULL, 0, 1, enomem_done, &status[i]); 1172 CU_ASSERT(rc == 0); 1173 } 1174 CU_ASSERT(TAILQ_EMPTY(&bdev_ch->shared_resource->nomem_io)); 1175 1176 /* Issue one more I/O to fill ENOMEM list. */ 1177 status[AVAIL] = SPDK_BDEV_IO_STATUS_PENDING; 1178 rc = spdk_bdev_read_blocks(g_desc, io_ch, NULL, 0, 1, enomem_done, &status[AVAIL]); 1179 CU_ASSERT(rc == 0); 1180 SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&bdev_ch->shared_resource->nomem_io)); 1181 1182 /* 1183 * Now submit I/O through the second bdev. This should go through and complete 1184 * successfully because we're using a different io_device underneath. 1185 */ 1186 status[AVAIL] = SPDK_BDEV_IO_STATUS_PENDING; 1187 rc = spdk_bdev_read_blocks(second_desc, second_ch, NULL, 0, 1, enomem_done, &status[AVAIL]); 1188 CU_ASSERT(rc == 0); 1189 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&second_bdev_ch->shared_resource->nomem_io)); 1190 stub_complete_io(second_bdev->io_target, 1); 1191 1192 /* Cleanup; Complete outstanding I/O. */ 1193 stub_complete_io(g_bdev.io_target, AVAIL); 1194 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&bdev_ch->shared_resource->nomem_io)); 1195 /* Complete the ENOMEM I/O */ 1196 stub_complete_io(g_bdev.io_target, 1); 1197 CU_ASSERT(bdev_ch->shared_resource->io_outstanding == 0); 1198 1199 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&bdev_ch->shared_resource->nomem_io)); 1200 CU_ASSERT(bdev_ch->shared_resource->io_outstanding == 0); 1201 spdk_put_io_channel(io_ch); 1202 spdk_put_io_channel(second_ch); 1203 spdk_bdev_close(second_desc); 1204 unregister_bdev(second_bdev); 1205 spdk_io_device_unregister(&new_io_device, NULL); 1206 poll_threads(); 1207 free(second_bdev); 1208 teardown_test(); 1209 } 1210 1211 static void 1212 qos_dynamic_enable_done(void *cb_arg, int status) 1213 { 1214 int *rc = cb_arg; 1215 *rc = status; 1216 } 1217 1218 static void 1219 qos_dynamic_enable(void) 1220 { 1221 struct spdk_io_channel *io_ch[2]; 1222 struct spdk_bdev_channel *bdev_ch[2]; 1223 struct spdk_bdev *bdev; 1224 enum spdk_bdev_io_status bdev_io_status[2]; 1225 uint64_t limits[SPDK_BDEV_QOS_NUM_RATE_LIMIT_TYPES] = {}; 1226 int status, second_status, rc, i; 1227 1228 setup_test(); 1229 MOCK_SET(spdk_get_ticks, 0); 1230 1231 for (i = 0; i < SPDK_BDEV_QOS_NUM_RATE_LIMIT_TYPES; i++) { 1232 limits[i] = UINT64_MAX; 1233 } 1234 1235 bdev = &g_bdev.bdev; 1236 1237 g_get_io_channel = true; 1238 1239 /* Create channels */ 1240 set_thread(0); 1241 io_ch[0] = spdk_bdev_get_io_channel(g_desc); 1242 bdev_ch[0] = spdk_io_channel_get_ctx(io_ch[0]); 1243 CU_ASSERT(bdev_ch[0]->flags == 0); 1244 1245 set_thread(1); 1246 io_ch[1] = spdk_bdev_get_io_channel(g_desc); 1247 bdev_ch[1] = spdk_io_channel_get_ctx(io_ch[1]); 1248 CU_ASSERT(bdev_ch[1]->flags == 0); 1249 1250 set_thread(0); 1251 1252 /* 1253 * Enable QoS: Read/Write IOPS, Read/Write byte, 1254 * Read only byte and Write only byte per second 1255 * rate limits. 1256 * More than 10 I/Os allowed per timeslice. 1257 */ 1258 status = -1; 1259 limits[SPDK_BDEV_QOS_RW_IOPS_RATE_LIMIT] = 10000; 1260 limits[SPDK_BDEV_QOS_RW_BPS_RATE_LIMIT] = 100; 1261 limits[SPDK_BDEV_QOS_R_BPS_RATE_LIMIT] = 100; 1262 limits[SPDK_BDEV_QOS_W_BPS_RATE_LIMIT] = 10; 1263 spdk_bdev_set_qos_rate_limits(bdev, limits, qos_dynamic_enable_done, &status); 1264 poll_threads(); 1265 CU_ASSERT(status == 0); 1266 CU_ASSERT((bdev_ch[0]->flags & BDEV_CH_QOS_ENABLED) != 0); 1267 CU_ASSERT((bdev_ch[1]->flags & BDEV_CH_QOS_ENABLED) != 0); 1268 1269 /* 1270 * Submit and complete 10 I/O to fill the QoS allotment for this timeslice. 1271 * Additional I/O will then be queued. 1272 */ 1273 set_thread(0); 1274 for (i = 0; i < 10; i++) { 1275 bdev_io_status[0] = SPDK_BDEV_IO_STATUS_PENDING; 1276 rc = spdk_bdev_read_blocks(g_desc, io_ch[0], NULL, 0, 1, io_during_io_done, &bdev_io_status[0]); 1277 CU_ASSERT(rc == 0); 1278 CU_ASSERT(bdev_io_status[0] == SPDK_BDEV_IO_STATUS_PENDING); 1279 poll_thread(0); 1280 stub_complete_io(g_bdev.io_target, 0); 1281 CU_ASSERT(bdev_io_status[0] == SPDK_BDEV_IO_STATUS_SUCCESS); 1282 } 1283 1284 /* 1285 * Send two more I/O. These I/O will be queued since the current timeslice allotment has been 1286 * filled already. We want to test that when QoS is disabled that these two I/O: 1287 * 1) are not aborted 1288 * 2) are sent back to their original thread for resubmission 1289 */ 1290 bdev_io_status[0] = SPDK_BDEV_IO_STATUS_PENDING; 1291 rc = spdk_bdev_read_blocks(g_desc, io_ch[0], NULL, 0, 1, io_during_io_done, &bdev_io_status[0]); 1292 CU_ASSERT(rc == 0); 1293 CU_ASSERT(bdev_io_status[0] == SPDK_BDEV_IO_STATUS_PENDING); 1294 set_thread(1); 1295 bdev_io_status[1] = SPDK_BDEV_IO_STATUS_PENDING; 1296 rc = spdk_bdev_read_blocks(g_desc, io_ch[1], NULL, 0, 1, io_during_io_done, &bdev_io_status[1]); 1297 CU_ASSERT(rc == 0); 1298 CU_ASSERT(bdev_io_status[1] == SPDK_BDEV_IO_STATUS_PENDING); 1299 poll_threads(); 1300 1301 /* 1302 * Disable QoS: Read/Write IOPS, Read/Write byte, 1303 * Read only byte rate limits 1304 */ 1305 status = -1; 1306 limits[SPDK_BDEV_QOS_RW_IOPS_RATE_LIMIT] = 0; 1307 limits[SPDK_BDEV_QOS_RW_BPS_RATE_LIMIT] = 0; 1308 limits[SPDK_BDEV_QOS_R_BPS_RATE_LIMIT] = 0; 1309 spdk_bdev_set_qos_rate_limits(bdev, limits, qos_dynamic_enable_done, &status); 1310 poll_threads(); 1311 CU_ASSERT(status == 0); 1312 CU_ASSERT((bdev_ch[0]->flags & BDEV_CH_QOS_ENABLED) != 0); 1313 CU_ASSERT((bdev_ch[1]->flags & BDEV_CH_QOS_ENABLED) != 0); 1314 1315 /* Disable QoS: Write only Byte per second rate limit */ 1316 status = -1; 1317 limits[SPDK_BDEV_QOS_W_BPS_RATE_LIMIT] = 0; 1318 spdk_bdev_set_qos_rate_limits(bdev, limits, qos_dynamic_enable_done, &status); 1319 poll_threads(); 1320 CU_ASSERT(status == 0); 1321 CU_ASSERT((bdev_ch[0]->flags & BDEV_CH_QOS_ENABLED) == 0); 1322 CU_ASSERT((bdev_ch[1]->flags & BDEV_CH_QOS_ENABLED) == 0); 1323 1324 /* 1325 * All I/O should have been resubmitted back on their original thread. Complete 1326 * all I/O on thread 0, and ensure that only the thread 0 I/O was completed. 1327 */ 1328 set_thread(0); 1329 stub_complete_io(g_bdev.io_target, 0); 1330 poll_threads(); 1331 CU_ASSERT(bdev_io_status[0] == SPDK_BDEV_IO_STATUS_SUCCESS); 1332 CU_ASSERT(bdev_io_status[1] == SPDK_BDEV_IO_STATUS_PENDING); 1333 1334 /* Now complete all I/O on thread 1 and ensure the thread 1 I/O was completed. */ 1335 set_thread(1); 1336 stub_complete_io(g_bdev.io_target, 0); 1337 poll_threads(); 1338 CU_ASSERT(bdev_io_status[1] == SPDK_BDEV_IO_STATUS_SUCCESS); 1339 1340 /* Disable QoS again */ 1341 status = -1; 1342 limits[SPDK_BDEV_QOS_RW_IOPS_RATE_LIMIT] = 0; 1343 spdk_bdev_set_qos_rate_limits(bdev, limits, qos_dynamic_enable_done, &status); 1344 poll_threads(); 1345 CU_ASSERT(status == 0); /* This should succeed */ 1346 CU_ASSERT((bdev_ch[0]->flags & BDEV_CH_QOS_ENABLED) == 0); 1347 CU_ASSERT((bdev_ch[1]->flags & BDEV_CH_QOS_ENABLED) == 0); 1348 1349 /* Enable QoS on thread 0 */ 1350 status = -1; 1351 limits[SPDK_BDEV_QOS_RW_IOPS_RATE_LIMIT] = 10000; 1352 spdk_bdev_set_qos_rate_limits(bdev, limits, qos_dynamic_enable_done, &status); 1353 poll_threads(); 1354 CU_ASSERT(status == 0); 1355 CU_ASSERT((bdev_ch[0]->flags & BDEV_CH_QOS_ENABLED) != 0); 1356 CU_ASSERT((bdev_ch[1]->flags & BDEV_CH_QOS_ENABLED) != 0); 1357 1358 /* Disable QoS on thread 1 */ 1359 set_thread(1); 1360 status = -1; 1361 limits[SPDK_BDEV_QOS_RW_IOPS_RATE_LIMIT] = 0; 1362 spdk_bdev_set_qos_rate_limits(bdev, limits, qos_dynamic_enable_done, &status); 1363 /* Don't poll yet. This should leave the channels with QoS enabled */ 1364 CU_ASSERT(status == -1); 1365 CU_ASSERT((bdev_ch[0]->flags & BDEV_CH_QOS_ENABLED) != 0); 1366 CU_ASSERT((bdev_ch[1]->flags & BDEV_CH_QOS_ENABLED) != 0); 1367 1368 /* Enable QoS. This should immediately fail because the previous disable QoS hasn't completed. */ 1369 second_status = 0; 1370 limits[SPDK_BDEV_QOS_RW_BPS_RATE_LIMIT] = 10; 1371 spdk_bdev_set_qos_rate_limits(bdev, limits, qos_dynamic_enable_done, &second_status); 1372 poll_threads(); 1373 CU_ASSERT(status == 0); /* The disable should succeed */ 1374 CU_ASSERT(second_status < 0); /* The enable should fail */ 1375 CU_ASSERT((bdev_ch[0]->flags & BDEV_CH_QOS_ENABLED) == 0); 1376 CU_ASSERT((bdev_ch[1]->flags & BDEV_CH_QOS_ENABLED) == 0); 1377 1378 /* Enable QoS on thread 1. This should succeed now that the disable has completed. */ 1379 status = -1; 1380 limits[SPDK_BDEV_QOS_RW_IOPS_RATE_LIMIT] = 10000; 1381 spdk_bdev_set_qos_rate_limits(bdev, limits, qos_dynamic_enable_done, &status); 1382 poll_threads(); 1383 CU_ASSERT(status == 0); 1384 CU_ASSERT((bdev_ch[0]->flags & BDEV_CH_QOS_ENABLED) != 0); 1385 CU_ASSERT((bdev_ch[1]->flags & BDEV_CH_QOS_ENABLED) != 0); 1386 1387 /* Tear down the channels */ 1388 set_thread(0); 1389 spdk_put_io_channel(io_ch[0]); 1390 set_thread(1); 1391 spdk_put_io_channel(io_ch[1]); 1392 poll_threads(); 1393 1394 set_thread(0); 1395 teardown_test(); 1396 } 1397 1398 static void 1399 histogram_status_cb(void *cb_arg, int status) 1400 { 1401 g_status = status; 1402 } 1403 1404 static void 1405 histogram_data_cb(void *cb_arg, int status, struct spdk_histogram_data *histogram) 1406 { 1407 g_status = status; 1408 g_histogram = histogram; 1409 } 1410 1411 static void 1412 histogram_io_count(void *ctx, uint64_t start, uint64_t end, uint64_t count, 1413 uint64_t total, uint64_t so_far) 1414 { 1415 g_count += count; 1416 } 1417 1418 static void 1419 bdev_histograms_mt(void) 1420 { 1421 struct spdk_io_channel *ch[2]; 1422 struct spdk_histogram_data *histogram; 1423 uint8_t buf[4096]; 1424 int status = false; 1425 int rc; 1426 1427 1428 setup_test(); 1429 1430 set_thread(0); 1431 ch[0] = spdk_bdev_get_io_channel(g_desc); 1432 CU_ASSERT(ch[0] != NULL); 1433 1434 set_thread(1); 1435 ch[1] = spdk_bdev_get_io_channel(g_desc); 1436 CU_ASSERT(ch[1] != NULL); 1437 1438 1439 /* Enable histogram */ 1440 spdk_bdev_histogram_enable(&g_bdev.bdev, histogram_status_cb, NULL, true); 1441 poll_threads(); 1442 CU_ASSERT(g_status == 0); 1443 CU_ASSERT(g_bdev.bdev.internal.histogram_enabled == true); 1444 1445 /* Allocate histogram */ 1446 histogram = spdk_histogram_data_alloc(); 1447 1448 /* Check if histogram is zeroed */ 1449 spdk_bdev_histogram_get(&g_bdev.bdev, histogram, histogram_data_cb, NULL); 1450 poll_threads(); 1451 CU_ASSERT(g_status == 0); 1452 SPDK_CU_ASSERT_FATAL(g_histogram != NULL); 1453 1454 g_count = 0; 1455 spdk_histogram_data_iterate(g_histogram, histogram_io_count, NULL); 1456 1457 CU_ASSERT(g_count == 0); 1458 1459 set_thread(0); 1460 rc = spdk_bdev_write_blocks(g_desc, ch[0], &buf, 0, 1, io_during_io_done, &status); 1461 CU_ASSERT(rc == 0); 1462 1463 spdk_delay_us(10); 1464 stub_complete_io(g_bdev.io_target, 1); 1465 poll_threads(); 1466 CU_ASSERT(status == true); 1467 1468 1469 set_thread(1); 1470 rc = spdk_bdev_read_blocks(g_desc, ch[1], &buf, 0, 1, io_during_io_done, &status); 1471 CU_ASSERT(rc == 0); 1472 1473 spdk_delay_us(10); 1474 stub_complete_io(g_bdev.io_target, 1); 1475 poll_threads(); 1476 CU_ASSERT(status == true); 1477 1478 set_thread(0); 1479 1480 /* Check if histogram gathered data from all I/O channels */ 1481 spdk_bdev_histogram_get(&g_bdev.bdev, histogram, histogram_data_cb, NULL); 1482 poll_threads(); 1483 CU_ASSERT(g_status == 0); 1484 CU_ASSERT(g_bdev.bdev.internal.histogram_enabled == true); 1485 SPDK_CU_ASSERT_FATAL(g_histogram != NULL); 1486 1487 g_count = 0; 1488 spdk_histogram_data_iterate(g_histogram, histogram_io_count, NULL); 1489 CU_ASSERT(g_count == 2); 1490 1491 /* Disable histogram */ 1492 spdk_bdev_histogram_enable(&g_bdev.bdev, histogram_status_cb, NULL, false); 1493 poll_threads(); 1494 CU_ASSERT(g_status == 0); 1495 CU_ASSERT(g_bdev.bdev.internal.histogram_enabled == false); 1496 1497 spdk_histogram_data_free(g_histogram); 1498 } 1499 1500 int 1501 main(int argc, char **argv) 1502 { 1503 CU_pSuite suite = NULL; 1504 unsigned int num_failures; 1505 1506 if (CU_initialize_registry() != CUE_SUCCESS) { 1507 return CU_get_error(); 1508 } 1509 1510 suite = CU_add_suite("bdev", NULL, NULL); 1511 if (suite == NULL) { 1512 CU_cleanup_registry(); 1513 return CU_get_error(); 1514 } 1515 1516 if ( 1517 CU_add_test(suite, "basic", basic) == NULL || 1518 CU_add_test(suite, "unregister_and_close", unregister_and_close) == NULL || 1519 CU_add_test(suite, "basic_qos", basic_qos) == NULL || 1520 CU_add_test(suite, "put_channel_during_reset", put_channel_during_reset) == NULL || 1521 CU_add_test(suite, "aborted_reset", aborted_reset) == NULL || 1522 CU_add_test(suite, "io_during_reset", io_during_reset) == NULL || 1523 CU_add_test(suite, "io_during_qos_queue", io_during_qos_queue) == NULL || 1524 CU_add_test(suite, "io_during_qos_reset", io_during_qos_reset) == NULL || 1525 CU_add_test(suite, "enomem", enomem) == NULL || 1526 CU_add_test(suite, "enomem_multi_bdev", enomem_multi_bdev) == NULL || 1527 CU_add_test(suite, "enomem_multi_io_target", enomem_multi_io_target) == NULL || 1528 CU_add_test(suite, "qos_dynamic_enable", qos_dynamic_enable) == NULL || 1529 CU_add_test(suite, "bdev_histograms_mt", bdev_histograms_mt) == NULL 1530 ) { 1531 CU_cleanup_registry(); 1532 return CU_get_error(); 1533 } 1534 1535 CU_basic_set_mode(CU_BRM_VERBOSE); 1536 CU_basic_run_tests(); 1537 num_failures = CU_get_number_of_failures(); 1538 CU_cleanup_registry(); 1539 return num_failures; 1540 } 1541