tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
ZFS tunable parameters
Hi,
I looked into exposing ZFS tunables through sysctl and it seems
straightforward. Despite being under "dist" I am not sure if this is true
upstream, so the patch is directly on arc.c (and I think it'd be tricky to
implement otherwise).
I tested arc_min and arc_max, and it seems like changes do have an effect
(e.g. on c, c_max). Additionally tested arc_free_target and it does have
an effect also.
Here are the new sysctl values on boot on a 8G system:
vfs.zfs.arc_min = 392903680
vfs.zfs.arc_max = 3143229440
vfs.zfs.arc_average_blocksize = 8192
vfs.zfs.arc_shrink_shift = 7
vfs.zfs.compressed_arc_enable = 1
vfs.zfs.arc_meta_limit = 785807360
vfs.zfs.arc_meta_min = 0
vfs.zfs.arc_free_target = 682
Cc'ing kre and martin because you worked on the ZFS source last. Hope
somebody finds this useful and I'd appreciate any feedback!
S.
Index: external/cddl/osnet/dist/uts/common/fs/zfs/arc.c
===================================================================
RCS file: /cvsroot/src/external/cddl/osnet/dist/uts/common/fs/zfs/arc.c,v
retrieving revision 1.23
diff -u -r1.23 arc.c
--- external/cddl/osnet/dist/uts/common/fs/zfs/arc.c 3 May 2026 22:41:40 -0000 1.23
+++ external/cddl/osnet/dist/uts/common/fs/zfs/arc.c 20 Jun 2026 12:56:45 -0000
@@ -288,13 +288,16 @@
#define freemem uvm_availmem(false)
#define minfree uvmexp.freemin
#define desfree uvmexp.freetarg
-#define zfs_arc_free_target desfree
+#define vm_pageout_wakeup_thresh desfree
#define lotsfree (desfree * 2)
#define availrmem desfree
#define swapfs_minfree 0
#define swapfs_reserve 0
#undef curproc
#define curproc curlwp
+#define vm_cnt uvmexp
+#define v_page_count npages
+#define SYSCTL_HANDLER_ARGS SYSCTLFN_ARGS
static void *zio_arena;
@@ -393,7 +396,7 @@
boolean_t zfs_compressed_arc_enabled = B_TRUE;
-#if defined(__FreeBSD__) && defined(_KERNEL)
+#if (defined(__FreeBSD__) || defined(__NetBSD__)) && defined(_KERNEL)
u_int zfs_arc_free_target = 0;
static int sysctl_vfs_zfs_arc_free_target(SYSCTL_HANDLER_ARGS);
@@ -407,6 +410,7 @@
zfs_arc_free_target = vm_pageout_wakeup_thresh;
}
+#ifdef __FreeBSD__
SYSINIT(arc_free_target_init, SI_SUB_KTHREAD_PAGE, SI_ORDER_ANY,
arc_free_target_init, NULL);
@@ -435,17 +439,98 @@
CTLTYPE_UINT | CTLFLAG_MPSAFE | CTLFLAG_RW, 0, sizeof(u_int),
sysctl_vfs_zfs_arc_free_target, "IU",
"Desired number of free pages below which ARC triggers reclaim");
+#elifdef __NetBSD__
+SYSCTL_SETUP(zfs_sysctl_init, "zfs sysctl")
+{
+ const struct sysctlnode *rnode;
+
+ sysctl_createv(clog, 0, NULL, &rnode,
+ CTLFLAG_PERMANENT,
+ CTLTYPE_NODE, "zfs",
+ SYSCTL_DESCR("ZFS vfs options"),
+ NULL, 0, NULL, 0,
+ CTL_VFS, CTL_CREATE, CTL_EOL);
+
+ sysctl_createv(clog, 0, &rnode, NULL,
+ CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+ CTLTYPE_QUAD, "arc_min",
+ SYSCTL_DESCR("Minimum ARC size"),
+ sysctl_vfs_zfs_arc_min, 0, &zfs_arc_min, 0,
+ CTL_CREATE, CTL_EOL);
+
+ sysctl_createv(clog, 0, &rnode, NULL,
+ CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+ CTLTYPE_QUAD, "arc_max",
+ SYSCTL_DESCR("Maximum ARC size"),
+ sysctl_vfs_zfs_arc_max, 0, &zfs_arc_max, 0,
+ CTL_CREATE, CTL_EOL);
+
+ sysctl_createv(clog, 0, &rnode, NULL,
+ CTLFLAG_PERMANENT|CTLFLAG_READONLY,
+ CTLTYPE_QUAD, "arc_average_blocksize",
+ SYSCTL_DESCR("ARC average blocksize"),
+ NULL, 0, &zfs_arc_average_blocksize, 0,
+ CTL_CREATE, CTL_EOL);
+
+ zfs_arc_shrink_shift = arc_shrink_shift;
+ sysctl_createv(clog, 0, &rnode, NULL,
+ CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+ CTLTYPE_INT, "arc_shrink_shift",
+ SYSCTL_DESCR("log2(fraction of arc to reclaim)"),
+ NULL, 0, &zfs_arc_shrink_shift, 0,
+ CTL_CREATE, CTL_EOL);
+
+ sysctl_createv(clog, 0, &rnode, NULL,
+ CTLFLAG_PERMANENT|CTLFLAG_READONLY,
+ CTLTYPE_INT, "compressed_arc_enable",
+ SYSCTL_DESCR("Enable compressed ARC"),
+ NULL, 0, &zfs_compressed_arc_enabled, 0,
+ CTL_CREATE, CTL_EOL);
+
+ sysctl_createv(clog, 0, &rnode, NULL,
+ CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+ CTLTYPE_QUAD, "arc_meta_limit",
+ SYSCTL_DESCR("ARC metadata limit"),
+ sysctl_vfs_zfs_arc_meta_limit, 0, &zfs_arc_meta_limit, 0,
+ CTL_CREATE, CTL_EOL);
+
+ sysctl_createv(clog, 0, &rnode, NULL,
+ CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+ CTLTYPE_QUAD, "arc_meta_min",
+ SYSCTL_DESCR("Minimum ARC metadata size"),
+ NULL, 0, &zfs_arc_meta_min, 0,
+ CTL_CREATE, CTL_EOL);
+
+ arc_free_target_init(NULL);
+ sysctl_createv(clog, 0, &rnode, NULL,
+ CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+ CTLTYPE_INT, "arc_free_target",
+ SYSCTL_DESCR("Desired number of free pages below which ARC triggers reclaim"),
+ sysctl_vfs_zfs_arc_free_target, 0, &zfs_arc_free_target, 0,
+ CTL_CREATE, CTL_EOL);
+}
+#endif
static int
sysctl_vfs_zfs_arc_free_target(SYSCTL_HANDLER_ARGS)
{
+#ifdef __NetBSD__
+ struct sysctlnode node;
+#endif
u_int val;
int err;
val = zfs_arc_free_target;
+#ifdef __FreeBSD__
err = sysctl_handle_int(oidp, &val, 0, req);
if (err != 0 || req->newptr == NULL)
+#else
+ node = *rnode;
+ node.sysctl_data = &val;
+ err = sysctl_lookup(SYSCTLFN_CALL(&node));
+ if (err || newp == NULL)
return (err);
+#endif
if (val < minfree)
return (EINVAL);
@@ -457,6 +542,7 @@
return (0);
}
+#ifdef __FreeBSD__
/*
* Must be declared here, before the definition of corresponding kstat
* macro which uses the same names will confuse the compiler.
@@ -466,6 +552,7 @@
sysctl_vfs_zfs_arc_meta_limit, "QU",
"ARC metadata limit");
#endif
+#endif
/*
* Note that buffers can be in one of 6 states:
@@ -1072,17 +1159,28 @@
l1arc_buf_hdr_t b_l1hdr;
};
-#if defined(__FreeBSD__) && defined(_KERNEL)
+#if (defined(__FreeBSD__) || defined(__NetBSD__)) && defined(_KERNEL)
static int
sysctl_vfs_zfs_arc_meta_limit(SYSCTL_HANDLER_ARGS)
{
+#ifdef __NetBSD__
+ struct sysctlnode node;
+#endif
uint64_t val;
int err;
val = arc_meta_limit;
+#ifdef __FreeBSD__
err = sysctl_handle_64(oidp, &val, 0, req);
if (err != 0 || req->newptr == NULL)
return (err);
+#elifdef __NetBSD__
+ node = *rnode;
+ node.sysctl_data = &val;
+ err = sysctl_lookup(SYSCTLFN_CALL(&node));
+ if (err || newp == NULL)
+ return (err);
+#endif
if (val <= 0 || val > arc_c_max)
return (EINVAL);
@@ -1094,14 +1192,26 @@
static int
sysctl_vfs_zfs_arc_max(SYSCTL_HANDLER_ARGS)
{
+#ifdef __NetBSD__
+ struct sysctlnode node;
+#endif
uint64_t val;
int err;
val = zfs_arc_max;
+#ifdef __FreeBSD__
err = sysctl_handle_64(oidp, &val, 0, req);
if (err != 0 || req->newptr == NULL)
return (err);
+#elifdef __NetBSD__
+ node = *rnode;
+ node.sysctl_data = &val;
+ err = sysctl_lookup(SYSCTLFN_CALL(&node));
+ if (err || newp == NULL)
+ return (err);
+#endif
+
if (zfs_arc_max == 0) {
/* Loader tunable so blindly set */
zfs_arc_max = val;
@@ -1137,13 +1247,24 @@
static int
sysctl_vfs_zfs_arc_min(SYSCTL_HANDLER_ARGS)
{
+#ifdef __NetBSD__
+ struct sysctlnode node;
+#endif
uint64_t val;
int err;
val = zfs_arc_min;
+#ifdef __FreeBSD__
err = sysctl_handle_64(oidp, &val, 0, req);
if (err != 0 || req->newptr == NULL)
return (err);
+#elifdef __NetBSD__
+ node = *rnode;
+ node.sysctl_data = &val;
+ err = sysctl_lookup(SYSCTLFN_CALL(&node));
+ if (err || newp == NULL)
+ return (err);
+#endif
if (zfs_arc_min == 0) {
/* Loader tunable so blindly set */
Home |
Main Index |
Thread Index |
Old Index