Bläddra i källkod

Kernel: Allocate profiling memory upfront

We need to allocate all pages for the profiler right away so that
we don't trigger page faults in the timer interrupt handler to
allocate them.

Fixes #4734
Tom 4 år sedan
förälder
incheckning
60f5f48dd1
2 ändrade filer med 14 tillägg och 11 borttagningar
  1. 6 6
      Kernel/KBuffer.h
  2. 8 5
      Kernel/Profiling.cpp

+ 6 - 6
Kernel/KBuffer.h

@@ -106,25 +106,25 @@ private:
 
 class KBuffer {
 public:
-    static OwnPtr<KBuffer> try_create_with_size(size_t size, u8 access = Region::Access::Read | Region::Access::Write, const char* name = "KBuffer")
+    static OwnPtr<KBuffer> try_create_with_size(size_t size, u8 access = Region::Access::Read | Region::Access::Write, const char* name = "KBuffer", AllocationStrategy strategy = AllocationStrategy::Reserve)
     {
-        auto impl = KBufferImpl::try_create_with_size(size, access, name);
+        auto impl = KBufferImpl::try_create_with_size(size, access, name, strategy);
         if (!impl)
             return nullptr;
         return adopt_own(*new KBuffer(impl.release_nonnull()));
     }
 
-    static OwnPtr<KBuffer> try_create_with_bytes(ReadonlyBytes bytes, u8 access = Region::Access::Read | Region::Access::Write, const char* name = "KBuffer")
+    static OwnPtr<KBuffer> try_create_with_bytes(ReadonlyBytes bytes, u8 access = Region::Access::Read | Region::Access::Write, const char* name = "KBuffer", AllocationStrategy strategy = AllocationStrategy::Reserve)
     {
-        auto impl = KBufferImpl::try_create_with_bytes(bytes, access, name);
+        auto impl = KBufferImpl::try_create_with_bytes(bytes, access, name, strategy);
         if (!impl)
             return nullptr;
         return adopt_own(*new KBuffer(impl.release_nonnull()));
     }
 
-    static KBuffer create_with_size(size_t size, u8 access = Region::Access::Read | Region::Access::Write, const char* name = "KBuffer")
+    static KBuffer create_with_size(size_t size, u8 access = Region::Access::Read | Region::Access::Write, const char* name = "KBuffer", AllocationStrategy strategy = AllocationStrategy::Reserve)
     {
-        return KBuffer(KBufferImpl::create_with_size(size, access, name));
+        return KBuffer(KBufferImpl::create_with_size(size, access, name, strategy));
     }
 
     static KBuffer copy(const void* data, size_t size, u8 access = Region::Access::Read | Region::Access::Write, const char* name = "KBuffer")

+ 8 - 5
Kernel/Profiling.cpp

@@ -25,6 +25,7 @@
  */
 
 #include <AK/Demangle.h>
+#include <AK/Singleton.h>
 #include <AK/StringBuilder.h>
 #include <Kernel/FileSystem/Custody.h>
 #include <Kernel/KBuffer.h>
@@ -36,8 +37,13 @@ namespace Kernel {
 
 namespace Profiling {
 
-static KBufferImpl* s_profiling_buffer;
 static size_t s_slot_count;
+static AK::Singleton<KBuffer, []() -> KBuffer* {
+    auto buffer = KBuffer::try_create_with_size(8 * MiB, Region::Access::Read | Region::Access::Write, "Profiling Buffer", AllocationStrategy::AllocateNow);
+    s_slot_count = buffer->size() / sizeof(Sample);
+    return buffer.leak_ptr();
+}>
+    s_profiling_buffer;
 static size_t s_next_slot_index;
 static ProcessID s_pid { -1 };
 
@@ -62,10 +68,7 @@ void start(Process& process)
         executable_path() = {};
     s_pid = process.pid();
 
-    if (!s_profiling_buffer) {
-        s_profiling_buffer = RefPtr<KBufferImpl>(KBuffer::create_with_size(8 * MiB).impl()).leak_ref();
-        s_slot_count = s_profiling_buffer->size() / sizeof(Sample);
-    }
+    s_profiling_buffer.ensure_instance();
 
     s_next_slot_index = 0;
 }