aboutsummaryrefslogtreecommitdiff
path: root/sys/compat/linuxkpi
diff options
context:
space:
mode:
authorHans Petter Selasky <hselasky@FreeBSD.org>2021-07-31 13:32:52 +0000
committerHans Petter Selasky <hselasky@FreeBSD.org>2021-07-31 13:36:48 +0000
commit469884cf04a9b92677c7c83e229ca6b8814f8b0a (patch)
treecb13a97a0cba8b3a9a83eabb0a1647b17a307fe5 /sys/compat/linuxkpi
parentf7f76c200a8c33822a25ae36e4399c9896efa951 (diff)
downloadsrc-469884cf04a9b92677c7c83e229ca6b8814f8b0a.tar.gz
src-469884cf04a9b92677c7c83e229ca6b8814f8b0a.zip
LinuxKPI: Make FPU sections thread-safe and use the NOCTX flag.
Reviewed by: kib Submitted by: greg@unrelenting.technology Differential Revision: https://reviews.freebsd.org/D29921 MFC after: 1 week Sponsored by: NVIDIA Networking
Diffstat (limited to 'sys/compat/linuxkpi')
-rw-r--r--sys/compat/linuxkpi/common/include/asm/fpu/api.h40
-rw-r--r--sys/compat/linuxkpi/common/include/linux/sched.h3
-rw-r--r--sys/compat/linuxkpi/common/src/linux_fpu.c43
3 files changed, 41 insertions, 45 deletions
diff --git a/sys/compat/linuxkpi/common/include/asm/fpu/api.h b/sys/compat/linuxkpi/common/include/asm/fpu/api.h
index 035ec3620fdd..9c63b2e972bf 100644
--- a/sys/compat/linuxkpi/common/include/asm/fpu/api.h
+++ b/sys/compat/linuxkpi/common/include/asm/fpu/api.h
@@ -28,41 +28,13 @@
#ifndef _FPU_API_H_
#define _FPU_API_H_
-#if defined(__aarch64__) || defined(__amd64__) || defined(__i386__)
+#define kernel_fpu_begin() \
+ lkpi_kernel_fpu_begin()
-#include <machine/fpu.h>
+#define kernel_fpu_end() \
+ lkpi_kernel_fpu_end()
-extern struct fpu_kern_ctx *__lkpi_fpu_ctx;
-extern unsigned int __lkpi_fpu_ctx_level;
-
-static inline void
-kernel_fpu_begin()
-{
- if (__lkpi_fpu_ctx_level++ == 0) {
- fpu_kern_enter(curthread, __lkpi_fpu_ctx, FPU_KERN_NORMAL);
- }
-}
-
-static inline void
-kernel_fpu_end()
-{
- if (--__lkpi_fpu_ctx_level == 0) {
- fpu_kern_leave(curthread, __lkpi_fpu_ctx);
- }
-}
-
-#else
-
-static inline void
-kernel_fpu_begin()
-{
-}
-
-static inline void
-kernel_fpu_end()
-{
-}
-
-#endif
+extern void lkpi_kernel_fpu_begin(void);
+extern void lkpi_kernel_fpu_end(void);
#endif /* _FPU_API_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/sched.h b/sys/compat/linuxkpi/common/include/linux/sched.h
index 937e9f27870c..5954b16f6496 100644
--- a/sys/compat/linuxkpi/common/include/linux/sched.h
+++ b/sys/compat/linuxkpi/common/include/linux/sched.h
@@ -82,7 +82,8 @@ struct task_struct {
int bsd_interrupt_value;
struct work_struct *work; /* current work struct, if set */
struct task_struct *group_leader;
- unsigned rcu_section[TS_RCU_TYPE_MAX];
+ unsigned rcu_section[TS_RCU_TYPE_MAX];
+ unsigned int fpu_ctx_level;
};
#define current ({ \
diff --git a/sys/compat/linuxkpi/common/src/linux_fpu.c b/sys/compat/linuxkpi/common/src/linux_fpu.c
index 976e55e68ca1..08f7e075d827 100644
--- a/sys/compat/linuxkpi/common/src/linux_fpu.c
+++ b/sys/compat/linuxkpi/common/src/linux_fpu.c
@@ -30,21 +30,44 @@
#include <sys/proc.h>
#include <sys/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/fpu/api.h>
+
+#if defined(__aarch64__) || defined(__amd64__) || defined(__i386__)
+
#include <machine/fpu.h>
-struct fpu_kern_ctx *__lkpi_fpu_ctx;
-unsigned int __lkpi_fpu_ctx_level = 0;
+/*
+ * Technically the Linux API isn't supposed to allow nesting sections
+ * either, but currently used versions of GPU drivers rely on nesting
+ * working, so we only enter the section on the outermost level.
+ */
+
+void
+lkpi_kernel_fpu_begin(void)
+{
+ if ((current->fpu_ctx_level)++ == 0)
+ fpu_kern_enter(curthread, NULL, FPU_KERN_NOCTX);
+}
+
+void
+lkpi_kernel_fpu_end(void)
+{
+ if (--(current->fpu_ctx_level) == 0)
+ fpu_kern_leave(curthread, NULL);
+}
+
+#else
-static void
-linux_fpu_init(void *arg __unused)
+void
+lkpi_kernel_fpu_begin(void)
{
- __lkpi_fpu_ctx = fpu_kern_alloc_ctx(0);
}
-SYSINIT(linux_fpu, SI_SUB_EVENTHANDLER, SI_ORDER_SECOND, linux_fpu_init, NULL);
-static void
-linux_fpu_uninit(void *arg __unused)
+void
+lkpi_kernel_fpu_end(void)
{
- fpu_kern_free_ctx(__lkpi_fpu_ctx);
}
-SYSUNINIT(linux_fpu, SI_SUB_EVENTHANDLER, SI_ORDER_SECOND, linux_fpu_uninit, NULL);
+
+#endif