mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 18:40:43 +03:00
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 <behlendorf1@llnl.gov> Reviewed-by: Mark Maybee <mark.maybee@delphix.com> Signed-off-by: Alexander Motin <mav@FreeBSD.org> Sponsored-By: iXsystems, Inc. Closes #12172
This commit is contained in:
committed by
Brian Behlendorf
parent
9a865b7fb7
commit
6b239d1757
@@ -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
|
||||
@@ -272,16 +281,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);
|
||||
}
|
||||
|
||||
@@ -298,6 +337,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;
|
||||
}
|
||||
|
||||
@@ -132,6 +132,20 @@ static abd_stats_t abd_stats = {
|
||||
{ "scatter_sg_table_retry", KSTAT_DATA_UINT64 },
|
||||
};
|
||||
|
||||
struct {
|
||||
wmsum_t abdstat_struct_size;
|
||||
wmsum_t abdstat_linear_cnt;
|
||||
wmsum_t abdstat_linear_data_size;
|
||||
wmsum_t abdstat_scatter_cnt;
|
||||
wmsum_t abdstat_scatter_data_size;
|
||||
wmsum_t abdstat_scatter_chunk_waste;
|
||||
wmsum_t abdstat_scatter_orders[MAX_ORDER];
|
||||
wmsum_t abdstat_scatter_page_multi_chunk;
|
||||
wmsum_t abdstat_scatter_page_multi_zone;
|
||||
wmsum_t abdstat_scatter_page_alloc_retry;
|
||||
wmsum_t abdstat_scatter_sg_table_retry;
|
||||
} abd_sums;
|
||||
|
||||
#define abd_for_each_sg(abd, sg, n, i) \
|
||||
for_each_sg(ABD_SCATTER(abd).abd_sgl, sg, n, i)
|
||||
|
||||
@@ -687,6 +701,40 @@ abd_free_zero_scatter(void)
|
||||
#endif /* _KERNEL */
|
||||
}
|
||||
|
||||
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_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);
|
||||
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);
|
||||
for (int i = 0; i < MAX_ORDER; i++) {
|
||||
as->abdstat_scatter_orders[i].value.ui64 =
|
||||
wmsum_value(&abd_sums.abdstat_scatter_orders[i]);
|
||||
}
|
||||
as->abdstat_scatter_page_multi_chunk.value.ui64 =
|
||||
wmsum_value(&abd_sums.abdstat_scatter_page_multi_chunk);
|
||||
as->abdstat_scatter_page_multi_zone.value.ui64 =
|
||||
wmsum_value(&abd_sums.abdstat_scatter_page_multi_zone);
|
||||
as->abdstat_scatter_page_alloc_retry.value.ui64 =
|
||||
wmsum_value(&abd_sums.abdstat_scatter_page_alloc_retry);
|
||||
as->abdstat_scatter_sg_table_retry.value.ui64 =
|
||||
wmsum_value(&abd_sums.abdstat_scatter_sg_table_retry);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
abd_init(void)
|
||||
{
|
||||
@@ -695,6 +743,19 @@ abd_init(void)
|
||||
abd_cache = kmem_cache_create("abd_t", sizeof (abd_t),
|
||||
0, NULL, NULL, NULL, NULL, NULL, 0);
|
||||
|
||||
wmsum_init(&abd_sums.abdstat_struct_size, 0);
|
||||
wmsum_init(&abd_sums.abdstat_linear_cnt, 0);
|
||||
wmsum_init(&abd_sums.abdstat_linear_data_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);
|
||||
for (i = 0; i < MAX_ORDER; i++)
|
||||
wmsum_init(&abd_sums.abdstat_scatter_orders[i], 0);
|
||||
wmsum_init(&abd_sums.abdstat_scatter_page_multi_chunk, 0);
|
||||
wmsum_init(&abd_sums.abdstat_scatter_page_multi_zone, 0);
|
||||
wmsum_init(&abd_sums.abdstat_scatter_page_alloc_retry, 0);
|
||||
wmsum_init(&abd_sums.abdstat_scatter_sg_table_retry, 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) {
|
||||
@@ -705,6 +766,7 @@ abd_init(void)
|
||||
KSTAT_DATA_UINT64;
|
||||
}
|
||||
abd_ksp->ks_data = &abd_stats;
|
||||
abd_ksp->ks_update = abd_kstats_update;
|
||||
kstat_install(abd_ksp);
|
||||
}
|
||||
|
||||
@@ -721,6 +783,19 @@ abd_fini(void)
|
||||
abd_ksp = NULL;
|
||||
}
|
||||
|
||||
wmsum_fini(&abd_sums.abdstat_struct_size);
|
||||
wmsum_fini(&abd_sums.abdstat_linear_cnt);
|
||||
wmsum_fini(&abd_sums.abdstat_linear_data_size);
|
||||
wmsum_fini(&abd_sums.abdstat_scatter_cnt);
|
||||
wmsum_fini(&abd_sums.abdstat_scatter_data_size);
|
||||
wmsum_fini(&abd_sums.abdstat_scatter_chunk_waste);
|
||||
for (int i = 0; i < MAX_ORDER; i++)
|
||||
wmsum_fini(&abd_sums.abdstat_scatter_orders[i]);
|
||||
wmsum_fini(&abd_sums.abdstat_scatter_page_multi_chunk);
|
||||
wmsum_fini(&abd_sums.abdstat_scatter_page_multi_zone);
|
||||
wmsum_fini(&abd_sums.abdstat_scatter_page_alloc_retry);
|
||||
wmsum_fini(&abd_sums.abdstat_scatter_sg_table_retry);
|
||||
|
||||
if (abd_cache) {
|
||||
kmem_cache_destroy(abd_cache);
|
||||
abd_cache = NULL;
|
||||
|
||||
@@ -135,7 +135,7 @@ arc_available_memory(void)
|
||||
static uint64_t
|
||||
arc_evictable_memory(void)
|
||||
{
|
||||
int64_t asize = aggsum_value(&arc_size);
|
||||
int64_t asize = aggsum_value(&arc_sums.arcstat_size);
|
||||
uint64_t arc_clean =
|
||||
zfs_refcount_count(&arc_mru->arcs_esize[ARC_BUFC_DATA]) +
|
||||
zfs_refcount_count(&arc_mru->arcs_esize[ARC_BUFC_METADATA]) +
|
||||
|
||||
Reference in New Issue
Block a user