Browse Source

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.
Brian Gianforcaro 4 years ago
parent
commit
7540f4268b
2 changed files with 15 additions and 14 deletions
  1. 5 11
      Kernel/Arch/i386/CPU.cpp
  2. 10 3
      Kernel/Arch/x86/CPU.h

+ 5 - 11
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;
     }
 }
 

+ 10 - 3
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;
     }