Skip to content

Commit efb8cd7

Browse files
committed
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. Signed-off-by: Alexander Motin <[email protected]> Sponsored by: iXsystems, Inc.
1 parent af7d609 commit efb8cd7

File tree

1 file changed

+8
-5
lines changed

1 file changed

+8
-5
lines changed

module/zfs/dmu.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2521,7 +2521,8 @@ int
25212521
dmu_offset_next(objset_t *os, uint64_t object, boolean_t hole, uint64_t *off)
25222522
{
25232523
dnode_t *dn;
2524-
int restarted = 0, err;
2524+
uint64_t txg, maxtxg = 0;
2525+
int err;
25252526

25262527
restart:
25272528
err = dnode_hold(os, object, FTAG, &dn);
@@ -2537,19 +2538,21 @@ dmu_offset_next(objset_t *os, uint64_t object, boolean_t hole, uint64_t *off)
25372538
* must be synced to disk to accurately report holes.
25382539
*
25392540
* Provided a RL_READER rangelock spanning 0-UINT64_MAX is
2540-
* held by the caller only a single restart will be required.
2541+
* held by the caller only limited restarts will be required.
25412542
* We tolerate callers which do not hold the rangelock by
25422543
* returning EBUSY and not reporting holes after one restart.
25432544
*/
25442545
if (zfs_dmu_offset_next_sync) {
25452546
rw_exit(&dn->dn_struct_rwlock);
25462547
dnode_rele(dn, FTAG);
25472548

2548-
if (restarted)
2549+
if (maxtxg == 0) {
2550+
txg = spa_last_synced_txg(dmu_objset_spa(os));
2551+
maxtxg = txg + TXG_CONCURRENT_STATES;
2552+
} else if (txg >= maxtxg)
25492553
return (SET_ERROR(EBUSY));
25502554

2551-
txg_wait_synced(dmu_objset_pool(os), 0);
2552-
restarted = 1;
2555+
txg_wait_synced(dmu_objset_pool(os), ++txg);
25532556
goto restart;
25542557
}
25552558

0 commit comments

Comments
 (0)