1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 08:57:34 +00:00

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.
This commit is contained in:
Brian Gianforcaro 2021-05-18 01:49:34 -07:00 committed by Andreas Kling
parent 1415b2cfc3
commit 7540f4268b
2 changed files with 15 additions and 14 deletions

View file

@ -924,15 +924,13 @@ UNMAP_AFTER_INIT void write_xcr0(u64 value)
READONLY_AFTER_INIT FPUState Processor::s_clean_fpu_state; READONLY_AFTER_INIT FPUState Processor::s_clean_fpu_state;
READONLY_AFTER_INIT static Vector<Processor*>* s_processors; READONLY_AFTER_INIT static ProcessorContainer s_processors {};
static SpinLock s_processor_lock;
READONLY_AFTER_INIT volatile u32 Processor::g_total_processors; READONLY_AFTER_INIT volatile u32 Processor::g_total_processors;
static volatile bool s_smp_enabled; 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) Processor& Processor::by_id(u32 cpu)
@ -1239,13 +1237,9 @@ UNMAP_AFTER_INIT void Processor::initialize(u32 cpu)
m_info = new ProcessorInfo(*this); m_info = new ProcessorInfo(*this);
{ {
ScopedSpinLock lock(s_processor_lock);
// We need to prevent races between APs starting up at the same time // We need to prevent races between APs starting up at the same time
if (!s_processors) VERIFY(cpu < s_processors.size());
s_processors = new Vector<Processor*>(); s_processors[cpu] = this;
if (cpu >= s_processors->size())
s_processors->resize(cpu + 1);
(*s_processors)[cpu] = this;
} }
} }

View file

@ -623,6 +623,11 @@ struct DeferredCallEntry {
bool was_allocated; 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 { class Processor {
friend class ProcessorInfo; friend class ProcessorInfo;
@ -665,7 +670,7 @@ class Processor {
void gdt_init(); void gdt_init();
void write_raw_gdt_entry(u16 selector, u32 low, u32 high); void write_raw_gdt_entry(u16 selector, u32 low, u32 high);
void write_gdt_entry(u16 selector, Descriptor& descriptor); void write_gdt_entry(u16 selector, Descriptor& descriptor);
static Vector<Processor*>& processors(); static ProcessorContainer& processors();
static void smp_return_to_pool(ProcessorMessage& msg); static void smp_return_to_pool(ProcessorMessage& msg);
static ProcessorMessage& smp_get_from_pool(); static ProcessorMessage& smp_get_from_pool();
@ -751,8 +756,10 @@ public:
{ {
auto& procs = processors(); auto& procs = processors();
size_t count = procs.size(); size_t count = procs.size();
for (size_t i = 0; i < count; i++) for (size_t i = 0; i < count; i++) {
callback(*procs[i]); if (procs[i] != nullptr)
callback(*procs[i]);
}
return IterationDecision::Continue; return IterationDecision::Continue;
} }