]> git.proxmox.com Git - mirror_zfs.git/commitdiff
FreeBSD: Implement sysctl for fletcher4 impl
authorRyan Moeller <ryan@iXsystems.com>
Wed, 2 Dec 2020 21:45:08 +0000 (21:45 +0000)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Fri, 11 Dec 2020 18:29:01 +0000 (10:29 -0800)
There is a tunable to select the fletcher 4 checksum implementation on
Linux but it was not present in FreeBSD.

Implement the sysctl handler for FreeBSD and use ZFS_MODULE_PARAM_CALL
to provide the tunable on both platforms.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ryan Moeller <ryan@iXsystems.com>
Closes #11270

include/os/freebsd/spl/sys/mod_os.h
include/os/linux/kernel/linux/mod_compat.h
module/zcommon/zfs_fletcher.c

index 9b1bdfbffea5509c8a34668cce3ae02868ee8292..5b3b3271e39e9ccefadc72f257d325fc2d9a85c4 100644 (file)
@@ -57,6 +57,8 @@
 #define        ZFS_MODULE_PARAM_CALL(scope_prefix, name_prefix, name, func, _, perm, desc) \
     ZFS_MODULE_PARAM_CALL_IMPL(_vfs_ ## scope_prefix, name, perm, func ## _args(name_prefix ## name), desc)
 
+#define        ZFS_MODULE_VIRTUAL_PARAM_CALL ZFS_MODULE_PARAM_CALL
+
 #define        param_set_arc_long_args(var) \
     CTLTYPE_ULONG, &var, 0, param_set_arc_long, "LU"
 
@@ -84,6 +86,9 @@
 #define        param_set_max_auto_ashift_args(var) \
     CTLTYPE_U64, &var, 0, param_set_max_auto_ashift, "QU"
 
+#define        fletcher_4_param_set_args(var) \
+    CTLTYPE_STRING, NULL, 0, fletcher_4_param, "A"
+
 #include <sys/kernel.h>
 #define        module_init(fn)                                                 \
 static void \
index 62905240b122d16ae9bb90227114edda41b065d5..e96e95313009e584369cdb47abb7769cefedbb65 100644 (file)
@@ -144,6 +144,17 @@ enum scope_prefix_types {
        MODULE_PARM_DESC(name_prefix ## name, desc)
 /* END CSTYLED */
 
+/*
+ * As above, but there is no variable with the name name_prefix ## name,
+ * so NULL is passed to module_param_call instead.
+ */
+/* BEGIN CSTYLED */
+#define        ZFS_MODULE_VIRTUAL_PARAM_CALL(scope_prefix, name_prefix, name, setfunc, getfunc, perm, desc) \
+       CTASSERT_GLOBAL((sizeof (scope_prefix) == sizeof (enum scope_prefix_types))); \
+       module_param_call(name_prefix ## name, setfunc, getfunc, NULL, perm); \
+       MODULE_PARM_DESC(name_prefix ## name, desc)
+/* END CSTYLED */
+
 #define        ZFS_MODULE_PARAM_ARGS   const char *buf, zfs_kernel_param_t *kp
 
 #define        ZFS_MODULE_DESCRIPTION(s) MODULE_DESCRIPTION(s)
index c5e63a8782b320456df47f380700f6b60c3a4a74..7a9de4a4309dcd59a8dc27ca58bfdfab855808a4 100644 (file)
@@ -885,23 +885,26 @@ zio_abd_checksum_func_t fletcher_4_abd_ops = {
        .acf_iter = abd_fletcher_4_iter
 };
 
+#if defined(_KERNEL)
+
+#define        IMPL_FMT(impl, i)       (((impl) == (i)) ? "[%s] " : "%s ")
 
-#if defined(_KERNEL) && defined(__linux__)
+#if defined(__linux__)
 
 static int
 fletcher_4_param_get(char *buffer, zfs_kernel_param_t *unused)
 {
        const uint32_t impl = IMPL_READ(fletcher_4_impl_chosen);
        char *fmt;
-       int i, cnt = 0;
+       int cnt = 0;
 
        /* list fastest */
-       fmt = (impl == IMPL_FASTEST) ? "[%s] " : "%s ";
+       fmt = IMPL_FMT(impl, IMPL_FASTEST);
        cnt += sprintf(buffer + cnt, fmt, "fastest");
 
        /* list all supported implementations */
-       for (i = 0; i < fletcher_4_supp_impls_cnt; i++) {
-               fmt = (i == impl) ? "[%s] " : "%s ";
+       for (uint32_t i = 0; i < fletcher_4_supp_impls_cnt; ++i) {
+               fmt = IMPL_FMT(impl, i);
                cnt += sprintf(buffer + cnt, fmt,
                    fletcher_4_supp_impls[i]->name);
        }
@@ -915,14 +918,62 @@ fletcher_4_param_set(const char *val, zfs_kernel_param_t *unused)
        return (fletcher_4_impl_set(val));
 }
 
+#else
+
+#include <sys/sbuf.h>
+
+static int
+fletcher_4_param(ZFS_MODULE_PARAM_ARGS)
+{
+       int err;
+
+       if (req->newptr == NULL) {
+               const uint32_t impl = IMPL_READ(fletcher_4_impl_chosen);
+               const int init_buflen = 64;
+               const char *fmt;
+               struct sbuf *s;
+
+               s = sbuf_new_for_sysctl(NULL, NULL, init_buflen, req);
+
+               /* list fastest */
+               fmt = IMPL_FMT(impl, IMPL_FASTEST);
+               (void) sbuf_printf(s, fmt, "fastest");
+
+               /* list all supported implementations */
+               for (uint32_t i = 0; i < fletcher_4_supp_impls_cnt; ++i) {
+                       fmt = IMPL_FMT(impl, i);
+                       (void) sbuf_printf(s, fmt,
+                           fletcher_4_supp_impls[i]->name);
+               }
+
+               err = sbuf_finish(s);
+               sbuf_delete(s);
+
+               return (err);
+       }
+
+       char buf[16];
+
+       err = sysctl_handle_string(oidp, buf, sizeof (buf), req);
+       if (err)
+               return (err);
+       return (-fletcher_4_impl_set(buf));
+}
+
+#endif
+
+#undef IMPL_FMT
+
 /*
  * Choose a fletcher 4 implementation in ZFS.
  * Users can choose "cycle" to exercise all implementations, but this is
  * for testing purpose therefore it can only be set in user space.
  */
-module_param_call(zfs_fletcher_4_impl,
-    fletcher_4_param_set, fletcher_4_param_get, NULL, 0644);
-MODULE_PARM_DESC(zfs_fletcher_4_impl, "Select fletcher 4 implementation.");
+/* BEGIN CSTYLED */
+ZFS_MODULE_VIRTUAL_PARAM_CALL(zfs, zfs_, fletcher_4_impl,
+       fletcher_4_param_set, fletcher_4_param_get, ZMOD_RW,
+       "Select fletcher 4 implementation.");
+/* END CSTYLED */
 
 EXPORT_SYMBOL(fletcher_init);
 EXPORT_SYMBOL(fletcher_2_incremental_native);