diff --git a/include/sys/metaslab.h b/include/sys/metaslab.h index 0df6e5f81fc1..6150e96e3dfa 100644 --- a/include/sys/metaslab.h +++ b/include/sys/metaslab.h @@ -112,12 +112,12 @@ boolean_t metaslab_class_throttle_reserve(metaslab_class_t *, int, int, void metaslab_class_throttle_unreserve(metaslab_class_t *, int, int, zio_t *); void metaslab_class_evict_old(metaslab_class_t *, uint64_t); uint64_t metaslab_class_get_alloc(metaslab_class_t *); +uint64_t metaslab_class_get_dalloc(metaslab_class_t *); uint64_t metaslab_class_get_space(metaslab_class_t *); uint64_t metaslab_class_get_dspace(metaslab_class_t *); uint64_t metaslab_class_get_deferred(metaslab_class_t *); -void metaslab_space_update(vdev_t *, metaslab_class_t *, - int64_t, int64_t, int64_t); +void metaslab_space_update(metaslab_group_t *, int64_t, int64_t, int64_t); metaslab_group_t *metaslab_group_create(metaslab_class_t *, vdev_t *, int); void metaslab_group_destroy(metaslab_group_t *); diff --git a/include/sys/metaslab_impl.h b/include/sys/metaslab_impl.h index 4f434291ddbf..96f7aae92e1a 100644 --- a/include/sys/metaslab_impl.h +++ b/include/sys/metaslab_impl.h @@ -196,10 +196,12 @@ struct metaslab_class { uint64_t mc_alloc_groups; /* # of allocatable groups */ - uint64_t mc_alloc; /* total allocated space */ - uint64_t mc_deferred; /* total deferred frees */ + uint64_t mc_alloc; /* allocated space */ + uint64_t mc_dalloc; /* deflated allocated space */ + uint64_t mc_deferred; /* deferred frees */ + uint64_t mc_ddeferred; /* deflated deferred frees */ uint64_t mc_space; /* total space (alloc + free) */ - uint64_t mc_dspace; /* total deflated space */ + uint64_t mc_dspace; /* deflated total space */ uint64_t mc_histogram[RANGE_TREE_HISTOGRAM_SIZE]; /* diff --git a/module/zfs/metaslab.c b/module/zfs/metaslab.c index 7eda653a810e..9a4a09ca5dc0 100644 --- a/module/zfs/metaslab.c +++ b/module/zfs/metaslab.c @@ -433,10 +433,12 @@ metaslab_class_destroy(metaslab_class_t *mc) { spa_t *spa = mc->mc_spa; - ASSERT(mc->mc_alloc == 0); - ASSERT(mc->mc_deferred == 0); - ASSERT(mc->mc_space == 0); - ASSERT(mc->mc_dspace == 0); + ASSERT0(mc->mc_alloc); + ASSERT0(mc->mc_dalloc); + ASSERT0(mc->mc_deferred); + ASSERT0(mc->mc_ddeferred); + ASSERT0(mc->mc_space); + ASSERT0(mc->mc_dspace); for (int i = 0; i < spa->spa_alloc_count; i++) { metaslab_class_allocator_t *mca = &mc->mc_allocator[i]; @@ -477,10 +479,13 @@ metaslab_class_validate(metaslab_class_t *mc) static void metaslab_class_space_update(metaslab_class_t *mc, int64_t alloc_delta, - int64_t defer_delta, int64_t space_delta, int64_t dspace_delta) + int64_t dalloc_delta, int64_t deferred_delta, int64_t ddeferred_delta, + int64_t space_delta, int64_t dspace_delta) { atomic_add_64(&mc->mc_alloc, alloc_delta); - atomic_add_64(&mc->mc_deferred, defer_delta); + atomic_add_64(&mc->mc_dalloc, dalloc_delta); + atomic_add_64(&mc->mc_deferred, deferred_delta); + atomic_add_64(&mc->mc_ddeferred, ddeferred_delta); atomic_add_64(&mc->mc_space, space_delta); atomic_add_64(&mc->mc_dspace, dspace_delta); } @@ -488,25 +493,34 @@ metaslab_class_space_update(metaslab_class_t *mc, int64_t alloc_delta, uint64_t metaslab_class_get_alloc(metaslab_class_t *mc) { - return (mc->mc_alloc); + return (atomic_load_64(&mc->mc_alloc)); +} + +uint64_t +metaslab_class_get_dalloc(metaslab_class_t *mc) +{ + return (spa_deflate(mc->mc_spa) ? atomic_load_64(&mc->mc_dalloc) : + atomic_load_64(&mc->mc_alloc)); } uint64_t metaslab_class_get_deferred(metaslab_class_t *mc) { - return (mc->mc_deferred); + return (spa_deflate(mc->mc_spa) ? atomic_load_64(&mc->mc_ddeferred) : + atomic_load_64(&mc->mc_deferred)); } uint64_t metaslab_class_get_space(metaslab_class_t *mc) { - return (mc->mc_space); + return (atomic_load_64(&mc->mc_space)); } uint64_t metaslab_class_get_dspace(metaslab_class_t *mc) { - return (spa_deflate(mc->mc_spa) ? mc->mc_dspace : mc->mc_space); + return (spa_deflate(mc->mc_spa) ? atomic_load_64(&mc->mc_dspace) : + atomic_load_64(&mc->mc_space)); } void @@ -2631,16 +2645,21 @@ metaslab_set_selected_txg(metaslab_t *msp, uint64_t txg) } void -metaslab_space_update(vdev_t *vd, metaslab_class_t *mc, int64_t alloc_delta, +metaslab_space_update(metaslab_group_t *mg, int64_t alloc_delta, int64_t defer_delta, int64_t space_delta) { + vdev_t *vd = mg->mg_vd; + int64_t dalloc_delta = vdev_deflated_space(vd, alloc_delta); + int64_t ddefer_delta = vdev_deflated_space(vd, defer_delta); + int64_t dspace_delta = vdev_deflated_space(vd, space_delta); + vdev_space_update(vd, alloc_delta, defer_delta, space_delta); ASSERT3P(vd->vdev_spa->spa_root_vdev, ==, vd->vdev_parent); ASSERT(vd->vdev_ms_count != 0); - metaslab_class_space_update(mc, alloc_delta, defer_delta, space_delta, - vdev_deflated_space(vd, space_delta)); + metaslab_class_space_update(mg->mg_class, alloc_delta, dalloc_delta, + defer_delta, ddefer_delta, space_delta, dspace_delta); } int @@ -2738,8 +2757,7 @@ metaslab_init(metaslab_group_t *mg, uint64_t id, uint64_t object, */ if (txg <= TXG_INITIAL) { metaslab_sync_done(ms, 0); - metaslab_space_update(vd, mg->mg_class, - metaslab_allocated_space(ms), 0, 0); + metaslab_space_update(mg, metaslab_allocated_space(ms), 0, 0); } if (txg != 0) { @@ -2801,9 +2819,8 @@ metaslab_fini(metaslab_t *msp) * subtracted. */ if (!msp->ms_new) { - metaslab_space_update(vd, mg->mg_class, - -metaslab_allocated_space(msp), 0, -msp->ms_size); - + metaslab_space_update(mg, -metaslab_allocated_space(msp), 0, + -msp->ms_size); } space_map_close(msp->ms_sm); msp->ms_sm = NULL; @@ -4290,7 +4307,7 @@ metaslab_sync_done(metaslab_t *msp, uint64_t txg) if (msp->ms_new) { /* this is a new metaslab, add its capacity to the vdev */ - metaslab_space_update(vd, mg->mg_class, 0, 0, msp->ms_size); + metaslab_space_update(mg, 0, 0, msp->ms_size); /* there should be no allocations nor frees at this point */ VERIFY0(msp->ms_allocated_this_txg); @@ -4318,8 +4335,7 @@ metaslab_sync_done(metaslab_t *msp, uint64_t txg) } else { defer_delta -= range_tree_space(*defer_tree); } - metaslab_space_update(vd, mg->mg_class, alloc_delta + defer_delta, - defer_delta, 0); + metaslab_space_update(mg, alloc_delta + defer_delta, defer_delta, 0); if (spa_syncing_log_sm(spa) == NULL) { /* @@ -5253,8 +5269,16 @@ metaslab_alloc_dva(spa_t *spa, metaslab_class_t *mc, uint64_t psize, */ if (mca->mca_aliquot == 0 && metaslab_bias_enabled) { vdev_stat_t *vs = &vd->vdev_stat; - int64_t vs_free = vs->vs_space - vs->vs_alloc; - int64_t mc_free = mc->mc_space - mc->mc_alloc; + uint64_t vs_space = + atomic_load_64(&vs->vs_space); + uint64_t mc_space = + atomic_load_64(&mc->mc_space); + uint64_t mc_alloc = + atomic_load_64(&mc->mc_alloc); + uint64_t vs_alloc = + atomic_load_64(&vs->vs_alloc); + int64_t vs_free = vs_space - vs_alloc; + int64_t mc_free = mc_space - mc_alloc; int64_t ratio; /* diff --git a/module/zfs/spa.c b/module/zfs/spa.c index 886867b739f0..8704139ce3f4 100644 --- a/module/zfs/spa.c +++ b/module/zfs/spa.c @@ -6349,6 +6349,7 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props, spa->spa_removing_phys.sr_removing_vdev = -1; spa->spa_removing_phys.sr_prev_indirect_vdev = -1; spa->spa_indirect_vdevs_loaded = B_TRUE; + spa->spa_deflate = (version >= SPA_VERSION_RAIDZ_DEFLATE); /* * Create "The Godfather" zio to hold all async IOs @@ -6478,7 +6479,6 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props, /* Newly created pools with the right version are always deflated. */ if (version >= SPA_VERSION_RAIDZ_DEFLATE) { - spa->spa_deflate = TRUE; if (zap_add(spa->spa_meta_objset, DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_DEFLATE, sizeof (uint64_t), 1, &spa->spa_deflate, tx) != 0) { diff --git a/module/zfs/spa_log_spacemap.c b/module/zfs/spa_log_spacemap.c index 873089a53e34..c0f58c95a3a4 100644 --- a/module/zfs/spa_log_spacemap.c +++ b/module/zfs/spa_log_spacemap.c @@ -1253,10 +1253,9 @@ spa_ld_log_sm_data(spa_t *spa) range_tree_space(m->ms_unflushed_allocs) - range_tree_space(m->ms_unflushed_frees); - vdev_t *vd = m->ms_group->mg_vd; - metaslab_space_update(vd, m->ms_group->mg_class, + metaslab_space_update(m->ms_group, range_tree_space(m->ms_unflushed_allocs), 0, 0); - metaslab_space_update(vd, m->ms_group->mg_class, + metaslab_space_update(m->ms_group, -range_tree_space(m->ms_unflushed_frees), 0, 0); ASSERT0(m->ms_weight & METASLAB_ACTIVE_MASK); diff --git a/module/zfs/spa_misc.c b/module/zfs/spa_misc.c index d2983ba15313..4a986802dcc5 100644 --- a/module/zfs/spa_misc.c +++ b/module/zfs/spa_misc.c @@ -1899,6 +1899,11 @@ spa_update_dspace(spa_t *spa) ASSERT3U(spa->spa_dspace, >=, spa->spa_nonallocating_dspace); spa->spa_dspace -= spa->spa_nonallocating_dspace; } + spa->spa_dspace = spa->spa_dspace + + metaslab_class_get_dalloc(spa_special_class(spa)) + + metaslab_class_get_dalloc(spa_dedup_class(spa)) + + ddt_get_dedup_dspace(spa) + + brt_get_dspace(spa); } /*