From c8ba864798baf5652e0abc766f79a67ba090f661 Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Fri, 22 Jan 2021 14:34:32 -0700 Subject: [PATCH] ZFS: add mutex protection to metaslab_class_t.mc_historgram The mc_histogram fields were unprotected when that code was first written in "Illumos 4976-4984 - metaslab improvements" (OpenZFS f3a7f6610f2df0217ba3b99099019417a954b673). The lock wasn't added until 3dfb57a35e8cbaa7c424611235d669f3c575ada1, though it's unclear exactly which fields it's supposed to protect. In any case, it wasn't until vdev_load was parallelized that any code attempted concurrent access to those fields. Signed-off-by: Alan Somers --- module/zfs/metaslab.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/module/zfs/metaslab.c b/module/zfs/metaslab.c index bed6bf64c928..112b90e6776e 100644 --- a/module/zfs/metaslab.c +++ b/module/zfs/metaslab.c @@ -522,6 +522,7 @@ metaslab_class_histogram_verify(metaslab_class_t *mc) mc_hist = kmem_zalloc(sizeof (uint64_t) * RANGE_TREE_HISTOGRAM_SIZE, KM_SLEEP); + mutex_enter(&mc->mc_lock); for (int c = 0; c < rvd->vdev_children; c++) { vdev_t *tvd = rvd->vdev_child[c]; metaslab_group_t *mg = tvd->vdev_mg; @@ -542,6 +543,7 @@ metaslab_class_histogram_verify(metaslab_class_t *mc) for (i = 0; i < RANGE_TREE_HISTOGRAM_SIZE; i++) VERIFY3U(mc_hist[i], ==, mc->mc_histogram[i]); + mutex_exit(&mc->mc_lock); kmem_free(mc_hist, sizeof (uint64_t) * RANGE_TREE_HISTOGRAM_SIZE); } @@ -1053,12 +1055,14 @@ metaslab_group_histogram_add(metaslab_group_t *mg, metaslab_t *msp) return; mutex_enter(&mg->mg_lock); + mutex_enter(&mc->mc_lock); for (int i = 0; i < SPACE_MAP_HISTOGRAM_SIZE; i++) { mg->mg_histogram[i + ashift] += msp->ms_sm->sm_phys->smp_histogram[i]; mc->mc_histogram[i + ashift] += msp->ms_sm->sm_phys->smp_histogram[i]; } + mutex_exit(&mc->mc_lock); mutex_exit(&mg->mg_lock); } @@ -1073,6 +1077,7 @@ metaslab_group_histogram_remove(metaslab_group_t *mg, metaslab_t *msp) return; mutex_enter(&mg->mg_lock); + mutex_enter(&mc->mc_lock); for (int i = 0; i < SPACE_MAP_HISTOGRAM_SIZE; i++) { ASSERT3U(mg->mg_histogram[i + ashift], >=, msp->ms_sm->sm_phys->smp_histogram[i]); @@ -1084,6 +1089,7 @@ metaslab_group_histogram_remove(metaslab_group_t *mg, metaslab_t *msp) mc->mc_histogram[i + ashift] -= msp->ms_sm->sm_phys->smp_histogram[i]; } + mutex_exit(&mc->mc_lock); mutex_exit(&mg->mg_lock); }