Implement accessors for per-cpu variables which don't depend on the

symbols in globals.s.

	PCPU_GET(name) returns the value of the per-cpu variable
	PCPU_PTR(name) returns a pointer to the per-cpu variable
	PCPU_SET(name, val) sets the value of the per-cpu variable

In general these are not yet used, compatibility macros remain.

Unifdef SMP struct globaldata, this makes variables such as cpuid
available for UP as well.

Rebuilding modules is probably a good idea, but I believe old
modules will still work, as most of the old infrastructure
remains.
This commit is contained in:
Jake Burkholder 2001-01-06 19:55:42 +00:00
parent 12e275aaee
commit f8761e53a7
7 changed files with 52 additions and 156 deletions

View File

@ -41,6 +41,7 @@ register struct globaldata *globalp __asm__("$8");
#endif #endif
#define PCPU_GET(name) (GLOBALP->gd_##name) #define PCPU_GET(name) (GLOBALP->gd_##name)
#define PCPU_PTR(name) (&GLOBALP->gd_##name)
#define PCPU_SET(name,value) (GLOBALP->gd_##name = (value)) #define PCPU_SET(name,value) (GLOBALP->gd_##name = (value))
/* /*

View File

@ -61,11 +61,11 @@ struct globaldata {
struct timeval gd_switchtime; struct timeval gd_switchtime;
struct i386tss gd_common_tss; struct i386tss gd_common_tss;
int gd_switchticks; int gd_switchticks;
int gd_intr_nesting_level; u_char gd_intr_nesting_level;
u_char gd_pad0[3];
struct segment_descriptor gd_common_tssd; struct segment_descriptor gd_common_tssd;
struct segment_descriptor *gd_tss_gdt; struct segment_descriptor *gd_tss_gdt;
int gd_currentldt; /* only used for USER_LDT */ int gd_currentldt; /* only used for USER_LDT */
#ifdef SMP
u_int gd_cpuid; u_int gd_cpuid;
u_int gd_cpu_lockid; u_int gd_cpu_lockid;
u_int gd_other_cpus; u_int gd_other_cpus;
@ -79,7 +79,6 @@ struct globaldata {
caddr_t gd_prv_CADDR2; caddr_t gd_prv_CADDR2;
caddr_t gd_prv_CADDR3; caddr_t gd_prv_CADDR3;
unsigned *gd_prv_PADDR1; unsigned *gd_prv_PADDR1;
#endif
u_int gd_astpending; u_int gd_astpending;
SLIST_ENTRY(globaldata) gd_allcpu; SLIST_ENTRY(globaldata) gd_allcpu;
int gd_witness_spin_check; int gd_witness_spin_check;

View File

@ -61,11 +61,11 @@ struct globaldata {
struct timeval gd_switchtime; struct timeval gd_switchtime;
struct i386tss gd_common_tss; struct i386tss gd_common_tss;
int gd_switchticks; int gd_switchticks;
int gd_intr_nesting_level; u_char gd_intr_nesting_level;
u_char gd_pad0[3];
struct segment_descriptor gd_common_tssd; struct segment_descriptor gd_common_tssd;
struct segment_descriptor *gd_tss_gdt; struct segment_descriptor *gd_tss_gdt;
int gd_currentldt; /* only used for USER_LDT */ int gd_currentldt; /* only used for USER_LDT */
#ifdef SMP
u_int gd_cpuid; u_int gd_cpuid;
u_int gd_cpu_lockid; u_int gd_cpu_lockid;
u_int gd_other_cpus; u_int gd_other_cpus;
@ -79,7 +79,6 @@ struct globaldata {
caddr_t gd_prv_CADDR2; caddr_t gd_prv_CADDR2;
caddr_t gd_prv_CADDR3; caddr_t gd_prv_CADDR3;
unsigned *gd_prv_PADDR1; unsigned *gd_prv_PADDR1;
#endif
u_int gd_astpending; u_int gd_astpending;
SLIST_ENTRY(globaldata) gd_allcpu; SLIST_ENTRY(globaldata) gd_allcpu;
int gd_witness_spin_check; int gd_witness_spin_check;

View File

@ -1,6 +1,8 @@
/*- /*-
* Copyright (c) 1999 Luoqi Chen <luoqi@freebsd.org> * Copyright (c) 1999 Luoqi Chen <luoqi@freebsd.org>
* All rights reserved. * All rights reserved.
* Copyright (c) 2000 Jake Burkholder <jake@freebsd.org>
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -31,161 +33,55 @@
#ifdef _KERNEL #ifdef _KERNEL
#define GLOBAL_LVALUE(name, type) \ #include <machine/globaldata.h>
(*(type *)_global_ptr_##name())
#define GLOBAL_RVALUE(name, type) \
((type)_global_##name())
/* non-volatile version */ static __inline struct globaldata *
#define GLOBAL_LVALUE_NV(name, type) \
(*(type *)_global_ptr_##name##_nv())
#define GLOBAL_RVALUE_NV(name, type) \
((type)_global_##name##_nv())
#define GLOBAL_FUNC(name) \
static __inline void *_global_ptr_##name(void) { \
void *val; \
__asm __volatile("movl $gd_" #name ",%0;" \
"addl %%fs:globaldata,%0" : "=r" (val)); \
return (val); \
} \
static __inline void *_global_ptr_##name##_nv(void) { \
void *val; \
__asm("movl $gd_" #name ",%0;" \
"addl %%fs:globaldata,%0" : "=r" (val)); \
return (val); \
} \
static __inline int _global_##name(void) { \
int val; \
__asm __volatile("movl %%fs:gd_" #name ",%0" : "=r" (val)); \
return (val); \
} \
static __inline int _global_##name##_nv(void) { \
int val; \
__asm("movl %%fs:gd_" #name ",%0" : "=r" (val)); \
return (val); \
} \
static __inline void _global_##name##_set(int val) { \
__asm __volatile("movl %0,%%fs:gd_" #name : : "r" (val)); \
} \
static __inline void _global_##name##_set_nv(int val) { \
__asm("movl %0,%%fs:gd_" #name : : "r" (val)); \
}
static __inline int
_global_globaldata(void) _global_globaldata(void)
{ {
int val; struct globaldata *gd;
__asm("movl %%fs:globaldata,%0" : "=r" (val)); int offset;
return (val);
offset = offsetof(struct globaldata, gd_prvspace);
__asm __volatile("movl %%fs:%1,%0"
: "=r" (gd)
: "m" (*(struct globaldata *)(offset)));
return (gd);
} }
/* #if defined(SMP) || defined(KLD_MODULE) */ #define GLOBALDATA (_global_globaldata())
#if 1
/*
* The following set of macros works for UP kernel as well, but for maximum
* performance we allow the global variables to be accessed directly. On the
* other hand, kernel modules should always use these macros to maintain
* portability between UP and SMP kernels.
*/
#define curproc GLOBAL_RVALUE_NV(curproc, struct proc *)
#define curpcb GLOBAL_RVALUE_NV(curpcb, struct pcb *)
#define npxproc GLOBAL_RVALUE_NV(npxproc, struct proc *)
#define idleproc GLOBAL_RVALUE_NV(idleproc, struct proc *)
#define common_tss GLOBAL_LVALUE(common_tss, struct i386tss)
#define switchtime GLOBAL_LVALUE(switchtime, struct timeval)
#define switchticks GLOBAL_LVALUE(switchticks, int)
#define intr_nesting_level GLOBAL_RVALUE(intr_nesting_level, u_char)
#define common_tssd GLOBAL_LVALUE(common_tssd, struct segment_descriptor) #define PCPU_GET(member) (GLOBALDATA->gd_ ## member)
#define tss_gdt GLOBAL_LVALUE(tss_gdt, struct segment_descriptor *) #define PCPU_PTR(member) (&GLOBALDATA->gd_ ## member)
#define astpending GLOBAL_RVALUE(astpending, u_int) #define PCPU_SET(member, val) (GLOBALDATA->gd_ ## member = (val))
#ifdef USER_LDT #define CURPROC PCPU_GET(curproc)
#define currentldt GLOBAL_RVALUE(currentldt, int) #define CURTHD PCPU_GET(curproc)
#endif
#ifdef SMP #define astpending PCPU_GET(astpending)
#define cpuid GLOBAL_RVALUE(cpuid, u_int) #define common_tss (*PCPU_PTR(common_tss))
#define other_cpus GLOBAL_LVALUE(other_cpus, u_int) #define common_tssd (*PCPU_PTR(common_tssd))
#define inside_intr GLOBAL_LVALUE(inside_intr, int) #define cpuid PCPU_GET(cpuid)
#define prv_CMAP1 GLOBAL_LVALUE(prv_CMAP1, pt_entry_t *) #define currentldt PCPU_GET(currentldt)
#define prv_CMAP2 GLOBAL_LVALUE(prv_CMAP2, pt_entry_t *) #define curpcb PCPU_GET(curpcb)
#define prv_CMAP3 GLOBAL_LVALUE(prv_CMAP3, pt_entry_t *) #define curproc PCPU_GET(curproc)
#define prv_PMAP1 GLOBAL_LVALUE(prv_PMAP1, pt_entry_t *) #define idleproc PCPU_GET(idleproc)
#define prv_CADDR1 GLOBAL_RVALUE(prv_CADDR1, caddr_t) #define inside_intr (*PCPU_PTR(inside_intr))
#define prv_CADDR2 GLOBAL_RVALUE(prv_CADDR2, caddr_t) #define intr_nesting_level PCPU_GET(intr_nesting_level)
#define prv_CADDR3 GLOBAL_RVALUE(prv_CADDR3, caddr_t) #define npxproc PCPU_GET(npxproc)
#define prv_PADDR1 GLOBAL_RVALUE(prv_PADDR1, unsigned *) #define prv_CMAP1 (*PCPU_PTR(prv_CMAP1))
#endif #define prv_CMAP2 (*PCPU_PTR(prv_CMAP2))
#define prv_CMAP3 (*PCPU_PTR(prv_CMAP3))
#define witness_spin_check GLOBAL_RVALUE(witness_spin_check, int) #define prv_PMAP1 (*PCPU_PTR(prv_PMAP1))
#define prv_CADDR1 PCPU_GET(prv_CADDR1)
#else /* !(SMP || KLD_MODULE) */ #define prv_CADDR2 PCPU_GET(prv_CADDR2)
#define prv_CADDR3 PCPU_GET(prv_CADDR3)
extern u_int astpending; #define prv_PADDR1 PCPU_GET(prv_PADDR1)
extern struct i386tss common_tss; #define other_cpus (*PCPU_PTR(other_cpus))
extern struct segment_descriptor common_tssd; #define switchticks (*PCPU_PTR(switchticks))
extern struct pcb *curpcb; /* Our current running pcb. */ #define switchtime (*PCPU_PTR(switchtime))
extern struct proc *curproc; /* Current running proc. */ #define tss_gdt (*PCPU_PTR(tss_gdt))
extern struct proc *idleproc; /* Current idle proc. */ #define witness_spin_check PCPU_GET(witness_spin_check)
extern u_char intr_nesting_level;
extern struct proc *npxproc;
extern int switchticks; /* `ticks' at last context switch. */
extern struct timeval switchtime; /* Uptime at last context switch. */
extern struct segment_descriptor *tss_gdt;
extern int witness_spin_check;
#endif /* SMP || KLD_MODULE */
GLOBAL_FUNC(curproc)
GLOBAL_FUNC(astpending)
GLOBAL_FUNC(curpcb)
GLOBAL_FUNC(npxproc)
GLOBAL_FUNC(idleproc)
GLOBAL_FUNC(common_tss)
GLOBAL_FUNC(switchtime)
GLOBAL_FUNC(switchticks)
GLOBAL_FUNC(intr_nesting_level)
GLOBAL_FUNC(common_tssd)
GLOBAL_FUNC(tss_gdt)
/* XXX */
#ifdef KTR_PERCPU
GLOBAL_FUNC(ktr_idx)
GLOBAL_FUNC(ktr_buf)
GLOBAL_FUNC(ktr_buf_data)
#endif
#ifdef USER_LDT
GLOBAL_FUNC(currentldt)
#endif
#ifdef SMP
GLOBAL_FUNC(cpuid)
GLOBAL_FUNC(other_cpus)
GLOBAL_FUNC(inside_intr)
GLOBAL_FUNC(prv_CMAP1)
GLOBAL_FUNC(prv_CMAP2)
GLOBAL_FUNC(prv_CMAP3)
GLOBAL_FUNC(prv_PMAP1)
GLOBAL_FUNC(prv_CADDR1)
GLOBAL_FUNC(prv_CADDR2)
GLOBAL_FUNC(prv_CADDR3)
GLOBAL_FUNC(prv_PADDR1)
#endif
GLOBAL_FUNC(witness_spin_check)
#define GLOBALDATA GLOBAL_RVALUE(globaldata, struct globaldata *)
#define CURTHD curproc
#define CURPROC curproc
#define PCPU_SET(name, value) (_global_##name##_set((int)value))
#endif /* _KERNEL */ #endif /* _KERNEL */

View File

@ -61,11 +61,11 @@ struct globaldata {
struct timeval gd_switchtime; struct timeval gd_switchtime;
struct i386tss gd_common_tss; struct i386tss gd_common_tss;
int gd_switchticks; int gd_switchticks;
int gd_intr_nesting_level; u_char gd_intr_nesting_level;
u_char gd_pad0[3];
struct segment_descriptor gd_common_tssd; struct segment_descriptor gd_common_tssd;
struct segment_descriptor *gd_tss_gdt; struct segment_descriptor *gd_tss_gdt;
int gd_currentldt; /* only used for USER_LDT */ int gd_currentldt; /* only used for USER_LDT */
#ifdef SMP
u_int gd_cpuid; u_int gd_cpuid;
u_int gd_cpu_lockid; u_int gd_cpu_lockid;
u_int gd_other_cpus; u_int gd_other_cpus;
@ -79,7 +79,6 @@ struct globaldata {
caddr_t gd_prv_CADDR2; caddr_t gd_prv_CADDR2;
caddr_t gd_prv_CADDR3; caddr_t gd_prv_CADDR3;
unsigned *gd_prv_PADDR1; unsigned *gd_prv_PADDR1;
#endif
u_int gd_astpending; u_int gd_astpending;
SLIST_ENTRY(globaldata) gd_allcpu; SLIST_ENTRY(globaldata) gd_allcpu;
int gd_witness_spin_check; int gd_witness_spin_check;

View File

@ -41,6 +41,7 @@ register struct globaldata *globalp __asm__("r13");
#endif #endif
#define PCPU_GET(name) (GLOBALP->gd_##name) #define PCPU_GET(name) (GLOBALP->gd_##name)
#define PCPU_PTR(name) (&GLOBALP->gd_##name)
#define PCPU_SET(name,value) (GLOBALP->gd_##name = (value)) #define PCPU_SET(name,value) (GLOBALP->gd_##name = (value))
/* /*

View File

@ -41,6 +41,7 @@ register struct globaldata *globalp __asm__("$8");
#endif #endif
#define PCPU_GET(name) (GLOBALP->gd_##name) #define PCPU_GET(name) (GLOBALP->gd_##name)
#define PCPU_PTR(name) (&GLOBALP->gd_##name)
#define PCPU_SET(name,value) (GLOBALP->gd_##name = (value)) #define PCPU_SET(name,value) (GLOBALP->gd_##name = (value))
/* /*