summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyan Moeller <[email protected]>2020-03-27 12:14:46 -0400
committerGitHub <[email protected]>2020-03-27 09:14:46 -0700
commit9a51738b60c2164822baefa17f8fdcebe9d82fbc (patch)
treea16926d3b550160a937d533e41a6651b6f3ad6c8
parent3f38797338f2e4b16e8e0065e21f1bca6ef59784 (diff)
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 <[email protected]> Signed-off-by: Ryan Moeller <[email protected]> Closes #10155
-rw-r--r--include/sys/arc.h1
-rw-r--r--man/man5/zfs-module-parameters.57
-rw-r--r--module/os/linux/zfs/arc_os.c10
-rw-r--r--module/zfs/arc.c12
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