From 864582fb568e319abb29b21763d338b1129a36bb Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 6 Jan 2001 19:55:42 +0000 Subject: [PATCH] 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. --- sys/alpha/include/globals.h | 1 + sys/amd64/include/pcpu.h | 5 +- sys/i386/include/globaldata.h | 5 +- sys/i386/include/globals.h | 190 ++++++++-------------------------- sys/i386/include/pcpu.h | 5 +- sys/ia64/include/globals.h | 1 + sys/powerpc/include/globals.h | 1 + 7 files changed, 52 insertions(+), 156 deletions(-) diff --git a/sys/alpha/include/globals.h b/sys/alpha/include/globals.h index 970ef683495e..85fcad3c40fa 100644 --- a/sys/alpha/include/globals.h +++ b/sys/alpha/include/globals.h @@ -41,6 +41,7 @@ register struct globaldata *globalp __asm__("$8"); #endif #define PCPU_GET(name) (GLOBALP->gd_##name) +#define PCPU_PTR(name) (&GLOBALP->gd_##name) #define PCPU_SET(name,value) (GLOBALP->gd_##name = (value)) /* diff --git a/sys/amd64/include/pcpu.h b/sys/amd64/include/pcpu.h index 90c3bd733df2..173cb08264d0 100644 --- a/sys/amd64/include/pcpu.h +++ b/sys/amd64/include/pcpu.h @@ -61,11 +61,11 @@ struct globaldata { struct timeval gd_switchtime; struct i386tss gd_common_tss; 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_tss_gdt; int gd_currentldt; /* only used for USER_LDT */ -#ifdef SMP u_int gd_cpuid; u_int gd_cpu_lockid; u_int gd_other_cpus; @@ -79,7 +79,6 @@ struct globaldata { caddr_t gd_prv_CADDR2; caddr_t gd_prv_CADDR3; unsigned *gd_prv_PADDR1; -#endif u_int gd_astpending; SLIST_ENTRY(globaldata) gd_allcpu; int gd_witness_spin_check; diff --git a/sys/i386/include/globaldata.h b/sys/i386/include/globaldata.h index 90c3bd733df2..173cb08264d0 100644 --- a/sys/i386/include/globaldata.h +++ b/sys/i386/include/globaldata.h @@ -61,11 +61,11 @@ struct globaldata { struct timeval gd_switchtime; struct i386tss gd_common_tss; 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_tss_gdt; int gd_currentldt; /* only used for USER_LDT */ -#ifdef SMP u_int gd_cpuid; u_int gd_cpu_lockid; u_int gd_other_cpus; @@ -79,7 +79,6 @@ struct globaldata { caddr_t gd_prv_CADDR2; caddr_t gd_prv_CADDR3; unsigned *gd_prv_PADDR1; -#endif u_int gd_astpending; SLIST_ENTRY(globaldata) gd_allcpu; int gd_witness_spin_check; diff --git a/sys/i386/include/globals.h b/sys/i386/include/globals.h index 386810c19f4b..140ee8aaae79 100644 --- a/sys/i386/include/globals.h +++ b/sys/i386/include/globals.h @@ -1,6 +1,8 @@ /*- * Copyright (c) 1999 Luoqi Chen * All rights reserved. + * Copyright (c) 2000 Jake Burkholder + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -31,161 +33,55 @@ #ifdef _KERNEL -#define GLOBAL_LVALUE(name, type) \ - (*(type *)_global_ptr_##name()) - -#define GLOBAL_RVALUE(name, type) \ - ((type)_global_##name()) +#include -/* non-volatile version */ -#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 +static __inline struct globaldata * _global_globaldata(void) { - int val; - __asm("movl %%fs:globaldata,%0" : "=r" (val)); - return (val); + struct globaldata *gd; + int offset; + + 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) */ -#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 GLOBALDATA (_global_globaldata()) -#define common_tssd GLOBAL_LVALUE(common_tssd, struct segment_descriptor) -#define tss_gdt GLOBAL_LVALUE(tss_gdt, struct segment_descriptor *) -#define astpending GLOBAL_RVALUE(astpending, u_int) +#define PCPU_GET(member) (GLOBALDATA->gd_ ## member) +#define PCPU_PTR(member) (&GLOBALDATA->gd_ ## member) +#define PCPU_SET(member, val) (GLOBALDATA->gd_ ## member = (val)) -#ifdef USER_LDT -#define currentldt GLOBAL_RVALUE(currentldt, int) -#endif +#define CURPROC PCPU_GET(curproc) +#define CURTHD PCPU_GET(curproc) -#ifdef SMP -#define cpuid GLOBAL_RVALUE(cpuid, u_int) -#define other_cpus GLOBAL_LVALUE(other_cpus, u_int) -#define inside_intr GLOBAL_LVALUE(inside_intr, int) -#define prv_CMAP1 GLOBAL_LVALUE(prv_CMAP1, pt_entry_t *) -#define prv_CMAP2 GLOBAL_LVALUE(prv_CMAP2, pt_entry_t *) -#define prv_CMAP3 GLOBAL_LVALUE(prv_CMAP3, pt_entry_t *) -#define prv_PMAP1 GLOBAL_LVALUE(prv_PMAP1, pt_entry_t *) -#define prv_CADDR1 GLOBAL_RVALUE(prv_CADDR1, caddr_t) -#define prv_CADDR2 GLOBAL_RVALUE(prv_CADDR2, caddr_t) -#define prv_CADDR3 GLOBAL_RVALUE(prv_CADDR3, caddr_t) -#define prv_PADDR1 GLOBAL_RVALUE(prv_PADDR1, unsigned *) -#endif - -#define witness_spin_check GLOBAL_RVALUE(witness_spin_check, int) - -#else /* !(SMP || KLD_MODULE) */ - -extern u_int astpending; -extern struct i386tss common_tss; -extern struct segment_descriptor common_tssd; -extern struct pcb *curpcb; /* Our current running pcb. */ -extern struct proc *curproc; /* Current running proc. */ -extern struct proc *idleproc; /* Current idle proc. */ -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)) +#define astpending PCPU_GET(astpending) +#define common_tss (*PCPU_PTR(common_tss)) +#define common_tssd (*PCPU_PTR(common_tssd)) +#define cpuid PCPU_GET(cpuid) +#define currentldt PCPU_GET(currentldt) +#define curpcb PCPU_GET(curpcb) +#define curproc PCPU_GET(curproc) +#define idleproc PCPU_GET(idleproc) +#define inside_intr (*PCPU_PTR(inside_intr)) +#define intr_nesting_level PCPU_GET(intr_nesting_level) +#define npxproc PCPU_GET(npxproc) +#define prv_CMAP1 (*PCPU_PTR(prv_CMAP1)) +#define prv_CMAP2 (*PCPU_PTR(prv_CMAP2)) +#define prv_CMAP3 (*PCPU_PTR(prv_CMAP3)) +#define prv_PMAP1 (*PCPU_PTR(prv_PMAP1)) +#define prv_CADDR1 PCPU_GET(prv_CADDR1) +#define prv_CADDR2 PCPU_GET(prv_CADDR2) +#define prv_CADDR3 PCPU_GET(prv_CADDR3) +#define prv_PADDR1 PCPU_GET(prv_PADDR1) +#define other_cpus (*PCPU_PTR(other_cpus)) +#define switchticks (*PCPU_PTR(switchticks)) +#define switchtime (*PCPU_PTR(switchtime)) +#define tss_gdt (*PCPU_PTR(tss_gdt)) +#define witness_spin_check PCPU_GET(witness_spin_check) #endif /* _KERNEL */ diff --git a/sys/i386/include/pcpu.h b/sys/i386/include/pcpu.h index 90c3bd733df2..173cb08264d0 100644 --- a/sys/i386/include/pcpu.h +++ b/sys/i386/include/pcpu.h @@ -61,11 +61,11 @@ struct globaldata { struct timeval gd_switchtime; struct i386tss gd_common_tss; 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_tss_gdt; int gd_currentldt; /* only used for USER_LDT */ -#ifdef SMP u_int gd_cpuid; u_int gd_cpu_lockid; u_int gd_other_cpus; @@ -79,7 +79,6 @@ struct globaldata { caddr_t gd_prv_CADDR2; caddr_t gd_prv_CADDR3; unsigned *gd_prv_PADDR1; -#endif u_int gd_astpending; SLIST_ENTRY(globaldata) gd_allcpu; int gd_witness_spin_check; diff --git a/sys/ia64/include/globals.h b/sys/ia64/include/globals.h index c036d9ec5365..7faa5ff08c28 100644 --- a/sys/ia64/include/globals.h +++ b/sys/ia64/include/globals.h @@ -41,6 +41,7 @@ register struct globaldata *globalp __asm__("r13"); #endif #define PCPU_GET(name) (GLOBALP->gd_##name) +#define PCPU_PTR(name) (&GLOBALP->gd_##name) #define PCPU_SET(name,value) (GLOBALP->gd_##name = (value)) /* diff --git a/sys/powerpc/include/globals.h b/sys/powerpc/include/globals.h index 970ef683495e..85fcad3c40fa 100644 --- a/sys/powerpc/include/globals.h +++ b/sys/powerpc/include/globals.h @@ -41,6 +41,7 @@ register struct globaldata *globalp __asm__("$8"); #endif #define PCPU_GET(name) (GLOBALP->gd_##name) +#define PCPU_PTR(name) (&GLOBALP->gd_##name) #define PCPU_SET(name,value) (GLOBALP->gd_##name = (value)) /*