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

Make the vfs.zfs.vdev.raidz_impl sysctl cross-platform #16980

Merged
merged 10 commits into from
Jan 29, 2025
3 changes: 3 additions & 0 deletions include/os/freebsd/spl/sys/mod_os.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@
#define param_set_max_auto_ashift_args(var) \
CTLTYPE_UINT, NULL, 0, param_set_max_auto_ashift, "IU"

#define param_set_raidz_impl_args(var) \
CTLTYPE_STRING, NULL, 0, param_set_raidz_impl, "A"

#define spa_taskq_read_param_set_args(var) \
CTLTYPE_STRING, NULL, 0, spa_taskq_read_param, "A"

Expand Down
4 changes: 4 additions & 0 deletions include/sys/vdev_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,10 @@ extern int vdev_obsolete_counts_are_precise(vdev_t *vd, boolean_t *are_precise);
int vdev_checkpoint_sm_object(vdev_t *vd, uint64_t *sm_obj);
void vdev_metaslab_group_create(vdev_t *vd);
uint64_t vdev_best_ashift(uint64_t logical, uint64_t a, uint64_t b);
#if defined(__linux__)
int param_get_raidz_impl(char *buf, zfs_kernel_param_t *kp);
#endif
int param_set_raidz_impl(ZFS_MODULE_PARAM_ARGS);

/*
* Vdev ashift optimization tunables
Expand Down
3 changes: 3 additions & 0 deletions include/sys/vdev_raidz.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,16 @@ extern const zio_vsd_ops_t vdev_raidz_vsd_ops;
/*
* vdev_raidz_math interface
*/
/* Required, but not used, by ZFS_MODULE_PARAM_CALL */
extern uint32_t zfs_vdev_raidz_impl;
void vdev_raidz_math_init(void);
void vdev_raidz_math_fini(void);
const struct raidz_impl_ops *vdev_raidz_math_get_ops(void);
int vdev_raidz_math_generate(struct raidz_map *, struct raidz_row *);
int vdev_raidz_math_reconstruct(struct raidz_map *, struct raidz_row *,
const int *, const int *, const int);
int vdev_raidz_impl_set(const char *);
int vdev_raidz_impl_get(char *buffer, size_t size);

typedef struct vdev_raidz_expand {
uint64_t vre_vdev_id;
Expand Down
1 change: 1 addition & 0 deletions module/Kbuild.in
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,7 @@ ZFS_OBJS_OS := \
trace.o \
vdev_disk.o \
vdev_file.o \
vdev_raidz.o \
vdev_label_os.o \
zfs_acl.o \
zfs_ctldir.o \
Expand Down
21 changes: 21 additions & 0 deletions module/os/freebsd/zfs/sysctl_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,27 @@ param_set_deadman_failmode(SYSCTL_HANDLER_ARGS)
return (-param_set_deadman_failmode_common(buf));
}

int
param_set_raidz_impl(SYSCTL_HANDLER_ARGS)
{
const size_t bufsize = 128;
char *buf;
int rc;

buf = malloc(bufsize, M_SOLARIS, M_WAITOK | M_ZERO);
if (req->newptr == NULL)
vdev_raidz_impl_get(buf, bufsize);

rc = sysctl_handle_string(oidp, buf, bufsize, req);
if (rc || req->newptr == NULL) {
free(buf, M_SOLARIS);
return (rc);
}
rc = vdev_raidz_impl_set(buf);
free(buf, M_SOLARIS);
return (rc);
}

int
param_set_slop_shift(SYSCTL_HANDLER_ARGS)
{
Expand Down
42 changes: 42 additions & 0 deletions module/os/linux/zfs/vdev_raidz.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/* Copyright (C) 2025 ConnectWise */

#include <sys/zfs_context.h>
#include <sys/spa.h>
#include <sys/zio.h>
#include <sys/vdev_impl.h>
#include <sys/vdev_raidz.h>

int
param_get_raidz_impl(char *buf, zfs_kernel_param_t *kp)
{
return (vdev_raidz_impl_get(buf, PAGE_SIZE));
}

int
param_set_raidz_impl(const char *val, zfs_kernel_param_t *kp)
{
int error;

error = vdev_raidz_impl_set(val);
return (error);
}
4 changes: 4 additions & 0 deletions module/zfs/vdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -6580,3 +6580,7 @@ ZFS_MODULE_PARAM_CALL(zfs_vdev, zfs_vdev_, max_auto_ashift,
param_set_max_auto_ashift, param_get_uint, ZMOD_RW,
"Maximum ashift used when optimizing for logical -> physical sector "
"size on new top-level vdevs");

ZFS_MODULE_PARAM_CALL(zfs_vdev, zfs_vdev_, raidz_impl,
param_set_raidz_impl, param_get_raidz_impl, ZMOD_RW,
"RAIDZ implementation");
21 changes: 6 additions & 15 deletions module/zfs/vdev_raidz_math.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ static boolean_t raidz_math_initialized = B_FALSE;

#define RAIDZ_IMPL_READ(i) (*(volatile uint32_t *) &(i))

static uint32_t zfs_vdev_raidz_impl = IMPL_SCALAR;
uint32_t zfs_vdev_raidz_impl = IMPL_SCALAR;
static uint32_t user_sel_impl = IMPL_FASTEST;

/* Hold all supported implementations */
Expand Down Expand Up @@ -633,16 +633,10 @@ vdev_raidz_impl_set(const char *val)
return (err);
}

#if defined(_KERNEL) && defined(__linux__)

static int
zfs_vdev_raidz_impl_set(const char *val, zfs_kernel_param_t *kp)
{
return (vdev_raidz_impl_set(val));
}
#if defined(_KERNEL)

static int
zfs_vdev_raidz_impl_get(char *buffer, zfs_kernel_param_t *kp)
int
vdev_raidz_impl_get(char *buffer, size_t size)
{
int i, cnt = 0;
char *fmt;
Expand All @@ -653,21 +647,18 @@ zfs_vdev_raidz_impl_get(char *buffer, zfs_kernel_param_t *kp)
/* list mandatory options */
for (i = 0; i < ARRAY_SIZE(math_impl_opts) - 2; i++) {
fmt = (impl == math_impl_opts[i].sel) ? "[%s] " : "%s ";
cnt += kmem_scnprintf(buffer + cnt, PAGE_SIZE - cnt, fmt,
cnt += kmem_scnprintf(buffer + cnt, size - cnt, fmt,
math_impl_opts[i].name);
}

/* list all supported implementations */
for (i = 0; i < raidz_supp_impl_cnt; i++) {
fmt = (i == impl) ? "[%s] " : "%s ";
cnt += kmem_scnprintf(buffer + cnt, PAGE_SIZE - cnt, fmt,
cnt += kmem_scnprintf(buffer + cnt, size - cnt, fmt,
raidz_supp_impl[i]->name);
}

return (cnt);
}

module_param_call(zfs_vdev_raidz_impl, zfs_vdev_raidz_impl_set,
zfs_vdev_raidz_impl_get, NULL, 0644);
MODULE_PARM_DESC(zfs_vdev_raidz_impl, "Select raidz implementation.");
#endif
Loading