FreeBSD: Do zcommon_init sooner to avoid FPU panic

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
This commit is contained in:
Ryan Moeller 2020-12-10 00:29:00 -05:00 committed by Brian Behlendorf
parent de2ac3f700
commit fb3ad5d24e
3 changed files with 10 additions and 1 deletions

View File

@ -93,6 +93,13 @@ wrap_ ## fn(void *dummy __unused) \
} \ } \
SYSINIT(zfs_ ## fn, SI_SUB_LAST, SI_ORDER_FIRST, wrap_ ## fn, NULL) 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) \ #define module_exit(fn) \
static void \ static void \

View File

@ -150,4 +150,6 @@ enum scope_prefix_types {
#define ZFS_MODULE_LICENSE(s) MODULE_LICENSE(s) #define ZFS_MODULE_LICENSE(s) MODULE_LICENSE(s)
#define ZFS_MODULE_VERSION(s) MODULE_VERSION(s) #define ZFS_MODULE_VERSION(s) MODULE_VERSION(s)
#define module_init_early(fn) module_init(fn)
#endif /* _MOD_COMPAT_H */ #endif /* _MOD_COMPAT_H */

View File

@ -1016,7 +1016,7 @@ zcommon_fini(void)
kfpu_fini(); kfpu_fini();
} }
module_init(zcommon_init); module_init_early(zcommon_init);
module_exit(zcommon_fini); module_exit(zcommon_fini);
#endif #endif