Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restore FreeBSD sysctl processing for arc.min and arc.max #12161

Merged
merged 1 commit into from
Aug 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions include/os/freebsd/spl/sys/mod_os.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@
#define param_set_arc_long_args(var) \
CTLTYPE_ULONG, &var, 0, param_set_arc_long, "LU"

#define param_set_arc_min_args(var) \
CTLTYPE_ULONG, &var, 0, param_set_arc_min, "LU"

#define param_set_arc_max_args(var) \
CTLTYPE_ULONG, &var, 0, param_set_arc_max, "LU"

#define param_set_arc_int_args(var) \
CTLTYPE_INT, &var, 0, param_set_arc_int, "I"

Expand Down
7 changes: 7 additions & 0 deletions include/sys/arc.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ extern "C" {
*/
#define ARC_EVICT_ALL UINT64_MAX

/*
* ZFS gets very unhappy when the maximum ARC size is smaller than the maximum
* block size and a larger block is written. To leave some safety margin, we
* limit the minimum for zfs_arc_max to the maximium transaction size.
*/
#define MIN_ARC_MAX DMU_MAX_ACCESS

#define HDR_SET_LSIZE(hdr, x) do { \
ASSERT(IS_P2ALIGNED(x, 1U << SPA_MINBLOCKSHIFT)); \
(hdr)->b_lsize = ((x) >> SPA_MINBLOCKSHIFT); \
Expand Down
2 changes: 2 additions & 0 deletions include/sys/arc_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1004,6 +1004,8 @@ extern void arc_unregister_hotplug(void);

extern int param_set_arc_long(ZFS_MODULE_PARAM_ARGS);
extern int param_set_arc_int(ZFS_MODULE_PARAM_ARGS);
extern int param_set_arc_min(ZFS_MODULE_PARAM_ARGS);
extern int param_set_arc_max(ZFS_MODULE_PARAM_ARGS);

/* used in zdb.c */
boolean_t l2arc_log_blkptr_valid(l2arc_dev_t *dev,
Expand Down
53 changes: 51 additions & 2 deletions module/os/freebsd/zfs/sysctl_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,55 @@ extern arc_state_t ARC_l2c_only;

/* arc.c */

int
param_set_arc_max(SYSCTL_HANDLER_ARGS)
{
uint64_t val;
int err;

val = zfs_arc_max;
err = sysctl_handle_long(oidp, &val, 0, req);
if (err != 0 || req->newptr == NULL)
return (SET_ERROR(err));

if (val != 0 && (val < MIN_ARC_MAX || val <= arc_c_min ||
val >= arc_all_memory()))
return (SET_ERROR(EINVAL));

zfs_arc_max = val;
arc_tuning_update(B_TRUE);

/* Update the sysctl to the tuned value */
if (val != 0)
zfs_arc_max = arc_c_max;

return (0);
}

int
param_set_arc_min(SYSCTL_HANDLER_ARGS)
{
uint64_t val;
int err;

val = zfs_arc_min;
err = sysctl_handle_64(oidp, &val, 0, req);
if (err != 0 || req->newptr == NULL)
return (SET_ERROR(err));

if (val != 0 && (val < 2ULL << SPA_MAXBLOCKSHIFT || 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)
zfs_arc_min = arc_c_min;

return (0);
}

/* legacy compat */
extern uint64_t l2arc_write_max; /* def max write size */
extern uint64_t l2arc_write_boost; /* extra warmup write */
Expand Down Expand Up @@ -278,11 +327,11 @@ param_set_arc_int(SYSCTL_HANDLER_ARGS)

SYSCTL_PROC(_vfs_zfs, OID_AUTO, arc_min,
CTLTYPE_ULONG | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
&zfs_arc_min, sizeof (zfs_arc_min), param_set_arc_long, "LU",
&zfs_arc_min, sizeof (zfs_arc_min), param_set_arc_min, "LU",
"min arc size (LEGACY)");
SYSCTL_PROC(_vfs_zfs, OID_AUTO, arc_max,
CTLTYPE_ULONG | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
&zfs_arc_max, sizeof (zfs_arc_max), param_set_arc_long, "LU",
&zfs_arc_max, sizeof (zfs_arc_max), param_set_arc_max, "LU",
"max arc size (LEGACY)");

/* dbuf.c */
Expand Down
12 changes: 12 additions & 0 deletions module/os/linux/zfs/arc_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,18 @@ param_set_arc_long(const char *buf, zfs_kernel_param_t *kp)
return (0);
}

int
param_set_arc_min(const char *buf, zfs_kernel_param_t *kp)
{
return (param_set_arc_long(buf, kp));
}

int
param_set_arc_max(const char *buf, zfs_kernel_param_t *kp)
{
return (param_set_arc_long(buf, kp));
}

int
param_set_arc_int(const char *buf, zfs_kernel_param_t *kp)
{
Expand Down
24 changes: 20 additions & 4 deletions module/zfs/arc.c
Original file line number Diff line number Diff line change
Expand Up @@ -7498,7 +7498,7 @@ arc_tuning_update(boolean_t verbose)

/* Valid range: 64M - <all physical memory> */
if ((zfs_arc_max) && (zfs_arc_max != arc_c_max) &&
(zfs_arc_max >= 64 << 20) && (zfs_arc_max < allmem) &&
(zfs_arc_max >= MIN_ARC_MAX) && (zfs_arc_max < allmem) &&
(zfs_arc_max > arc_c_min)) {
arc_c_max = zfs_arc_max;
arc_c = MIN(arc_c, arc_c_max);
Expand Down Expand Up @@ -7893,7 +7893,23 @@ arc_init(void)

arc_set_limits(allmem);

#ifndef _KERNEL
#ifdef _KERNEL
/*
* If zfs_arc_max is non-zero at init, meaning it was set in the kernel
* environment before the module was loaded, don't block setting the
* maximum because it is less than arc_c_min, instead, reset arc_c_min
* to a lower value.
* zfs_arc_min will be handled by arc_tuning_update().
*/
if (zfs_arc_max != 0 && zfs_arc_max >= MIN_ARC_MAX &&
zfs_arc_max < allmem) {
arc_c_max = zfs_arc_max;
if (arc_c_min >= arc_c_max) {
arc_c_min = MAX(zfs_arc_max / 2,
2ULL << SPA_MAXBLOCKSHIFT);
}
}
#else
/*
* In userland, there's only the memory pressure that we artificially
* create (see arc_available_memory()). Don't let arc_c get too
Expand Down Expand Up @@ -10965,10 +10981,10 @@ EXPORT_SYMBOL(arc_add_prune_callback);
EXPORT_SYMBOL(arc_remove_prune_callback);

/* BEGIN CSTYLED */
ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, min, param_set_arc_long,
ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, min, param_set_arc_min,
param_get_long, ZMOD_RW, "Min arc size");

ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, max, param_set_arc_long,
ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, max, param_set_arc_max,
param_get_long, ZMOD_RW, "Max arc size");

ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, meta_limit, param_set_arc_long,
Expand Down