diff options
author | Alexander Motin <[email protected]> | 2021-06-16 20:19:34 -0400 |
---|---|---|
committer | GitHub <[email protected]> | 2021-06-16 18:19:34 -0600 |
commit | c4c162c1e8ff9ce8833014711875d18df520096c (patch) | |
tree | a056dcb7b82161a9cc2826c70a00998014571e03 /module/os/freebsd/zfs/abd_os.c | |
parent | 9ffcaa370aee6871c92c7c84aa65942fba63a884 (diff) |
Use wmsum for arc, abd, dbuf and zfetch statistics. (#12172)
wmsum was designed exactly for cases like these with many updates
and rare reads. It allows to completely avoid atomic operations on
congested global variables.
Reviewed-by: Brian Behlendorf <[email protected]>
Reviewed-by: Mark Maybee <[email protected]>
Signed-off-by: Alexander Motin <[email protected]>
Sponsored-By: iXsystems, Inc.
Closes #12172
Diffstat (limited to 'module/os/freebsd/zfs/abd_os.c')
-rw-r--r-- | module/os/freebsd/zfs/abd_os.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/module/os/freebsd/zfs/abd_os.c b/module/os/freebsd/zfs/abd_os.c index 00aa21c6c..47adc2278 100644 --- a/module/os/freebsd/zfs/abd_os.c +++ b/module/os/freebsd/zfs/abd_os.c @@ -69,6 +69,15 @@ static abd_stats_t abd_stats = { { "linear_data_size", KSTAT_DATA_UINT64 }, }; +struct { + wmsum_t abdstat_struct_size; + wmsum_t abdstat_scatter_cnt; + wmsum_t abdstat_scatter_data_size; + wmsum_t abdstat_scatter_chunk_waste; + wmsum_t abdstat_linear_cnt; + wmsum_t abdstat_linear_data_size; +} abd_sums; + /* * The size of the chunks ABD allocates. Because the sizes allocated from the * kmem_cache can't change, this tunable can only be modified at boot. Changing @@ -271,16 +280,46 @@ abd_free_zero_scatter(void) kmem_free(abd_zero_buf, zfs_abd_chunk_size); } +static int +abd_kstats_update(kstat_t *ksp, int rw) +{ + abd_stats_t *as = ksp->ks_data; + + if (rw == KSTAT_WRITE) + return (EACCES); + as->abdstat_struct_size.value.ui64 = + wmsum_value(&abd_sums.abdstat_struct_size); + as->abdstat_scatter_cnt.value.ui64 = + wmsum_value(&abd_sums.abdstat_scatter_cnt); + as->abdstat_scatter_data_size.value.ui64 = + wmsum_value(&abd_sums.abdstat_scatter_data_size); + as->abdstat_scatter_chunk_waste.value.ui64 = + wmsum_value(&abd_sums.abdstat_scatter_chunk_waste); + as->abdstat_linear_cnt.value.ui64 = + wmsum_value(&abd_sums.abdstat_linear_cnt); + as->abdstat_linear_data_size.value.ui64 = + wmsum_value(&abd_sums.abdstat_linear_data_size); + return (0); +} + void abd_init(void) { abd_chunk_cache = kmem_cache_create("abd_chunk", zfs_abd_chunk_size, 0, NULL, NULL, NULL, NULL, 0, KMC_NODEBUG); + wmsum_init(&abd_sums.abdstat_struct_size, 0); + wmsum_init(&abd_sums.abdstat_scatter_cnt, 0); + wmsum_init(&abd_sums.abdstat_scatter_data_size, 0); + wmsum_init(&abd_sums.abdstat_scatter_chunk_waste, 0); + wmsum_init(&abd_sums.abdstat_linear_cnt, 0); + wmsum_init(&abd_sums.abdstat_linear_data_size, 0); + abd_ksp = kstat_create("zfs", 0, "abdstats", "misc", KSTAT_TYPE_NAMED, sizeof (abd_stats) / sizeof (kstat_named_t), KSTAT_FLAG_VIRTUAL); if (abd_ksp != NULL) { abd_ksp->ks_data = &abd_stats; + abd_ksp->ks_update = abd_kstats_update; kstat_install(abd_ksp); } @@ -297,6 +336,13 @@ abd_fini(void) abd_ksp = NULL; } + wmsum_fini(&abd_sums.abdstat_struct_size); + wmsum_fini(&abd_sums.abdstat_scatter_cnt); + wmsum_fini(&abd_sums.abdstat_scatter_data_size); + wmsum_fini(&abd_sums.abdstat_scatter_chunk_waste); + wmsum_fini(&abd_sums.abdstat_linear_cnt); + wmsum_fini(&abd_sums.abdstat_linear_data_size); + kmem_cache_destroy(abd_chunk_cache); abd_chunk_cache = NULL; } |