diff options
author | Damien Zammit <damien@zamaudio.com> | 2023-08-05 07:49:54 +0000 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2023-08-05 10:43:07 +0200 |
commit | 22f2a7160fa0795894b0d50de4c216add33e5f2b (patch) | |
tree | ea393725efea61e66d8ad98417f4bd7099096252 | |
parent | 5e25bd3cbd2be0e510d53e2b35ddb2c54a8e0ac5 (diff) | |
download | gnumach-22f2a7160fa0795894b0d50de4c216add33e5f2b.tar.gz gnumach-22f2a7160fa0795894b0d50de4c216add33e5f2b.tar.bz2 gnumach-22f2a7160fa0795894b0d50de4c216add33e5f2b.zip |
cpu_number: Look up cpu kernel_id via lookup table
This speeds up smp slightly by reducing the cpu_number()
complexity to have no branching, just a look up table.
It also addresses the problem that CPU_NUMBER was only using
raw apic_id as an approximation of the kernel_id.
Other improvements were to remove unnecessary checks now that
the lookup table always resolves to a valid value.
Message-Id: <20230805074945.1983707-1-damien@zamaudio.com>
-rw-r--r-- | i386/i386/apic.c | 33 | ||||
-rw-r--r-- | i386/i386/apic.h | 2 | ||||
-rw-r--r-- | i386/i386/cpu_number.c | 19 | ||||
-rw-r--r-- | i386/i386/cpu_number.h | 1 | ||||
-rw-r--r-- | i386/i386at/acpi_parse_apic.c | 2 |
5 files changed, 28 insertions, 29 deletions
diff --git a/i386/i386/apic.c b/i386/i386/apic.c index c399074d..2bb8e3f1 100644 --- a/i386/i386/apic.c +++ b/i386/i386/apic.c @@ -35,6 +35,11 @@ static ApicLocalUnit dummy_lapic = {0}; volatile ApicLocalUnit* lapic = &dummy_lapic; +/* This lookup table of [apic_id] -> kernel_id is initially populated with zeroes + * so every lookup results in master processor until real kernel ids are populated. + */ +int cpu_id_lut[UINT8_MAX + 1] = {0}; + ApicInfo apic_data; /* @@ -137,14 +142,7 @@ apic_get_cpu_apic_id(int kernel_id) int apic_get_cpu_kernel_id(uint16_t apic_id) { - int i; - - for (i = 0; i < apic_data.ncpus; i++) { - if (apic_data.cpu_lapic_list[i] == apic_id) - return i; - } - - return -1; + return cpu_id_lut[apic_id]; } /* apic_get_lapic: returns a reference to the common memory address for Local APIC. */ @@ -187,9 +185,6 @@ apic_get_num_ioapics(void) int apic_get_current_cpu(void) { - if(lapic == NULL) - return -1; - return (lapic->apic_id.r >> 24) & 0xff; } @@ -223,6 +218,22 @@ int apic_refit_cpulist(void) } /* + * apic_generate_cpu_id_lut: Generate lookup table of cpu kernel ids from apic ids + */ +void apic_generate_cpu_id_lut(void) +{ + int i, apic_id; + + for (i = 0; i < apic_data.ncpus; i++) { + apic_id = apic_get_cpu_apic_id(i); + if (apic_id >= 0) + cpu_id_lut[apic_id] = i; + else + printf("apic_get_cpu_apic_id(%d) failed...\n", i); + } +} + +/* * apic_print_info: shows the list of Local APIC and IOAPIC. * Shows each CPU and IOAPIC, with Its Kernel ID and APIC ID. */ diff --git a/i386/i386/apic.h b/i386/i386/apic.h index 73e32dfe..e870dcf8 100644 --- a/i386/i386/apic.h +++ b/i386/i386/apic.h @@ -238,6 +238,7 @@ uint8_t apic_get_num_ioapics(void); int apic_get_current_cpu(void); void apic_print_info(void); int apic_refit_cpulist(void); +void apic_generate_cpu_id_lut(void); void picdisable(void); void lapic_eoi(void); void ioapic_irq_eoi(int pin); @@ -250,6 +251,7 @@ void ioapic_configure(void); extern int timer_pin; extern void intnull(int unit); extern volatile ApicLocalUnit* lapic; +extern int cpu_id_lut[]; #endif diff --git a/i386/i386/cpu_number.c b/i386/i386/cpu_number.c index 1d2fab3a..ef19e11f 100644 --- a/i386/i386/cpu_number.c +++ b/i386/i386/cpu_number.c @@ -25,23 +25,6 @@ #if NCPUS > 1 int cpu_number(void) { - int kernel_id, apic_id; - - if (bspdone == 0) - return 0; - - apic_id = apic_get_current_cpu(); - if (apic_id < 0) { - printf("apic_get_current_cpu() failed, assuming BSP\n"); - apic_id = 0; - } - - kernel_id = apic_get_cpu_kernel_id(apic_id); - if (kernel_id < 0) { - printf("apic_get_cpu_kernel_id() failed, assuming BSP\n"); - kernel_id = 0; - } - - return kernel_id; + return cpu_id_lut[apic_get_current_cpu()]; } #endif diff --git a/i386/i386/cpu_number.h b/i386/i386/cpu_number.h index a5658471..c00896e8 100644 --- a/i386/i386/cpu_number.h +++ b/i386/i386/cpu_number.h @@ -43,6 +43,7 @@ movl %cs:lapic, reg ;\ movl %cs:APIC_ID(reg), reg ;\ shrl $24, reg ;\ + movl %cs:CX(cpu_id_lut, reg), reg ;\ #ifndef __ASSEMBLER__ #include "kern/cpu_number.h" diff --git a/i386/i386at/acpi_parse_apic.c b/i386/i386at/acpi_parse_apic.c index 27e3410d..9cd861ed 100644 --- a/i386/i386at/acpi_parse_apic.c +++ b/i386/i386at/acpi_parse_apic.c @@ -483,6 +483,8 @@ acpi_apic_setup(struct acpi_apic *apic) return ACPI_FIT_FAILURE; } + apic_generate_cpu_id_lut(); + return ACPI_SUCCESS; } |