diff options
author | Paul Dagnelie <[email protected]> | 2019-08-16 08:08:21 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2019-08-16 09:08:21 -0600 |
commit | f09fda5071813751ba3fa77c28e588689795e17e (patch) | |
tree | 164564e5c5a88412d05477214c06cda69f929858 /module/zfs/arc.c | |
parent | 9323aad14d2f99d6fff1e50cce25fa6361495ec4 (diff) |
Cap metaslab memory usage
On systems with large amounts of storage and high fragmentation, a huge
amount of space can be used by storing metaslab range trees. Since
metaslabs are only unloaded during a txg sync, and only if they have
been inactive for 8 txgs, it is possible to get into a state where all
of the system's memory is consumed by range trees and metaslabs, and
txgs cannot sync. While ZFS knows how to evict ARC data when needed,
it has no such mechanism for range tree data. This can result in boot
hangs for some system configurations.
First, we add the ability to unload metaslabs outside of syncing
context. Second, we store a multilist of all loaded metaslabs, sorted
by their selection txg, so we can quickly identify the oldest
metaslabs. We use a multilist to reduce lock contention during heavy
write workloads. Finally, we add logic that will unload a metaslab
when we're loading a new metaslab, if we're using more than a certain
fraction of the available memory on range trees.
Reviewed-by: Matt Ahrens <[email protected]>
Reviewed-by: George Wilson <[email protected]>
Reviewed-by: Sebastien Roy <[email protected]>
Reviewed-by: Serapheim Dimitropoulos <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Paul Dagnelie <[email protected]>
Closes #9128
Diffstat (limited to 'module/zfs/arc.c')
-rw-r--r-- | module/zfs/arc.c | 3 |
1 files changed, 1 insertions, 2 deletions
diff --git a/module/zfs/arc.c b/module/zfs/arc.c index 90a731bff..b5fca8e26 100644 --- a/module/zfs/arc.c +++ b/module/zfs/arc.c @@ -1110,7 +1110,6 @@ static boolean_t arc_is_overflowing(void); static void arc_buf_watch(arc_buf_t *); static void arc_tuning_update(void); static void arc_prune_async(int64_t); -static uint64_t arc_all_memory(void); static arc_buf_contents_t arc_buf_type(arc_buf_hdr_t *); static uint32_t arc_bufc_to_flags(arc_buf_contents_t); @@ -4828,7 +4827,7 @@ arc_reduce_target_size(int64_t to_free) * Return maximum amount of memory that we could possibly use. Reduced * to half of all memory in user space which is primarily used for testing. */ -static uint64_t +uint64_t arc_all_memory(void) { #ifdef _KERNEL |