diff --git a/include/sys/arc.h b/include/sys/arc.h index 6f56f732ad..75c483918c 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 3c61ac1a90..a7623ff27d 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 1e0cabd0a5..bff0f05179 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 c6b194183f..8a0c1a4a7e 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