Skip to content

Commit 6831d75

Browse files
committed
Restore FreeBSD sysctl processing for arc.min and arc.max
Before OpenZFS 2.0, trying to set the FreeBSD sysctl vfs.zfs.arc_max to a disallowed value would return an error. Since the switch, it instead only generates WARN_IF_TUNING_IGNORED Also lost, was the ability to set vfs.zfs.arc_max to a value less than the default vfs.zfs.arc_min at boot time. Restore this as well. Signed-off-by: Allan Jude <[email protected]>
1 parent 757df52 commit 6831d75

File tree

5 files changed

+87
-5
lines changed

5 files changed

+87
-5
lines changed

include/os/freebsd/spl/sys/mod_os.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@
6262
#define param_set_arc_long_args(var) \
6363
CTLTYPE_ULONG, &var, 0, param_set_arc_long, "LU"
6464

65+
#define param_set_arc_min_args(var) \
66+
CTLTYPE_ULONG, &var, 0, param_set_arc_min, "LU"
67+
68+
#define param_set_arc_max_args(var) \
69+
CTLTYPE_ULONG, &var, 0, param_set_arc_max, "LU"
70+
6571
#define param_set_arc_int_args(var) \
6672
CTLTYPE_INT, &var, 0, param_set_arc_int, "I"
6773

include/sys/arc_impl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,8 @@ extern void arc_unregister_hotplug(void);
932932

933933
extern int param_set_arc_long(ZFS_MODULE_PARAM_ARGS);
934934
extern int param_set_arc_int(ZFS_MODULE_PARAM_ARGS);
935+
extern int param_set_arc_min(ZFS_MODULE_PARAM_ARGS);
936+
extern int param_set_arc_max(ZFS_MODULE_PARAM_ARGS);
935937

936938
/* used in zdb.c */
937939
boolean_t l2arc_log_blkptr_valid(l2arc_dev_t *dev,

module/os/freebsd/zfs/sysctl_os.c

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,52 @@ extern arc_state_t ARC_l2c_only;
144144

145145
/* arc.c */
146146

147+
int
148+
param_set_arc_max(SYSCTL_HANDLER_ARGS)
149+
{
150+
uint64_t val;
151+
int err;
152+
153+
val = zfs_arc_max;
154+
err = sysctl_handle_long(oidp, &val, 0, req);
155+
if (err != 0 || req->newptr == NULL)
156+
return (SET_ERROR(err));
157+
158+
if (val < 64 << 20 || val <= arc_c_min || val >= kmem_size())
159+
return (SET_ERROR(EINVAL));
160+
161+
zfs_arc_max = val;
162+
arc_tuning_update(B_TRUE);
163+
164+
/* Update the sysctl to the tuned value */
165+
zfs_arc_max = arc_c_max;
166+
167+
return (0);
168+
}
169+
170+
int
171+
param_set_arc_min(SYSCTL_HANDLER_ARGS)
172+
{
173+
uint64_t val;
174+
int err;
175+
176+
val = zfs_arc_min;
177+
err = sysctl_handle_64(oidp, &val, 0, req);
178+
if (err != 0 || req->newptr == NULL)
179+
return (SET_ERROR(err));
180+
181+
if (val < 2ULL << SPA_MAXBLOCKSHIFT || val > arc_c_max)
182+
return (SET_ERROR(EINVAL));
183+
184+
zfs_arc_min = val;
185+
arc_tuning_update(B_TRUE);
186+
187+
/* Update the sysctl to the tuned value */
188+
zfs_arc_min = arc_c_min;
189+
190+
return (0);
191+
}
192+
147193
/* legacy compat */
148194
extern uint64_t l2arc_write_max; /* def max write size */
149195
extern uint64_t l2arc_write_boost; /* extra warmup write */
@@ -278,11 +324,11 @@ param_set_arc_int(SYSCTL_HANDLER_ARGS)
278324

279325
SYSCTL_PROC(_vfs_zfs, OID_AUTO, arc_min,
280326
CTLTYPE_ULONG | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
281-
&zfs_arc_min, sizeof (zfs_arc_min), param_set_arc_long, "LU",
327+
&zfs_arc_min, sizeof (zfs_arc_min), param_set_arc_min, "LU",
282328
"min arc size (LEGACY)");
283329
SYSCTL_PROC(_vfs_zfs, OID_AUTO, arc_max,
284330
CTLTYPE_ULONG | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
285-
&zfs_arc_max, sizeof (zfs_arc_max), param_set_arc_long, "LU",
331+
&zfs_arc_max, sizeof (zfs_arc_max), param_set_arc_max, "LU",
286332
"max arc size (LEGACY)");
287333

288334
/* dbuf.c */

module/os/linux/zfs/arc_os.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,18 @@ param_set_arc_long(const char *buf, zfs_kernel_param_t *kp)
371371
return (0);
372372
}
373373

374+
int
375+
param_set_arc_min(const char *buf, zfs_kernel_param_t *kp)
376+
{
377+
return (param_set_arc_long(buf, kp));
378+
}
379+
380+
int
381+
param_set_arc_max(const char *buf, zfs_kernel_param_t *kp)
382+
{
383+
return (param_set_arc_long(buf, kp));
384+
}
385+
374386
int
375387
param_set_arc_int(const char *buf, zfs_kernel_param_t *kp)
376388
{

module/zfs/arc.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7618,7 +7618,23 @@ arc_init(void)
76187618

76197619
arc_set_limits(allmem);
76207620

7621-
#ifndef _KERNEL
7621+
#ifdef _KERNEL
7622+
/*
7623+
* If zfs_arc_max is non-zero at init, meaning it was set in the kernel
7624+
* environment before the module was loaded, don't block setting the
7625+
* maximum because it is less than arc_c_min, instead, reset arc_c_min
7626+
* to a lower value.
7627+
* zfs_arc_min will be handled by arc_tuning_update().
7628+
*/
7629+
if (zfs_arc_max != 0 && zfs_arc_max > 64 << 20 &&
7630+
zfs_arc_max < allmem) {
7631+
arc_c_max = zfs_arc_max;
7632+
if (arc_c_min >= arc_c_max) {
7633+
arc_c_min = MAX(zfs_arc_max / 2,
7634+
2ULL << SPA_MAXBLOCKSHIFT);
7635+
}
7636+
}
7637+
#else
76227638
/*
76237639
* In userland, there's only the memory pressure that we artificially
76247640
* create (see arc_available_memory()). Don't let arc_c get too
@@ -10651,10 +10667,10 @@ EXPORT_SYMBOL(arc_add_prune_callback);
1065110667
EXPORT_SYMBOL(arc_remove_prune_callback);
1065210668

1065310669
/* BEGIN CSTYLED */
10654-
ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, min, param_set_arc_long,
10670+
ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, min, param_set_arc_min,
1065510671
param_get_long, ZMOD_RW, "Min arc size");
1065610672

10657-
ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, max, param_set_arc_long,
10673+
ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, max, param_set_arc_max,
1065810674
param_get_long, ZMOD_RW, "Max arc size");
1065910675

1066010676
ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, meta_limit, param_set_arc_long,

0 commit comments

Comments
 (0)