aboutsummaryrefslogtreecommitdiffstats
path: root/module/zfs/spa_misc.c
diff options
context:
space:
mode:
authorAlexander Motin <[email protected]>2024-11-10 17:29:25 -0500
committerBrian Behlendorf <[email protected]>2024-11-15 15:04:11 -0800
commitfd6e8c1d2a5c8d95d509b691b81c66597e354981 (patch)
treec0e097909e2d2bc381ee2c6ab0ab824c9248ce14 /module/zfs/spa_misc.c
parent309ce6303fa7e455e9adee0674a29685bdbbcc8d (diff)
BRT: Rework structures and locks to be per-vdev
While block cloning operation from the beginning was made per-vdev, before this change most of its data were protected by two pool- wide locks. It created lots of lock contention in many workload. This change makes most of block cloning data structures per-vdev, which allows to lock them separately. The only pool-wide lock now it spa_brt_lock, protecting array of per-vdev pointers and in most cases taken as reader. Also this splits per-vdev locks into three different ones: bv_pending_lock protects the AVL-tree of pending operations in open context, bv_mos_entries_lock protects BRT ZAP object from while being prefetched, and bv_lock protects the rest of per-vdev context during TXG commit process. There should be no functional difference aside of some optimizations. Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Pawel Jakub Dawidek <[email protected]> Reviewed-by: Brian Atkinson <[email protected]> Signed-off-by: Alexander Motin <[email protected]> Sponsored by: iXsystems, Inc. Closes #16740
Diffstat (limited to 'module/zfs/spa_misc.c')
-rw-r--r--module/zfs/spa_misc.c17
1 files changed, 6 insertions, 11 deletions
diff --git a/module/zfs/spa_misc.c b/module/zfs/spa_misc.c
index f486513fc..32542e7ce 100644
--- a/module/zfs/spa_misc.c
+++ b/module/zfs/spa_misc.c
@@ -1870,13 +1870,7 @@ spa_get_slop_space(spa_t *spa)
if (spa->spa_dedup_dspace == ~0ULL)
spa_update_dspace(spa);
- /*
- * spa_get_dspace() includes the space only logically "used" by
- * deduplicated data, so since it's not useful to reserve more
- * space with more deduplicated data, we subtract that out here.
- */
- space =
- spa_get_dspace(spa) - spa->spa_dedup_dspace - brt_get_dspace(spa);
+ space = spa->spa_rdspace;
slop = MIN(space >> spa_slop_shift, spa_max_slop);
/*
@@ -1912,8 +1906,7 @@ spa_get_checkpoint_space(spa_t *spa)
void
spa_update_dspace(spa_t *spa)
{
- spa->spa_dspace = metaslab_class_get_dspace(spa_normal_class(spa)) +
- ddt_get_dedup_dspace(spa) + brt_get_dspace(spa);
+ spa->spa_rdspace = metaslab_class_get_dspace(spa_normal_class(spa));
if (spa->spa_nonallocating_dspace > 0) {
/*
* Subtract the space provided by all non-allocating vdevs that
@@ -1933,9 +1926,11 @@ spa_update_dspace(spa_t *spa)
* doesn't matter that the data we are moving may be
* allocated twice (on the old device and the new device).
*/
- ASSERT3U(spa->spa_dspace, >=, spa->spa_nonallocating_dspace);
- spa->spa_dspace -= spa->spa_nonallocating_dspace;
+ ASSERT3U(spa->spa_rdspace, >=, spa->spa_nonallocating_dspace);
+ spa->spa_rdspace -= spa->spa_nonallocating_dspace;
}
+ spa->spa_dspace = spa->spa_rdspace + ddt_get_dedup_dspace(spa) +
+ brt_get_dspace(spa);
}
/*