Skip to content

Commit

Permalink
Merge pull request openzfs#816 from ahrens/merge
Browse files Browse the repository at this point in the history
Merge with `Allow MMP to bypass waiting for other threads`
  • Loading branch information
ahrens authored Apr 21, 2023
2 parents 1f28ff8 + 8b8b49f commit bbc2095
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 6 deletions.
2 changes: 2 additions & 0 deletions include/sys/spa.h
Original file line number Diff line number Diff line change
Expand Up @@ -980,6 +980,8 @@ extern int spa_import_progress_set_state(uint64_t pool_guid,
extern int spa_config_tryenter(spa_t *spa, int locks, const void *tag,
krw_t rw);
extern void spa_config_enter(spa_t *spa, int locks, const void *tag, krw_t rw);
extern void spa_config_enter_mmp(spa_t *spa, int locks, const void *tag,
krw_t rw);
extern void spa_config_exit(spa_t *spa, int locks, const void *tag);
extern int spa_config_held(spa_t *spa, int locks, krw_t rw);
extern void spa_config_enter_read_priority(spa_t *, int);
Expand Down
2 changes: 1 addition & 1 deletion module/zfs/mmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ mmp_write_uberblock(spa_t *spa)
uint64_t offset;

hrtime_t lock_acquire_time = gethrtime();
spa_config_enter(spa, SCL_STATE, mmp_tag, RW_READER);
spa_config_enter_mmp(spa, SCL_STATE, mmp_tag, RW_READER);
lock_acquire_time = gethrtime() - lock_acquire_time;
if (lock_acquire_time > (MSEC2NSEC(MMP_MIN_INTERVAL) / 10))
zfs_dbgmsg("MMP SCL_STATE acquisition pool '%s' took %llu ns "
Expand Down
29 changes: 26 additions & 3 deletions module/zfs/spa_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -551,8 +551,9 @@ spa_config_enter_read_priority(spa_t *spa, int locks)
}
}

void
spa_config_enter(spa_t *spa, int locks, const void *tag, krw_t rw)
static void
spa_config_enter_impl(spa_t *spa, int locks, const void *tag, krw_t rw,
int mmp_flag)
{
(void) tag;
int wlocks_held = 0;
Expand All @@ -570,7 +571,8 @@ spa_config_enter(spa_t *spa, int locks, const void *tag, krw_t rw)
continue;
mutex_enter(&scl->scl_lock);
if (rw == RW_READER) {
while (scl->scl_writer || scl->scl_write_wanted) {
while (scl->scl_writer ||
(!mmp_flag && scl->scl_write_wanted)) {
cv_wait(&scl->scl_cv, &scl->scl_lock);
}
} else {
Expand Down Expand Up @@ -598,6 +600,27 @@ spa_config_enter(spa_t *spa, int locks, const void *tag, krw_t rw)
ASSERT3U(wlocks_held, <=, locks);
}

void
spa_config_enter(spa_t *spa, int locks, const void *tag, krw_t rw)
{
spa_config_enter_impl(spa, locks, tag, rw, 0);
}

/*
* The spa_config_enter_mmp() allows the mmp thread to cut in front of
* outstanding write lock requests. This is needed since the mmp updates are
* time sensitive and failure to service them promptly will result in a
* suspended pool. This pool suspension has been seen in practice when there is
* a single disk in a pool that is responding slowly and presumably about to
* fail.
*/

void
spa_config_enter_mmp(spa_t *spa, int locks, const void *tag, krw_t rw)
{
spa_config_enter_impl(spa, locks, tag, rw, 1);
}

void
spa_config_exit(spa_t *spa, int locks, const void *tag)
{
Expand Down
9 changes: 7 additions & 2 deletions tests/zfs-tests/tests/functional/rsend/send-c_volume.ksh
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

function cleanup
{
rm $BACKDIR/copy
log_must_busy zfs destroy -r $vol
cleanup_pool $POOL2
}
Expand Down Expand Up @@ -60,7 +61,9 @@ log_must eval "zfs recv -d $POOL2 <$BACKDIR/full"

verify_stream_size $BACKDIR/full $vol
verify_stream_size $BACKDIR/full $vol2
md5=$(dd if=$voldev2 bs=1024k count=$megs 2>/dev/null | md5digest)
block_device_wait $voldev2
log_must dd if=$voldev2 of=$BACKDIR/copy bs=1024k count=$megs
md5=$(md5digest $BACKDIR/copy)
[[ $md5 = $md5_1 ]] || log_fail "md5 mismatch: $md5 != $md5_1"

# Repeat, for an incremental send
Expand All @@ -72,7 +75,9 @@ log_must eval "zfs recv -d $POOL2 <$BACKDIR/inc"

verify_stream_size $BACKDIR/inc $vol 90 $vol@snap
verify_stream_size $BACKDIR/inc $vol2 90 $vol2@snap
md5=$(dd skip=$megs if=$voldev2 bs=1024k count=$megs 2>/dev/null | md5digest)
block_device_wait $voldev2
log_must dd skip=$megs if=$voldev2 of=$BACKDIR/copy bs=1024k count=$megs
md5=$(md5digest $BACKDIR/copy)
[[ $md5 = $md5_2 ]] || log_fail "md5 mismatch: $md5 != $md5_2"

log_pass "Verify compressed send works with volumes"

0 comments on commit bbc2095

Please sign in to comment.