mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-30 18:56:23 +03:00
Introduce dsl_dir_diduse_transfer_space()
Most of dsl_dir_diduse_space() and dsl_dir_transfer_space() CPU time is a dd_lock overhead and time spent in dmu_buf_will_dirty(). Calling them one after another is a waste of time and even more contention. Doing that twice for each rewritten block within dbuf_write_done() via dsl_dataset_block_kill() and dsl_dataset_block_born() created one of the biggest CPU overheads in case of small blocks rewrite. dsl_dir_diduse_transfer_space() combines functionality of these two functions for cases where it is needed, but without double overhead, practically for the cost of dsl_dir_diduse_space() or even cheaper. While there, optimize dsl_dir_phys() calls in dsl_dir_diduse_space() and dsl_dir_transfer_space(). It seems Clang detects some aliasing there, repeating dd->dd_dbuf->db_data dereference multiple times, increasing dd_lock scope and contention. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Matthew Ahrens <mahrens@delphix.com> Author: Ryan Moeller <ryan@iXsystems.com> Signed-off-by: Alexander Motin <mav@FreeBSD.org> Closes #12300
This commit is contained in:
committed by
Tony Hutter
parent
968dc13572
commit
ba76bb30a6
@@ -192,9 +192,8 @@ dsl_dataset_block_born(dsl_dataset_t *ds, const blkptr_t *bp, dmu_tx_t *tx)
|
||||
}
|
||||
|
||||
mutex_exit(&ds->ds_lock);
|
||||
dsl_dir_diduse_space(ds->ds_dir, DD_USED_HEAD, delta,
|
||||
compressed, uncompressed, tx);
|
||||
dsl_dir_transfer_space(ds->ds_dir, used - delta,
|
||||
dsl_dir_diduse_transfer_space(ds->ds_dir, delta,
|
||||
compressed, uncompressed, used,
|
||||
DD_USED_REFRSRV, DD_USED_HEAD, tx);
|
||||
}
|
||||
|
||||
@@ -291,9 +290,8 @@ dsl_dataset_block_kill(dsl_dataset_t *ds, const blkptr_t *bp, dmu_tx_t *tx,
|
||||
delta = parent_delta(ds, -used);
|
||||
dsl_dataset_phys(ds)->ds_unique_bytes -= used;
|
||||
mutex_exit(&ds->ds_lock);
|
||||
dsl_dir_diduse_space(ds->ds_dir, DD_USED_HEAD,
|
||||
delta, -compressed, -uncompressed, tx);
|
||||
dsl_dir_transfer_space(ds->ds_dir, -used - delta,
|
||||
dsl_dir_diduse_transfer_space(ds->ds_dir,
|
||||
delta, -compressed, -uncompressed, -used,
|
||||
DD_USED_REFRSRV, DD_USED_HEAD, tx);
|
||||
} else {
|
||||
dprintf_bp(bp, "putting on dead list: %s", "");
|
||||
|
||||
Reference in New Issue
Block a user