From 9a51738b60c2164822baefa17f8fdcebe9d82fbc Mon Sep 17 00:00:00 2001 From: Ryan Moeller Date: Fri, 27 Mar 2020 12:14:46 -0400 Subject: Let default arc_c_max be platform dependent Linux changed the default max ARC size to 1/2 of physical memory to deal with shortcomings of the Linux SLUB allocator. Other platforms do not require the same logic. Implement an arc_default_max() function to determine a default max ARC size in platform code. Reviewed-by: Brian Behlendorf Signed-off-by: Ryan Moeller Closes #10155 --- include/sys/arc.h | 1 + man/man5/zfs-module-parameters.5 | 7 +++++-- module/os/linux/zfs/arc_os.c | 10 ++++++++++ module/zfs/arc.c | 12 ++++++------ 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/include/sys/arc.h b/include/sys/arc.h index 6f56f732a..75c483918 100644 --- a/include/sys/arc.h +++ b/include/sys/arc.h @@ -298,6 +298,7 @@ void arc_tempreserve_clear(uint64_t reserve); int arc_tempreserve_space(spa_t *spa, uint64_t reserve, uint64_t txg); uint64_t arc_all_memory(void); +uint64_t arc_default_max(uint64_t min, uint64_t allmem); uint64_t arc_target_bytes(void); void arc_init(void); void arc_fini(void); diff --git a/man/man5/zfs-module-parameters.5 b/man/man5/zfs-module-parameters.5 index 3c61ac1a9..a7623ff27 100644 --- a/man/man5/zfs-module-parameters.5 +++ b/man/man5/zfs-module-parameters.5 @@ -854,8 +854,11 @@ Default value: \fB10\fR%. \fBzfs_arc_max\fR (ulong) .ad .RS 12n -Max arc size of ARC in bytes. If set to 0 then it will consume 1/2 of system -RAM. This value must be at least 67108864 (64 megabytes). +Max size of ARC in bytes. If set to 0 then the max size of ARC is determined +by the amount of system memory installed. For Linux, 1/2 of system memory will +be used as the limit. For FreeBSD, the larger of all system memory - 1GB or +5/8 of system memory will be used as the limit. This value must be at least +67108864 (64 megabytes). .sp This value can be changed dynamically with some caveats. It cannot be set back to 0 while running and reducing it below the current ARC size will not cause diff --git a/module/os/linux/zfs/arc_os.c b/module/os/linux/zfs/arc_os.c index 1e0cabd0a..bff0f0517 100644 --- a/module/os/linux/zfs/arc_os.c +++ b/module/os/linux/zfs/arc_os.c @@ -60,6 +60,16 @@ int64_t last_free_memory; free_memory_reason_t last_free_reason; +/* + * Return a default max arc size based on the amount of physical memory. + */ +uint64_t +arc_default_max(uint64_t min, uint64_t allmem) +{ + /* Default to 1/2 of all memory. */ + return (MAX(allmem / 2, min)); +} + #ifdef _KERNEL /* * Return maximum amount of memory that we could possibly use. Reduced diff --git a/module/zfs/arc.c b/module/zfs/arc.c index c6b194183..8a0c1a4a7 100644 --- a/module/zfs/arc.c +++ b/module/zfs/arc.c @@ -7150,13 +7150,13 @@ arc_init(void) arc_lowmem_init(); #endif - /* Set max to 1/2 of all memory */ - arc_c_max = allmem / 2; - -#ifdef _KERNEL - /* Set min cache to 1/32 of all memory, or 32MB, whichever is more */ + /* Set min cache to 1/32 of all memory, or 32MB, whichever is more. */ arc_c_min = MAX(allmem / 32, 2ULL << SPA_MAXBLOCKSHIFT); -#else + + /* How to set default max varies by platform. */ + arc_c_max = arc_default_max(arc_c_min, allmem); + +#ifndef _KERNEL /* * In userland, there's only the memory pressure that we artificially * create (see arc_available_memory()). Don't let arc_c get too -- cgit v1.2.3