summaryrefslogtreecommitdiff
path: root/Kernel/Arch
diff options
context:
space:
mode:
authorBrian Gianforcaro <bgianf@serenityos.org>2021-05-18 01:49:34 -0700
committerAndreas Kling <kling@serenityos.org>2021-05-20 08:10:07 +0200
commit7540f4268b96d3ee28f394defd6c88a77d6a6ae8 (patch)
tree115db69cc7c07a2bdb299d244cee3063150c2f60 /Kernel/Arch
parent1415b2cfc300db1128fce1fa98e3e10a49810610 (diff)
downloadserenity-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.cpp16
-rw-r--r--Kernel/Arch/x86/CPU.h13
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;
}