Skip to content

Commit 3eb93ef

Browse files
amotinbehlendorf
authored andcommitted
Reduce zfs_dmu_offset_next_sync penalty
Looking on txg_wait_synced(, 0) I've noticed that it always syncs 5 TXGs: 3 TXG_CONCURRENT_STATES + 2 TXG_DEFER_SIZE. But in case of dmu_offset_next() we do not care about deferred frees. And even concurrent TXGs we might not need sync all 3 if the dnode was not dirtied in last few TXGs. This patch makes dmu_offset_next() to sync one TXG at a time until the dnode is clean, but no more than 3 TXG_CONCURRENT_STATES times. My tests with random simultaneous writes and seeks over many files on HDD pool show 7-14% performance increase. Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Rob Norris <[email protected]> Signed-off-by: Alexander Motin <[email protected]> Sponsored by: iXsystems, Inc. Closes #17434
1 parent bbb3d58 commit 3eb93ef

File tree

1 file changed

+10
-6
lines changed

1 file changed

+10
-6
lines changed

module/zfs/dmu.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2506,7 +2506,8 @@ int
25062506
dmu_offset_next(objset_t *os, uint64_t object, boolean_t hole, uint64_t *off)
25072507
{
25082508
dnode_t *dn;
2509-
int restarted = 0, err;
2509+
uint64_t txg, maxtxg = 0;
2510+
int err;
25102511

25112512
restart:
25122513
err = dnode_hold(os, object, FTAG, &dn);
@@ -2522,19 +2523,22 @@ dmu_offset_next(objset_t *os, uint64_t object, boolean_t hole, uint64_t *off)
25222523
* must be synced to disk to accurately report holes.
25232524
*
25242525
* Provided a RL_READER rangelock spanning 0-UINT64_MAX is
2525-
* held by the caller only a single restart will be required.
2526+
* held by the caller only limited restarts will be required.
25262527
* We tolerate callers which do not hold the rangelock by
2527-
* returning EBUSY and not reporting holes after one restart.
2528+
* returning EBUSY and not reporting holes after at most
2529+
* TXG_CONCURRENT_STATES (3) restarts.
25282530
*/
25292531
if (zfs_dmu_offset_next_sync) {
25302532
rw_exit(&dn->dn_struct_rwlock);
25312533
dnode_rele(dn, FTAG);
25322534

2533-
if (restarted)
2535+
if (maxtxg == 0) {
2536+
txg = spa_last_synced_txg(dmu_objset_spa(os));
2537+
maxtxg = txg + TXG_CONCURRENT_STATES;
2538+
} else if (txg >= maxtxg)
25342539
return (SET_ERROR(EBUSY));
25352540

2536-
txg_wait_synced(dmu_objset_pool(os), 0);
2537-
restarted = 1;
2541+
txg_wait_synced(dmu_objset_pool(os), ++txg);
25382542
goto restart;
25392543
}
25402544

0 commit comments

Comments
 (0)