diff options
author | Brian Gianforcaro <bgianf@serenityos.org> | 2021-05-18 01:49:34 -0700 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-05-20 08:10:07 +0200 |
commit | 7540f4268b96d3ee28f394defd6c88a77d6a6ae8 (patch) | |
tree | 115db69cc7c07a2bdb299d244cee3063150c2f60 /Kernel/Arch | |
parent | 1415b2cfc300db1128fce1fa98e3e10a49810610 (diff) | |
download | serenity-7540f4268b96d3ee28f394defd6c88a77d6a6ae8.zip |
Kernel: Remove s_processor_lock by making s_processors statically sized
Currently in SMP mode we hard code support for up to only 8 processors.
There is no reason for this to be a dynamic allocation that needs to be
guarded by a spinlock. Instead use a Array<T* with inline storage of 8,
allowing each processor to initialize it self in place, avoiding all
the need for locks.
Diffstat (limited to 'Kernel/Arch')
-rw-r--r-- | Kernel/Arch/i386/CPU.cpp | 16 | ||||
-rw-r--r-- | Kernel/Arch/x86/CPU.h | 13 |
2 files changed, 15 insertions, 14 deletions
diff --git a/Kernel/Arch/i386/CPU.cpp b/Kernel/Arch/i386/CPU.cpp index 10b8136662..984a69dd05 100644 --- a/Kernel/Arch/i386/CPU.cpp +++ b/Kernel/Arch/i386/CPU.cpp @@ -924,15 +924,13 @@ UNMAP_AFTER_INIT void write_xcr0(u64 value) READONLY_AFTER_INIT FPUState Processor::s_clean_fpu_state; -READONLY_AFTER_INIT static Vector<Processor*>* s_processors; -static SpinLock s_processor_lock; +READONLY_AFTER_INIT static ProcessorContainer s_processors {}; READONLY_AFTER_INIT volatile u32 Processor::g_total_processors; static volatile bool s_smp_enabled; -Vector<Processor*>& Processor::processors() +ProcessorContainer& Processor::processors() { - VERIFY(s_processors); - return *s_processors; + return s_processors; } Processor& Processor::by_id(u32 cpu) @@ -1239,13 +1237,9 @@ UNMAP_AFTER_INIT void Processor::initialize(u32 cpu) m_info = new ProcessorInfo(*this); { - ScopedSpinLock lock(s_processor_lock); // We need to prevent races between APs starting up at the same time - if (!s_processors) - s_processors = new Vector<Processor*>(); - if (cpu >= s_processors->size()) - s_processors->resize(cpu + 1); - (*s_processors)[cpu] = this; + VERIFY(cpu < s_processors.size()); + s_processors[cpu] = this; } } diff --git a/Kernel/Arch/x86/CPU.h b/Kernel/Arch/x86/CPU.h index 488443a7fc..060821cba7 100644 --- a/Kernel/Arch/x86/CPU.h +++ b/Kernel/Arch/x86/CPU.h @@ -623,6 +623,11 @@ struct DeferredCallEntry { bool was_allocated; }; +class Processor; +// Note: We only support processors at most at the moment, +// so allocate 8 slots of inline capacity in the container. +using ProcessorContainer = Array<Processor*, 8>; + class Processor { friend class ProcessorInfo; @@ -665,7 +670,7 @@ class Processor { void gdt_init(); void write_raw_gdt_entry(u16 selector, u32 low, u32 high); void write_gdt_entry(u16 selector, Descriptor& descriptor); - static Vector<Processor*>& processors(); + static ProcessorContainer& processors(); static void smp_return_to_pool(ProcessorMessage& msg); static ProcessorMessage& smp_get_from_pool(); @@ -751,8 +756,10 @@ public: { auto& procs = processors(); size_t count = procs.size(); - for (size_t i = 0; i < count; i++) - callback(*procs[i]); + for (size_t i = 0; i < count; i++) { + if (procs[i] != nullptr) + callback(*procs[i]); + } return IterationDecision::Continue; } |