]> git.proxmox.com Git - mirror_zfs.git/commitdiff
FreeBSD: Do zcommon_init sooner to avoid FPU panic
authorRyan Moeller <ryan@iXsystems.com>
Thu, 10 Dec 2020 05:29:00 +0000 (00:29 -0500)
committerGitHub <noreply@github.com>
Thu, 10 Dec 2020 05:29:00 +0000 (21:29 -0800)
There has been a panic affecting some system configurations where the
thread FPU context is disturbed during the fletcher 4 benchmarks,
leading to a panic at boot.

module_init() registers zcommon_init to run in the last subsystem
(SI_SUB_LAST).  Running it as soon as interrupts have been configured
(SI_SUB_INT_CONFIG_HOOKS) makes sure we have finished the benchmarks
before we start doing other things.

While it's not clear *how* the FPU context was being disturbed, this
does seem to avoid it.

Add a module_init_early() macro to run zcommon_init() at this earlier
point on FreeBSD.  On Linux this is defined as module_init().

Authored by: Konstantin Belousov <kib@FreeBSD.org>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ryan Moeller <ryan@iXsystems.com>
Closes #11302

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

index ec1da1a46ae6e495f2d7cd00c3c07c362d9dab65..9b1bdfbffea5509c8a34668cce3ae02868ee8292 100644 (file)
@@ -93,6 +93,13 @@ wrap_ ## fn(void *dummy __unused) \
 }                                                                                                                                              \
 SYSINIT(zfs_ ## fn, SI_SUB_LAST, SI_ORDER_FIRST, wrap_ ## fn, NULL)
 
+#define        module_init_early(fn)                                                   \
+static void \
+wrap_ ## fn(void *dummy __unused) \
+{                                                               \
+       fn();                                            \
+}                                                                                                                                              \
+SYSINIT(zfs_ ## fn, SI_SUB_INT_CONFIG_HOOKS, SI_ORDER_FIRST, wrap_ ## fn, NULL)
 
 #define        module_exit(fn)                                                         \
 static void \
index 1bd8206bb8d647da4998bac9d27e753d8afa9b73..62905240b122d16ae9bb90227114edda41b065d5 100644 (file)
@@ -151,4 +151,6 @@ enum scope_prefix_types {
 #define        ZFS_MODULE_LICENSE(s) MODULE_LICENSE(s)
 #define        ZFS_MODULE_VERSION(s) MODULE_VERSION(s)
 
+#define        module_init_early(fn) module_init(fn)
+
 #endif /* _MOD_COMPAT_H */
index 89ddc59b226cab31653f5437dd10f13c2a2c1e6a..b78331187e13dc1e3de4cc1c156b7ff298413a7d 100644 (file)
@@ -1016,7 +1016,7 @@ zcommon_fini(void)
        kfpu_fini();
 }
 
-module_init(zcommon_init);
+module_init_early(zcommon_init);
 module_exit(zcommon_fini);
 
 #endif