mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 19:34:43 +01:00
arc: apply arc_min tunables set before arc_init() has run
Tunables are applied as each parameter is registered, and zfs_arc_min is
registered before zfs_arc_max. So param_set_arc_min() can run while
arc_c_max is still zero, and its upper bound check rejects every
non-zero value:
Setting sysctl vfs.zfs.arc.min failed: 22
The value is dropped and the ARC floor falls back to allmem/32.
param_set_arc_max() is not affected, because it tests a lower bound
against arc_c_min, which a zero value satisfies.
Skip the upper bound while arc_c_max is zero and store the raw value.
arc_init() expects this: arc_set_limits() sets both limits, and the
arc_tuning_update() call after it applies zfs_arc_min.
Storing the value exposes a second bug. The other arc handlers call
arc_tuning_update() unconditionally, so one registered before arc_init()
reaches WARN_IF_TUNING_IGNORED with both limits still zero and reports
the tunable as ignored, even though arc_init() applies it soon after:
WARNING: ignoring tunable zfs_arc_min (using 0 instead)
Return early from arc_tuning_update() while arc_c_max is zero, which
covers every caller. Also guard the writeback, so the tunable is not
overwritten with a zero limit.
This is the warning reported in #12504.
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Abdelkader Boudih <[email protected]>
Closes #12504
Closes #19008
This commit is contained in:
1 parent
5280a08f6b
commit
c47591d5da
2 files changed
+7
-3
No files matched your search
@@ -198,7 +198,7 @@ param_set_arc_max(SYSCTL_HANDLER_ARGS)
|
||||
arc_tuning_update(B_TRUE);
|
||||
|
||||
/* Update the sysctl to the tuned value */
|
||||
if (val != 0)
|
||||
if (val != 0 && arc_c_max != 0)
|
||||
zfs_arc_max = arc_c_max;
|
||||
|
||||
return (0);
|
||||
@@ -215,14 +215,15 @@ param_set_arc_min(SYSCTL_HANDLER_ARGS)
|
||||
if (err != 0 || req->newptr == NULL)
|
||||
return (SET_ERROR(err));
|
||||
|
||||
if (val != 0 && (val < 2ULL << SPA_MAXBLOCKSHIFT || val > arc_c_max))
|
||||
if (val != 0 && (val < 2ULL << SPA_MAXBLOCKSHIFT ||
|
||||
(arc_c_max != 0 && val > arc_c_max)))
|
||||
return (SET_ERROR(EINVAL));
|
||||
|
||||
zfs_arc_min = val;
|
||||
arc_tuning_update(B_TRUE);
|
||||
|
||||
/* Update the sysctl to the tuned value */
|
||||
if (val != 0)
|
||||
if (val != 0 && arc_c_max != 0)
|
||||
zfs_arc_min = arc_c_min;
|
||||
|
||||
return (0);
|
||||
|
||||
@@ -7624,6 +7624,9 @@ arc_tuning_update(boolean_t verbose)
|
||||
{
|
||||
uint64_t allmem = arc_all_memory();
|
||||
|
||||
if (arc_c_max == 0)
|
||||
return;
|
||||
|
||||
/* Valid range: 32M - <arc_c_max> */
|
||||
if ((zfs_arc_min) && (zfs_arc_min != arc_c_min) &&
|
||||
(zfs_arc_min >= 2ULL << SPA_MAXBLOCKSHIFT) &&
|
||||
|
||||
Reference in new issue
Block a user