Skip to content

Commit

Permalink
Make the vfs.zfs.vdev.raidz_impl sysctl cross-platform
Browse files Browse the repository at this point in the history
Signed-off-by:	Alan Somers <[email protected]>
Sponsored by:	ConnectWise
  • Loading branch information
asomers committed Jan 22, 2025
1 parent 59a7751 commit 13b506c
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 20 deletions.
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
2 changes: 2 additions & 0 deletions include/sys/vdev_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ struct abd;
extern uint_t zfs_vdev_queue_depth_pct;
extern uint_t zfs_vdev_def_queue_depth;
extern uint_t zfs_vdev_async_write_max_active;
extern const char *zfs_vdev_raidz_impl;

/*
* Virtual device operations
Expand Down Expand Up @@ -645,6 +646,7 @@ 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);
int param_set_raidz_impl(ZFS_MODULE_PARAM_ARGS);

/*
* Vdev ashift optimization tunables
Expand Down
1 change: 1 addition & 0 deletions include/sys/vdev_raidz.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ 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
20 changes: 20 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,26 @@ param_set_deadman_failmode(SYSCTL_HANDLER_ARGS)
return (-param_set_deadman_failmode_common(buf));
}

int
param_set_raidz_impl(SYSCTL_HANDLER_ARGS)
{
char *buf;
int rc;

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

rc = sysctl_handle_string(oidp, buf, 64, 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
12 changes: 12 additions & 0 deletions module/os/linux/zfs/vdev_disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -1637,6 +1637,18 @@ param_set_max_auto_ashift(const char *buf, zfs_kernel_param_t *kp)
return (0);
}

const char *zfs_vdev_raidz_impl = "TODO";

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

error = vdev_raidz_impl_set(val);

return (error);
}

ZFS_MODULE_PARAM(zfs_vdev, zfs_vdev_, open_timeout_ms, UINT, ZMOD_RW,
"Timeout before determining that a device is missing");

Expand Down
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_charp, ZMOD_RW,
"RAIDZ implementation");
31 changes: 11 additions & 20 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;
static uint32_t zfs_vdev_raidz_impl_setting = IMPL_SCALAR;
static uint32_t user_sel_impl = IMPL_FASTEST;

/* Hold all supported implementations */
Expand Down Expand Up @@ -111,7 +111,7 @@ vdev_raidz_math_get_ops(void)
return (&vdev_raidz_scalar_impl);

raidz_impl_ops_t *ops = NULL;
const uint32_t impl = RAIDZ_IMPL_READ(zfs_vdev_raidz_impl);
const uint32_t impl = RAIDZ_IMPL_READ(zfs_vdev_raidz_impl_setting);

switch (impl) {
case IMPL_FASTEST:
Expand Down Expand Up @@ -540,7 +540,7 @@ vdev_raidz_math_init(void)
#endif

/* Finish initialization */
atomic_swap_32(&zfs_vdev_raidz_impl, user_sel_impl);
atomic_swap_32(&zfs_vdev_raidz_impl_setting, user_sel_impl);
raidz_math_initialized = B_TRUE;
}

Expand Down Expand Up @@ -579,7 +579,7 @@ static const struct {
* If we are called before init(), user preference will be saved in
* user_sel_impl, and applied in later init() call. This occurs when module
* parameter is specified on module load. Otherwise, directly update
* zfs_vdev_raidz_impl.
* zfs_vdev_raidz_impl_setting.
*
* @val Name of raidz implementation to use
* @param Unused.
Expand Down Expand Up @@ -625,49 +625,40 @@ vdev_raidz_impl_set(const char *val)

if (err == 0) {
if (raidz_math_initialized)
atomic_swap_32(&zfs_vdev_raidz_impl, impl);
atomic_swap_32(&zfs_vdev_raidz_impl_setting, impl);
else
atomic_swap_32(&user_sel_impl, impl);
}

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;
const uint32_t impl = RAIDZ_IMPL_READ(zfs_vdev_raidz_impl);
const uint32_t impl = RAIDZ_IMPL_READ(zfs_vdev_raidz_impl_setting);

ASSERT(raidz_math_initialized);

/* 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

0 comments on commit 13b506c

Please sign in to comment.