New functions kthread_fpu_enter/exit.
The MI definitions don't do anything but maintain a flag, but MD code can define kthread_fpu_enter/exit_md to actually enable/disable the FPU. (These are almost pcu_load/discard on systems that use pcu(9), except they apply to all PCUs.) Discussed on tech-kern: https://mail-index.netbsd.org/tech-kern/2020/06/20/msg026524.html The proposed kthread flag KTHREAD_FPU is not included because I couldn't find any particular need for it that would not be covered by just calling kthread_fpu_enter/exit in the kthread function.
This commit is contained in:
parent
eef82c7583
commit
7c54d842f7
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: kthread.9,v 1.28 2015/04/21 11:10:29 pooka Exp $
|
||||
.\" $NetBSD: kthread.9,v 1.29 2020/08/01 02:04:55 riastradh Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2000, 2007, 2008 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
|
@ -33,7 +33,9 @@
|
|||
.Sh NAME
|
||||
.Nm kthread_create ,
|
||||
.Nm kthread_exit ,
|
||||
.Nm kthread_join
|
||||
.Nm kthread_join ,
|
||||
.Nm kthread_fpu_enter ,
|
||||
.Nm kthread_fpu_exit
|
||||
.Nd kernel threads
|
||||
.Sh SYNOPSIS
|
||||
.In sys/kthread.h
|
||||
|
@ -44,6 +46,10 @@
|
|||
.Fn kthread_exit "int ecode"
|
||||
.Ft int
|
||||
.Fn kthread_join "lwp_t *l"
|
||||
.Ft int
|
||||
.Fn kthread_fpu_enter
|
||||
.Ft void
|
||||
.Fn kthread_fpu_exit "int s"
|
||||
.Sh DESCRIPTION
|
||||
Kernel threads are light-weight processes which execute entirely
|
||||
within the kernel.
|
||||
|
@ -51,6 +57,13 @@ within the kernel.
|
|||
Any process can request the creation of a new kernel thread.
|
||||
Kernel threads are not swapped out during memory congestion.
|
||||
The VM space and limits are shared with proc0 (usually swapper).
|
||||
.Pp
|
||||
If the machine has any per-CPU floating-point units or SIMD vector
|
||||
units that are normally available to user threads, they can be used by
|
||||
kthreads between
|
||||
.Fn kthread_fpu_enter
|
||||
and
|
||||
.fn kthread_fpu_exit .
|
||||
.Sh FUNCTIONS
|
||||
.Bl -tag -width compact
|
||||
.It Fn kthread_create "pri" "flags" "ci" "func" "arg" "newlp" "fmt" "..."
|
||||
|
@ -155,6 +168,31 @@ created using the
|
|||
.Dv KTHREAD_MUSTJOIN
|
||||
flag and would wait on
|
||||
.Fa kthread_exit .
|
||||
.It Fn kthread_fpu_enter
|
||||
Allow the current kthread to use any machine-dependent per-CPU
|
||||
floating-point units or SIMD vector units normally available to user
|
||||
threads.
|
||||
Returns a cookie that must be passed to
|
||||
.Fn kthread_fpu_exit
|
||||
when done.
|
||||
.Pp
|
||||
Matching pairs of
|
||||
.Fn kthread_fpu_enter
|
||||
and
|
||||
.Fn kthread_fpu_exit
|
||||
may be nested.
|
||||
.It Fn kthread_fpu_exit "s"
|
||||
Restore the current kthread's access to machine-dependent per-CPU
|
||||
floating-point units or SIMD vector units to what it was before the
|
||||
call to
|
||||
.Fn kthread_fpu_enter
|
||||
that returned
|
||||
.Fa s .
|
||||
.Pp
|
||||
On the last
|
||||
.Fn kthread_fpu_exit ,
|
||||
zero all the units' registers to avoid leaking secrets \(em such units
|
||||
are often used for cryptography.
|
||||
.El
|
||||
.Sh RETURN VALUES
|
||||
Upon successful completion,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_kthread.c,v 1.45 2020/01/08 17:38:42 ad Exp $ */
|
||||
/* $NetBSD: kern_kthread.c,v 1.46 2020/08/01 02:04:55 riastradh Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 1999, 2007, 2009, 2019 The NetBSD Foundation, Inc.
|
||||
|
@ -31,9 +31,10 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_kthread.c,v 1.45 2020/01/08 17:38:42 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_kthread.c,v 1.46 2020/08/01 02:04:55 riastradh Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/cpu.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/kthread.h>
|
||||
|
@ -216,3 +217,71 @@ kthread_join(lwp_t *l)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* kthread_fpu_enter()
|
||||
*
|
||||
* Allow the current lwp, which must be a kthread, to use the FPU.
|
||||
* Return a cookie that must be passed to kthread_fpu_exit when
|
||||
* done. Must be used only in thread context. Recursive -- you
|
||||
* can call kthread_fpu_enter several times in a row as long as
|
||||
* you pass the cookies in reverse order to kthread_fpu_exit.
|
||||
*/
|
||||
int
|
||||
kthread_fpu_enter(void)
|
||||
{
|
||||
struct lwp *l = curlwp;
|
||||
int s;
|
||||
|
||||
KASSERTMSG(!cpu_intr_p(),
|
||||
"%s is not allowed in interrupt context", __func__);
|
||||
KASSERTMSG(!cpu_softintr_p(),
|
||||
"%s is not allowed in interrupt context", __func__);
|
||||
|
||||
/*
|
||||
* Remember whether this thread already had FPU access, and
|
||||
* mark this thread as having FPU access.
|
||||
*/
|
||||
lwp_lock(l);
|
||||
KASSERTMSG(l->l_flag & LW_SYSTEM,
|
||||
"%s is allowed only in kthreads", __func__);
|
||||
s = l->l_flag & LW_SYSTEM_FPU;
|
||||
l->l_flag |= LW_SYSTEM_FPU;
|
||||
lwp_unlock(l);
|
||||
|
||||
/* Take MD steps to enable the FPU if necessary. */
|
||||
if (s == 0)
|
||||
kthread_fpu_enter_md();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* kthread_fpu_exit(s)
|
||||
*
|
||||
* Restore the current lwp's FPU access to what it was before the
|
||||
* matching call to kthread_fpu_enter() that returned s. Must be
|
||||
* used only in thread context.
|
||||
*/
|
||||
void
|
||||
kthread_fpu_exit(int s)
|
||||
{
|
||||
struct lwp *l = curlwp;
|
||||
|
||||
KASSERT(s == (s & LW_SYSTEM_FPU));
|
||||
KASSERTMSG(!cpu_intr_p(),
|
||||
"%s is not allowed in interrupt context", __func__);
|
||||
KASSERTMSG(!cpu_softintr_p(),
|
||||
"%s is not allowed in interrupt context", __func__);
|
||||
|
||||
lwp_lock(l);
|
||||
KASSERTMSG(l->l_flag & LW_SYSTEM,
|
||||
"%s is allowed only in kthreads", __func__);
|
||||
KASSERT(l->l_flag & LW_SYSTEM_FPU);
|
||||
l->l_flag ^= s ^ LW_SYSTEM_FPU;
|
||||
lwp_unlock(l);
|
||||
|
||||
/* Take MD steps to zero and disable the FPU if necessary. */
|
||||
if (s == 0)
|
||||
kthread_fpu_exit_md();
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_stub.c,v 1.49 2020/05/23 23:42:43 ad Exp $ */
|
||||
/* $NetBSD: kern_stub.c,v 1.50 2020/08/01 02:04:55 riastradh Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
|
||||
|
@ -62,7 +62,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_stub.c,v 1.49 2020/05/23 23:42:43 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_stub.c,v 1.50 2020/08/01 02:04:55 riastradh Exp $");
|
||||
|
||||
#ifdef _KERNEL_OPT
|
||||
#include "opt_ktrace.h"
|
||||
|
@ -328,3 +328,7 @@ default_bus_space_is_equal(bus_space_tag_t t1, bus_space_tag_t t2)
|
|||
|
||||
return memcmp(&t1, &t2, sizeof(t1)) == 0;
|
||||
}
|
||||
|
||||
/* Stubs for architectures with no kernel FPU access. */
|
||||
__weak_alias(kthread_fpu_enter_md, voidop);
|
||||
__weak_alias(kthread_fpu_exit_md, voidop);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kthread.h,v 1.13 2015/04/21 11:10:29 pooka Exp $ */
|
||||
/* $NetBSD: kthread.h,v 1.14 2020/08/01 02:04:55 riastradh Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 2007, 2009 The NetBSD Foundation, Inc.
|
||||
|
@ -56,4 +56,11 @@ int kthread_create(pri_t, int, struct cpu_info *,
|
|||
void kthread_exit(int) __dead;
|
||||
int kthread_join(lwp_t *);
|
||||
|
||||
int kthread_fpu_enter(void);
|
||||
void kthread_fpu_exit(int);
|
||||
|
||||
/* Internal MD routines -- for use only by kthread_fpu_enter/exit. */
|
||||
void kthread_fpu_enter_md(void);
|
||||
void kthread_fpu_exit_md(void);
|
||||
|
||||
#endif /* _SYS_KTHREAD_H_ */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: lwp.h,v 1.210 2020/05/23 20:45:11 ad Exp $ */
|
||||
/* $NetBSD: lwp.h,v 1.211 2020/08/01 02:04:55 riastradh Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001, 2006, 2007, 2008, 2009, 2010, 2019, 2020
|
||||
|
@ -256,6 +256,7 @@ extern int maxlwp __read_mostly; /* max number of lwps */
|
|||
#define LW_STIMO 0x00000040 /* Sleep timed out */
|
||||
#define LW_SINTR 0x00000080 /* Sleep is interruptible. */
|
||||
#define LW_SYSTEM 0x00000200 /* Kernel thread */
|
||||
#define LW_SYSTEM_FPU 0x00000400 /* Kernel thread with vector/FP enabled */
|
||||
#define LW_DBGSUSPEND 0x00010000 /* Suspend by debugger */
|
||||
#define LW_WSUSPEND 0x00020000 /* Suspend before return to user */
|
||||
#define LW_BATCH 0x00040000 /* LWP tends to hog CPU */
|
||||
|
|
Loading…
Reference in New Issue