MCPcopy Create free account
hub / github.com/F-Stack/f-stack / zil_commit_waiter

Function zil_commit_waiter

freebsd/contrib/openzfs/module/zfs/zil.c:2641–2740  ·  view source on GitHub ↗

* This function is responsible for performing the following two tasks: * * 1. its primary responsibility is to block until the given "commit * waiter" is considered "done". * * 2. its secondary responsibility is to issue the zio for the lwb that * the given "commit waiter" is waiting on, if this function has * waited "long enough" and the lwb is still in the "open" state. * * Giv

Source from the content-addressed store, hash-verified

2639 * the comment at the bottom of that function.
2640 */
2641static void
2642zil_commit_waiter(zilog_t *zilog, zil_commit_waiter_t *zcw)
2643{
2644 ASSERT(!MUTEX_HELD(&zilog->zl_lock));
2645 ASSERT(!MUTEX_HELD(&zilog->zl_issuer_lock));
2646 ASSERT(spa_writeable(zilog->zl_spa));
2647
2648 mutex_enter(&zcw->zcw_lock);
2649
2650 /*
2651 * The timeout is scaled based on the lwb latency to avoid
2652 * significantly impacting the latency of each individual itx.
2653 * For more details, see the comment at the bottom of the
2654 * zil_process_commit_list() function.
2655 */
2656 int pct = MAX(zfs_commit_timeout_pct, 1);
2657 hrtime_t sleep = (zilog->zl_last_lwb_latency * pct) / 100;
2658 hrtime_t wakeup = gethrtime() + sleep;
2659 boolean_t timedout = B_FALSE;
2660
2661 while (!zcw->zcw_done) {
2662 ASSERT(MUTEX_HELD(&zcw->zcw_lock));
2663
2664 lwb_t *lwb = zcw->zcw_lwb;
2665
2666 /*
2667 * Usually, the waiter will have a non-NULL lwb field here,
2668 * but it's possible for it to be NULL as a result of
2669 * zil_commit() racing with spa_sync().
2670 *
2671 * When zil_clean() is called, it's possible for the itxg
2672 * list (which may be cleaned via a taskq) to contain
2673 * commit itxs. When this occurs, the commit waiters linked
2674 * off of these commit itxs will not be committed to an
2675 * lwb. Additionally, these commit waiters will not be
2676 * marked done until zil_commit_waiter_skip() is called via
2677 * zil_itxg_clean().
2678 *
2679 * Thus, it's possible for this commit waiter (i.e. the
2680 * "zcw" variable) to be found in this "in between" state;
2681 * where it's "zcw_lwb" field is NULL, and it hasn't yet
2682 * been skipped, so it's "zcw_done" field is still B_FALSE.
2683 */
2684 IMPLY(lwb != NULL, lwb->lwb_state != LWB_STATE_CLOSED);
2685
2686 if (lwb != NULL && lwb->lwb_state == LWB_STATE_OPENED) {
2687 ASSERT3B(timedout, ==, B_FALSE);
2688
2689 /*
2690 * If the lwb hasn't been issued yet, then we
2691 * need to wait with a timeout, in case this
2692 * function needs to issue the lwb after the
2693 * timeout is reached; responsibility (2) from
2694 * the comment above this function.
2695 */
2696 int rc = cv_timedwait_hires(&zcw->zcw_cv,
2697 &zcw->zcw_lock, wakeup, USEC2NSEC(1),
2698 CALLOUT_FLAG_ABSOLUTE);

Callers 1

zil_commit_implFunction · 0.70

Calls 7

spa_writeableFunction · 0.85
mutex_enterFunction · 0.85
cv_waitFunction · 0.85
mutex_exitFunction · 0.85
gethrtimeFunction · 0.50
cv_timedwait_hiresFunction · 0.50

Tested by

no test coverage detected