From 3dad29fb4b085a159d26e2322dc07b46950ff72e Mon Sep 17 00:00:00 2001 From: Matthew Macy Date: Wed, 23 Sep 2020 11:09:48 -0700 Subject: [PATCH] FreeBSD: Don't save user FPU context in kernel threads Reviewed-by: Alexander Motin Reviewed-by: Ryan Moeller Signed-off-by: Matt Macy Closes #10899 --- include/os/freebsd/spl/sys/simd_x86.h | 16 ++++++++-------- module/os/freebsd/spl/spl_taskq.c | 4 ++++ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/include/os/freebsd/spl/sys/simd_x86.h b/include/os/freebsd/spl/sys/simd_x86.h index a35e205d5a..63d6017b79 100644 --- a/include/os/freebsd/spl/sys/simd_x86.h +++ b/include/os/freebsd/spl/sys/simd_x86.h @@ -29,6 +29,7 @@ #include #include #include +#include #ifdef __i386__ #include #else @@ -42,16 +43,15 @@ #define kfpu_allowed() 1 #define kfpu_initialize(tsk) do {} while (0) -#define kfpu_begin() { \ - critical_enter(); \ - fpu_kern_enter(curthread, NULL, FPU_KERN_NOCTX); \ +#define kfpu_begin() { \ + if (__predict_false(!is_fpu_kern_thread(0))) \ + fpu_kern_enter(curthread, NULL, FPU_KERN_NOCTX);\ } -#define kfpu_end() \ - { \ - fpu_kern_leave(curthread, NULL); \ - critical_exit(); \ - } +#define kfpu_end() { \ + if (__predict_false(curpcb->pcb_flags & PCB_FPUNOSAVE)) \ + fpu_kern_leave(curthread, NULL); \ +} /* * Check if OS supports AVX and AVX2 by checking XCR0 diff --git a/module/os/freebsd/spl/spl_taskq.c b/module/os/freebsd/spl/spl_taskq.c index 049e889cf3..cc025de959 100644 --- a/module/os/freebsd/spl/spl_taskq.c +++ b/module/os/freebsd/spl/spl_taskq.c @@ -169,6 +169,10 @@ taskq_tsd_set(void *context) { taskq_t *tq = context; +#if defined(__amd64__) || defined(__i386__) || defined(__aarch64__) + if (context != NULL && tsd_get(taskq_tsd) == NULL) + fpu_kern_thread(FPU_KERN_NORMAL); +#endif tsd_set(taskq_tsd, tq); }