| 537 | } |
| 538 | |
| 539 | static void |
| 540 | mmp_thread(void *arg) |
| 541 | { |
| 542 | spa_t *spa = (spa_t *)arg; |
| 543 | mmp_thread_t *mmp = &spa->spa_mmp; |
| 544 | boolean_t suspended = spa_suspended(spa); |
| 545 | boolean_t multihost = spa_multihost(spa); |
| 546 | uint64_t mmp_interval = MSEC2NSEC(MMP_INTERVAL_OK( |
| 547 | zfs_multihost_interval)); |
| 548 | uint32_t mmp_fail_intervals = MMP_FAIL_INTVS_OK( |
| 549 | zfs_multihost_fail_intervals); |
| 550 | hrtime_t mmp_fail_ns = mmp_fail_intervals * mmp_interval; |
| 551 | boolean_t last_spa_suspended = suspended; |
| 552 | boolean_t last_spa_multihost = multihost; |
| 553 | uint64_t last_mmp_interval = mmp_interval; |
| 554 | uint32_t last_mmp_fail_intervals = mmp_fail_intervals; |
| 555 | hrtime_t last_mmp_fail_ns = mmp_fail_ns; |
| 556 | callb_cpr_t cpr; |
| 557 | int skip_wait = 0; |
| 558 | |
| 559 | mmp_thread_enter(mmp, &cpr); |
| 560 | |
| 561 | /* |
| 562 | * There have been no MMP writes yet. Setting mmp_last_write here gives |
| 563 | * us one mmp_fail_ns period, which is consistent with the activity |
| 564 | * check duration, to try to land an MMP write before MMP suspends the |
| 565 | * pool (if so configured). |
| 566 | */ |
| 567 | |
| 568 | mutex_enter(&mmp->mmp_io_lock); |
| 569 | mmp->mmp_last_write = gethrtime(); |
| 570 | mmp->mmp_delay = MSEC2NSEC(MMP_INTERVAL_OK(zfs_multihost_interval)); |
| 571 | mutex_exit(&mmp->mmp_io_lock); |
| 572 | |
| 573 | while (!mmp->mmp_thread_exiting) { |
| 574 | hrtime_t next_time = gethrtime() + |
| 575 | MSEC2NSEC(MMP_DEFAULT_INTERVAL); |
| 576 | int leaves = MAX(vdev_count_leaves(spa), 1); |
| 577 | |
| 578 | /* Detect changes in tunables or state */ |
| 579 | |
| 580 | last_spa_suspended = suspended; |
| 581 | last_spa_multihost = multihost; |
| 582 | suspended = spa_suspended(spa); |
| 583 | multihost = spa_multihost(spa); |
| 584 | |
| 585 | last_mmp_interval = mmp_interval; |
| 586 | last_mmp_fail_intervals = mmp_fail_intervals; |
| 587 | last_mmp_fail_ns = mmp_fail_ns; |
| 588 | mmp_interval = MSEC2NSEC(MMP_INTERVAL_OK( |
| 589 | zfs_multihost_interval)); |
| 590 | mmp_fail_intervals = MMP_FAIL_INTVS_OK( |
| 591 | zfs_multihost_fail_intervals); |
| 592 | |
| 593 | /* Smooth so pool is not suspended when reducing tunables */ |
| 594 | if (mmp_fail_intervals * mmp_interval < mmp_fail_ns) { |
| 595 | mmp_fail_ns = (mmp_fail_ns * 31 + |
| 596 | mmp_fail_intervals * mmp_interval) / 32; |
nothing calls this directly
no test coverage detected