Allow metaslab to be unloaded even when not freed from

On large systems, the memory used by loaded metaslabs can become
a concern. While range trees are a fairly efficient data structure, 
on heavily fragmented pools they can still consume a significant 
amount of memory. This problem is amplified when we fail to unload 
metaslabs that we aren't using. Currently, we only unload a metaslab 
during metaslab_sync_done; in order for that function to be called 
on a given metaslab in a given txg, we have to have dirtied that 
metaslab in that txg. If the dirtying was the result of an allocation, 
we wouldn't be unloading it (since it wouldn't be 8 txgs since it 
was selected), so in effect we only unload a metaslab during txgs 
where it's being freed from.

We move the unload logic from sync_done to a new function, and 
call that function on all metaslabs in a given vdev during 
vdev_sync_done().

Reviewed-by: Richard Elling <Richard.Elling@RichardElling.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Paul Dagnelie <pcd@delphix.com>
Closes #8837
This commit is contained in:
Paul Dagnelie
2019-06-06 19:10:43 -07:00
committed by Brian Behlendorf
parent 876d76be34
commit 893a6d62c1
3 changed files with 40 additions and 22 deletions
+14
View File
@@ -3234,6 +3234,20 @@ vdev_sync_done(vdev_t *vd, uint64_t txg)
!= NULL)
metaslab_sync_done(msp, txg);
/*
* Because this function is only called on dirty vdevs, it's possible
* we won't consider all metaslabs for unloading on every
* txg. However, unless the system is largely idle it is likely that
* we will dirty all vdevs within a few txgs.
*/
for (int i = 0; i < vd->vdev_ms_count; i++) {
msp = vd->vdev_ms[i];
mutex_enter(&msp->ms_lock);
if (msp->ms_sm != NULL)
metaslab_potentially_unload(msp, txg);
mutex_exit(&msp->ms_lock);
}
if (reassess)
metaslab_sync_reassess(vd->vdev_mg);
}