From b11e10e2c81c2b608176021364a36d84173358e3 Mon Sep 17 00:00:00 2001 From: Damien Zammit Date: Sun, 24 Sep 2023 10:35:10 +0000 Subject: percpu area using gs segment This speeds up smp again, by storing the struct processor in a percpu area and avoiding an expensive cpu_number every call of current_processor(), as well as getting the cpu_number by an offset into the percpu area. Untested on 64 bit and work remains to use other percpu arrays. TESTED: (NCPUS=8) -smp 1 boots to login shell ~2x slower than uniprocessor TESTED: (NCPUS=8) -smp 2 boots to INIT but hangs there TESTED: (NCPUS=8) -smp 4 gets stuck seemingly within rumpdisk and hangs TESTED: (NCPUS=1) uniprocessor is a bit faster than normal Message-Id: <20230924103428.455966-3-damien@zamaudio.com> --- kern/cpu_number.h | 3 ++- kern/processor.c | 7 ++----- kern/processor.h | 17 +++++------------ kern/startup.c | 3 ++- 4 files changed, 11 insertions(+), 19 deletions(-) (limited to 'kern') diff --git a/kern/cpu_number.h b/kern/cpu_number.h index 0be2d338..1abe3dbb 100644 --- a/kern/cpu_number.h +++ b/kern/cpu_number.h @@ -37,7 +37,8 @@ extern int master_cpu; /* 'master' processor - keeps time */ #if (NCPUS == 1) /* cpu number is always 0 on a single processor system */ -#define cpu_number() (0) +#define cpu_number() (0) +#define cpu_number_slow() (0) #endif /* NCPUS == 1 */ diff --git a/kern/processor.c b/kern/processor.c index 2cd6d46c..76735381 100644 --- a/kern/processor.c +++ b/kern/processor.c @@ -60,14 +60,12 @@ struct kmem_cache pset_cache; int master_cpu; struct processor_set default_pset; -struct processor processor_array[NCPUS]; queue_head_t all_psets; int all_psets_count; def_simple_lock_data(, all_psets_lock); processor_t master_processor; -processor_t processor_ptr[NCPUS]; /* * Bootstrap the processor/pset system so the scheduler can run. @@ -81,10 +79,9 @@ void pset_sys_bootstrap(void) for (i = 0; i < NCPUS; i++) { /* * Initialize processor data structures. - * Note that cpu_to_processor(i) is processor_ptr[i]. + * Note that cpu_to_processor is processor_ptr. */ - processor_ptr[i] = &processor_array[i]; - processor_init(processor_ptr[i], i); + processor_init(processor_ptr(i), i); } master_processor = cpu_to_processor(master_cpu); queue_init(&all_psets); diff --git a/kern/processor.h b/kern/processor.h index 79386627..fc204ffa 100644 --- a/kern/processor.h +++ b/kern/processor.h @@ -112,6 +112,7 @@ typedef struct processor Processor; extern struct processor processor_array[NCPUS]; #include +#include /* * Chain of all processor sets. @@ -196,23 +197,15 @@ extern processor_t master_processor; #define PROCESSOR_ASSIGN 4 /* Assignment is changing */ #define PROCESSOR_SHUTDOWN 5 /* Being shutdown */ -/* - * Use processor ptr array to find current processor's data structure. - * This replaces a multiplication (index into processor_array) with - * an array lookup and a memory reference. It also allows us to save - * space if processor numbering gets too sparse. - */ - -extern processor_t processor_ptr[NCPUS]; - -#define cpu_to_processor(i) (processor_ptr[i]) +#define processor_ptr(i) (&percpu_array[i].processor) +#define cpu_to_processor processor_ptr -#define current_processor() (processor_ptr[cpu_number()]) +#define current_processor() (percpu_ptr(struct processor, processor)) #define current_processor_set() (current_processor()->processor_set) /* Compatibility -- will go away */ -#define cpu_state(slot_num) (processor_ptr[slot_num]->state) +#define cpu_state(slot_num) (processor_ptr(slot_num)->state) #define cpu_idle(slot_num) (cpu_state(slot_num) == PROCESSOR_IDLE) /* Useful lock macros */ diff --git a/kern/startup.c b/kern/startup.c index 2eb3a739..88608c7d 100644 --- a/kern/startup.c +++ b/kern/startup.c @@ -74,6 +74,7 @@ boolean_t reboot_on_panic = TRUE; #if NCPUS > 1 #include +#include #include #endif /* NCPUS > 1 */ @@ -281,7 +282,7 @@ void cpu_launch_first_thread(thread_t th) { int mycpu; - mycpu = cpu_number(); + mycpu = cpu_number_slow(); cpu_up(mycpu); -- cgit v1.2.3