Changeset View
Standalone View
sys/amd64/amd64/fpu.c
Show All 32 Lines | |||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/bus.h> | #include <sys/bus.h> | ||||
#include <sys/domainset.h> | |||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/lock.h> | #include <sys/lock.h> | ||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/module.h> | #include <sys/module.h> | ||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <sys/proc.h> | #include <sys/proc.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
▲ Show 20 Lines • Show All 974 Lines • ▼ Show 20 Lines | |||||
#define FPU_KERN_CTX_INUSE 0x04 | #define FPU_KERN_CTX_INUSE 0x04 | ||||
struct fpu_kern_ctx { | struct fpu_kern_ctx { | ||||
struct savefpu *prev; | struct savefpu *prev; | ||||
uint32_t flags; | uint32_t flags; | ||||
char hwstate1[]; | char hwstate1[]; | ||||
}; | }; | ||||
static inline size_t __pure2 | |||||
fpu_kern_alloc_sz(u_int max_est) | |||||
{ | |||||
return (sizeof(struct fpu_kern_ctx) + XSAVE_AREA_ALIGN + max_est); | |||||
} | |||||
static inline int __pure2 | |||||
fpu_kern_malloc_flags(u_int fpflags) | |||||
{ | |||||
return (((fpflags & FPU_KERN_NOWAIT) ? M_NOWAIT : M_WAITOK) | M_ZERO); | |||||
} | |||||
struct fpu_kern_ctx * | struct fpu_kern_ctx * | ||||
fpu_kern_alloc_ctx(u_int flags) | fpu_kern_alloc_ctx_domainset(struct domainset *ds, u_int flags) | ||||
markj: I would pass the domain index here instead of the policy. In practice we'll only ever want to… | |||||
cemAuthorUnsubmitted Done Inline ActionsThe general pattern for other _domainset variant functions has been to pass the policy; in callers this looks like fpu_kern_alloc_ctx_domainset(DOMAINSET_PREF(foo), 0) which seems clear to me. The alternative I think you're proposing is just making the PREF policy hardcoded in this function, and passing a plain domain? That might be fine, but we might want to use a different name. fpu_kern_alloc_ctx_domain_pref is a bit unwieldy, and fpu_kern_alloc_ctx_domain elides the PREF policy. I don't have any preference here. If we use domainid_t, it looks like we need to pull in the entire sys/domainset.h header rather than just forward-declaring a struct. cem: The general pattern for other `_domainset` variant functions has been to pass the policy; in… | |||||
markjUnsubmitted Done Inline ActionsRight, I'd just pass an int domain. fpu_kern_alloc_ctx_domain seems reasonable to me - the use of _PREF is really just an internal detail that handles the possibility of empty domains. markj: Right, I'd just pass an `int domain`.
`fpu_kern_alloc_ctx_domain` seems reasonable to me - the… | |||||
{ | { | ||||
struct fpu_kern_ctx *res; | return (malloc_domainset(fpu_kern_alloc_sz(cpu_max_ext_state_size), | ||||
size_t sz; | M_FPUKERN_CTX, ds, fpu_kern_malloc_flags(flags))); | ||||
} | |||||
sz = sizeof(struct fpu_kern_ctx) + XSAVE_AREA_ALIGN + | struct fpu_kern_ctx * | ||||
cpu_max_ext_state_size; | fpu_kern_alloc_ctx(u_int flags) | ||||
res = malloc(sz, M_FPUKERN_CTX, ((flags & FPU_KERN_NOWAIT) ? | { | ||||
M_NOWAIT : M_WAITOK) | M_ZERO); | return (malloc(fpu_kern_alloc_sz(cpu_max_ext_state_size), | ||||
return (res); | M_FPUKERN_CTX, fpu_kern_malloc_flags(flags))); | ||||
} | } | ||||
void | void | ||||
fpu_kern_free_ctx(struct fpu_kern_ctx *ctx) | fpu_kern_free_ctx(struct fpu_kern_ctx *ctx) | ||||
{ | { | ||||
Done Inline ActionsI would suggest calling plain malloc() in this case instead. The use of RR here overrides policy that might be specified in the malloc zones, or in the calling thread, or in the kernel VM object. markj: I would suggest calling plain malloc() in this case instead. The use of RR here overrides… | |||||
KASSERT((ctx->flags & FPU_KERN_CTX_INUSE) == 0, ("free'ing inuse ctx")); | KASSERT((ctx->flags & FPU_KERN_CTX_INUSE) == 0, ("free'ing inuse ctx")); | ||||
/* XXXKIB clear the memory ? */ | /* XXXKIB clear the memory ? */ | ||||
free(ctx, M_FPUKERN_CTX); | free(ctx, M_FPUKERN_CTX); | ||||
} | } | ||||
static struct savefpu * | static struct savefpu * | ||||
fpu_kern_ctx_savefpu(struct fpu_kern_ctx *ctx) | fpu_kern_ctx_savefpu(struct fpu_kern_ctx *ctx) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 153 Lines • Show Last 20 Lines |
I would pass the domain index here instead of the policy. In practice we'll only ever want to use the default policy (first-touch, implemented by malloc()/UMA), or request memory from a specific domain (DOMAINSET_PREF), and it makes the consumer KPI a bit lighter.