Browse Source

Kernel+ProcessManager: Expose the number of kmalloc/kfree calls.

This will be very helpful in tracking down unwanted kmalloc traffic. :^)
Andreas Kling 6 years ago
parent
commit
e9c0f4567d

+ 12 - 6
Applications/ProcessManager/MemoryStatsWidget.cpp

@@ -10,7 +10,7 @@ MemoryStatsWidget::MemoryStatsWidget(GWidget* parent)
     : GWidget(parent)
     : GWidget(parent)
 {
 {
     set_size_policy(SizePolicy::Fill, SizePolicy::Fixed);
     set_size_policy(SizePolicy::Fill, SizePolicy::Fixed);
-    set_preferred_size({ 0, 60 });
+    set_preferred_size({ 0, 72 });
 
 
     set_layout(make<GBoxLayout>(Orientation::Vertical));
     set_layout(make<GBoxLayout>(Orientation::Vertical));
     layout()->set_margins({ 0, 8, 0, 0 });
     layout()->set_margins({ 0, 8, 0, 0 });
@@ -20,7 +20,7 @@ MemoryStatsWidget::MemoryStatsWidget(GWidget* parent)
         auto* container = new GWidget(this);
         auto* container = new GWidget(this);
         container->set_layout(make<GBoxLayout>(Orientation::Horizontal));
         container->set_layout(make<GBoxLayout>(Orientation::Horizontal));
         container->set_size_policy(SizePolicy::Fixed, SizePolicy::Fixed);
         container->set_size_policy(SizePolicy::Fixed, SizePolicy::Fixed);
-        container->set_preferred_size({ 250, 12 });
+        container->set_preferred_size({ 255, 12 });
         auto* description_label = new GLabel(description, container);
         auto* description_label = new GLabel(description, container);
         description_label->set_font(Font::default_bold_font());
         description_label->set_font(Font::default_bold_font());
         description_label->set_text_alignment(TextAlignment::CenterLeft);
         description_label->set_text_alignment(TextAlignment::CenterLeft);
@@ -32,6 +32,7 @@ MemoryStatsWidget::MemoryStatsWidget(GWidget* parent)
     m_user_physical_pages_label = build_widgets_for_label("Userspace physical:");
     m_user_physical_pages_label = build_widgets_for_label("Userspace physical:");
     m_supervisor_physical_pages_label = build_widgets_for_label("Supervisor physical:");
     m_supervisor_physical_pages_label = build_widgets_for_label("Supervisor physical:");
     m_kmalloc_label = build_widgets_for_label("Kernel heap:");
     m_kmalloc_label = build_widgets_for_label("Kernel heap:");
+    m_kmalloc_count_label = build_widgets_for_label("Calls kmalloc/kfree:");
 
 
     start_timer(1000);
     start_timer(1000);
     refresh();
     refresh();
@@ -65,7 +66,7 @@ void MemoryStatsWidget::refresh()
         if (!ptr)
         if (!ptr)
             break;
             break;
         auto parts = String(buf, Chomp).split(',');
         auto parts = String(buf, Chomp).split(',');
-        if (parts.size() < 7)
+        if (parts.size() < 9)
             break;
             break;
         bool ok;
         bool ok;
         unsigned kmalloc_sum_eternal = parts[0].to_uint(ok);
         unsigned kmalloc_sum_eternal = parts[0].to_uint(ok);
@@ -83,14 +84,19 @@ void MemoryStatsWidget::refresh()
         ASSERT(ok);
         ASSERT(ok);
         unsigned supervisor_pages_free = parts[6].to_uint(ok);
         unsigned supervisor_pages_free = parts[6].to_uint(ok);
         ASSERT(ok);
         ASSERT(ok);
+        unsigned kmalloc_call_count = parts[7].to_uint(ok);
+        ASSERT(ok);
+        unsigned kfree_call_count = parts[8].to_uint(ok);
+        ASSERT(ok);
 
 
         size_t kmalloc_sum_available = kmalloc_sum_alloc + kmalloc_sum_free;
         size_t kmalloc_sum_available = kmalloc_sum_alloc + kmalloc_sum_free;
         size_t user_pages_available = user_pages_alloc + user_pages_free;
         size_t user_pages_available = user_pages_alloc + user_pages_free;
         size_t supervisor_pages_available = supervisor_pages_alloc + supervisor_pages_free;
         size_t supervisor_pages_available = supervisor_pages_alloc + supervisor_pages_free;
 
 
-        m_kmalloc_label->set_text(String::format("%uK/%uK\n", bytes_to_kb(kmalloc_sum_alloc), bytes_to_kb(kmalloc_sum_available)));
-        m_user_physical_pages_label->set_text(String::format("%uK/%uK\n", page_count_to_kb(user_pages_alloc), page_count_to_kb(user_pages_available)));
-        m_supervisor_physical_pages_label->set_text(String::format("%uK/%uK\n", page_count_to_kb(supervisor_pages_alloc), page_count_to_kb(supervisor_pages_available)));
+        m_kmalloc_label->set_text(String::format("%uK/%uK", bytes_to_kb(kmalloc_sum_alloc), bytes_to_kb(kmalloc_sum_available)));
+        m_user_physical_pages_label->set_text(String::format("%uK/%uK", page_count_to_kb(user_pages_alloc), page_count_to_kb(user_pages_available)));
+        m_supervisor_physical_pages_label->set_text(String::format("%uK/%uK", page_count_to_kb(supervisor_pages_alloc), page_count_to_kb(supervisor_pages_available)));
+        m_kmalloc_count_label->set_text(String::format("%u/%u (+%u)", kmalloc_call_count, kfree_call_count, kmalloc_call_count - kfree_call_count));
         break;
         break;
     }
     }
 
 

+ 1 - 0
Applications/ProcessManager/MemoryStatsWidget.h

@@ -18,4 +18,5 @@ private:
     GLabel* m_user_physical_pages_label { nullptr };
     GLabel* m_user_physical_pages_label { nullptr };
     GLabel* m_supervisor_physical_pages_label { nullptr };
     GLabel* m_supervisor_physical_pages_label { nullptr };
     GLabel* m_kmalloc_label { nullptr };
     GLabel* m_kmalloc_label { nullptr };
+    GLabel* m_kmalloc_count_label { nullptr };
 };
 };

+ 5 - 2
Kernel/FileSystem/ProcFS.cpp

@@ -8,6 +8,7 @@
 #include "Console.h"
 #include "Console.h"
 #include "Scheduler.h"
 #include "Scheduler.h"
 #include <Kernel/PCI.h>
 #include <Kernel/PCI.h>
+#include <Kernel/kmalloc.h>
 #include <AK/StringBuilder.h>
 #include <AK/StringBuilder.h>
 #include <LibC/errno_numbers.h>
 #include <LibC/errno_numbers.h>
 
 
@@ -558,14 +559,16 @@ ByteBuffer procfs$memstat(InodeIdentifier)
 {
 {
     InterruptDisabler disabler;
     InterruptDisabler disabler;
     StringBuilder builder;
     StringBuilder builder;
-    builder.appendf("%u,%u,%u,%u,%u,%u,%u\n",
+    builder.appendf("%u,%u,%u,%u,%u,%u,%u,%u,%u\n",
         kmalloc_sum_eternal,
         kmalloc_sum_eternal,
         sum_alloc,
         sum_alloc,
         sum_free,
         sum_free,
         MM.user_physical_pages_in_existence() - MM.m_free_physical_pages.size(),
         MM.user_physical_pages_in_existence() - MM.m_free_physical_pages.size(),
         MM.m_free_physical_pages.size(),
         MM.m_free_physical_pages.size(),
         MM.super_physical_pages_in_existence() - MM.m_free_supervisor_physical_pages.size(),
         MM.super_physical_pages_in_existence() - MM.m_free_supervisor_physical_pages.size(),
-        MM.m_free_supervisor_physical_pages.size()
+        MM.m_free_supervisor_physical_pages.size(),
+        g_kmalloc_call_count,
+        g_kfree_call_count
     );
     );
     return builder.to_byte_buffer();
     return builder.to_byte_buffer();
 }
 }

+ 5 - 0
Kernel/kmalloc.cpp

@@ -33,6 +33,9 @@ volatile size_t sum_alloc = 0;
 volatile size_t sum_free = POOL_SIZE;
 volatile size_t sum_free = POOL_SIZE;
 volatile size_t kmalloc_sum_eternal = 0;
 volatile size_t kmalloc_sum_eternal = 0;
 
 
+dword g_kmalloc_call_count;
+dword g_kfree_call_count;
+
 static byte* s_next_eternal_ptr;
 static byte* s_next_eternal_ptr;
 static byte* s_end_of_eternal_range;
 static byte* s_end_of_eternal_range;
 
 
@@ -90,6 +93,7 @@ void* kmalloc_page_aligned(size_t size)
 void* kmalloc_impl(size_t size)
 void* kmalloc_impl(size_t size)
 {
 {
     InterruptDisabler disabler;
     InterruptDisabler disabler;
+    ++g_kmalloc_call_count;
 
 
     // We need space for the allocation_t structure at the head of the block.
     // We need space for the allocation_t structure at the head of the block.
     size_t real_size = size + sizeof(allocation_t);
     size_t real_size = size + sizeof(allocation_t);
@@ -153,6 +157,7 @@ void* kmalloc_impl(size_t size)
 
 
 void kfree(void *ptr)
 void kfree(void *ptr)
 {
 {
+    ++g_kfree_call_count;
     if (!ptr)
     if (!ptr)
         return;
         return;
 
 

+ 2 - 0
Kernel/kmalloc.h

@@ -18,6 +18,8 @@ extern volatile size_t sum_alloc;
 extern volatile size_t sum_free;
 extern volatile size_t sum_free;
 extern volatile size_t kmalloc_sum_eternal;
 extern volatile size_t kmalloc_sum_eternal;
 extern volatile size_t kmalloc_sum_page_aligned;
 extern volatile size_t kmalloc_sum_page_aligned;
+extern dword g_kmalloc_call_count;
+extern dword g_kfree_call_count;
 
 
 inline void* operator new(size_t, void* p) { return p; }
 inline void* operator new(size_t, void* p) { return p; }
 inline void* operator new[](size_t, void* p) { return p; }
 inline void* operator new[](size_t, void* p) { return p; }