From 6d27ee5dc56f4e4cdd9f8f1bb62c2c6a7491c731 Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Wed, 15 Nov 2023 12:36:18 -0800 Subject: [PATCH] [Zion] Add more debug information about kernel heap usage. This will be helpful as we work to improve it. Without deallocations, we currently stand at the following alloc numbers 8 - 142 16 - 319 32 - 364 unsized - 305 total page usage including slabs is 12. --- zion/interrupt/interrupt.cpp | 2 +- zion/memory/kernel_heap.cpp | 62 +++++++++++++++++++++++----------- zion/memory/kernel_heap.h | 31 +++++++++-------- zion/memory/slab_allocator.cpp | 20 +++++++++++ zion/memory/slab_allocator.h | 5 +++ zion/zion.cpp | 2 +- 6 files changed, 87 insertions(+), 35 deletions(-) diff --git a/zion/interrupt/interrupt.cpp b/zion/interrupt/interrupt.cpp index bc299e7..a93bd53 100644 --- a/zion/interrupt/interrupt.cpp +++ b/zion/interrupt/interrupt.cpp @@ -141,7 +141,7 @@ extern "C" void interrupt_apic_timer(InterruptFrame*) { cnt++; if (cnt % 20 == 0) { if (cnt == 20) { - KernelHeap::DumpDistribution(); + KernelHeap::DumpDebugData(); } dbgln("timer: {}s", cnt * 50 / 1000); } diff --git a/zion/memory/kernel_heap.cpp b/zion/memory/kernel_heap.cpp index fb95310..ecce12d 100644 --- a/zion/memory/kernel_heap.cpp +++ b/zion/memory/kernel_heap.cpp @@ -3,7 +3,7 @@ #include "debug/debug.h" #include "memory/paging_util.h" -#define K_HEAP_DEBUG 0 +#define K_HEAP_DEBUG 1 namespace { @@ -38,9 +38,6 @@ void KernelHeap::InitializeSlabAllocators() { } void* KernelHeap::Allocate(uint64_t size) { -#if K_HEAP_DEBUG - dbgln("Alloc ({x})", size); -#endif if ((size <= 8) && slab_8_) { auto ptr_or = slab_8_->Allocate(); if (ptr_or.ok()) { @@ -77,31 +74,58 @@ void* KernelHeap::Allocate(uint64_t size) { #endif EnsureResident(next_addr_, size); uint64_t address = next_addr_; + alloc_count_ += 1; next_addr_ += size; return reinterpret_cast(address); } -void KernelHeap::DumpDistribution() { +void KernelHeap::DumpDebugData() { #if K_HEAP_DEBUG - uint64_t* distributions = gKernelHeap->distributions; - dbgln("<=4B: {}", distributions[0]); - dbgln("<=8B: {}", distributions[1]); - dbgln("<=16B: {}", distributions[2]); - dbgln("<=32B: {}", distributions[3]); - dbgln("<=64B: {}", distributions[4]); - dbgln("<=128B: {}", distributions[5]); - dbgln("<=256B: {}", distributions[6]); - dbgln("<=512B: {}", distributions[7]); - dbgln("<=1KiB: {}", distributions[8]); - dbgln("<=2KiB: {}", distributions[9]); - dbgln("<=4KiB: {}", distributions[10]); - dbgln("> 4KiB: {}", distributions[11]); + gKernelHeap->DumpDebugDataInternal(); #endif } +void KernelHeap::DumpDebugDataInternal() { + dbgln(""); + dbgln("Heap Debug Statistics!"); + + dbgln("Pages used: {}", (next_addr_ - 0xFFFFFFFF60000000 - 1) / 0x1000 + 1); + // Active Allocs. + dbgln("Active Allocations: {}", alloc_count_); + + dbgln("Slab Statistics:"); + if (slab_8_) { + dbgln("Slab 8: {} slabs, {} allocs", slab_8_->SlabCount(), + slab_8_->Allocations()); + } + if (slab_16_) { + dbgln("Slab 16: {} slabs, {} allocs", slab_16_->SlabCount(), + slab_16_->Allocations()); + } + if (slab_32_) { + dbgln("Slab 32: {} slabs, {} allocs", slab_32_->SlabCount(), + slab_32_->Allocations()); + } + + dbgln(""); + dbgln("Size Distributions of non slab-allocated."); + dbgln("<=8B: {}", distributions[0]); + dbgln("<=16B: {}", distributions[1]); + dbgln("<=32B: {}", distributions[2]); + dbgln("<=64B: {}", distributions[3]); + dbgln("<=128B: {}", distributions[4]); + dbgln("<=256B: {}", distributions[5]); + dbgln("<=512B: {}", distributions[6]); + dbgln("<=1KiB: {}", distributions[7]); + dbgln("<=2KiB: {}", distributions[8]); + dbgln("<=4KiB: {}", distributions[9]); + dbgln("> 4KiB: {}", distributions[10]); + dbgln(""); +} + void KernelHeap::RecordSize(uint64_t size) { size -= 1; - size >>= 2; + size >>= 3; uint64_t index = 0; while (size && index < 11) { size >>= 1; diff --git a/zion/memory/kernel_heap.h b/zion/memory/kernel_heap.h index dc024f0..20ed9f1 100644 --- a/zion/memory/kernel_heap.h +++ b/zion/memory/kernel_heap.h @@ -14,30 +14,33 @@ class KernelHeap { void Free(void* address); - static void DumpDistribution(); + static void DumpDebugData(); private: uint64_t next_addr_; uint64_t upper_bound_; + uint64_t alloc_count_ = 0; + glcr::UniquePtr slab_8_; glcr::UniquePtr slab_16_; glcr::UniquePtr slab_32_; // Distribution collection for the purpose of investigating a slab allocator. - // 0: 0-4B - // 1: 4B-8B - // 2: 8B-16B - // 3: 16B-32B - // 4: 32B-64B - // 5: 64B-128B - // 6: 128B-256B - // 7: 256B-512B - // 8: 512B-1KiB - // 9: 1KiB-2KiB - // 10: 2KiB-4KiB - // 11: 4KiB+ - uint64_t distributions[12]; + // 0: 0-8B + // 1: 8B-16B + // 2: 16B-32B + // 3: 32B-64B + // 4: 64B-128B + // 5: 128B-256B + // 6: 256B-512B + // 7: 512B-1KiB + // 8: 1KiB-2KiB + // 9: 2KiB-4KiB + // 10: 4KiB+ + uint64_t distributions[11]; void RecordSize(uint64_t size); + + void DumpDebugDataInternal(); }; diff --git a/zion/memory/slab_allocator.cpp b/zion/memory/slab_allocator.cpp index 28cd24a..19d22d2 100644 --- a/zion/memory/slab_allocator.cpp +++ b/zion/memory/slab_allocator.cpp @@ -93,3 +93,23 @@ glcr::ErrorOr SlabAllocator::Allocate() { slabs_.PushFront(glcr::AdoptPtr(new (next_slab) Slab(elem_size_))); return slabs_.PeekFront()->Allocate(); } + +uint64_t SlabAllocator::SlabCount() { + auto slab = slabs_.PeekFront(); + uint64_t count = 0; + while (slab) { + count++; + slab = slab->next_; + } + return count; +} + +uint64_t SlabAllocator::Allocations() { + auto slab = slabs_.PeekFront(); + uint64_t count = 0; + while (slab) { + count += slab->Allocations(); + slab = slab->next_; + } + return count; +} diff --git a/zion/memory/slab_allocator.h b/zion/memory/slab_allocator.h index aab4c83..1e2c9ff 100644 --- a/zion/memory/slab_allocator.h +++ b/zion/memory/slab_allocator.h @@ -19,6 +19,7 @@ class Slab : public glcr::RefCounted, void Free(void* addr); bool IsFull(); + uint64_t Allocations() { return num_allocated_; } private: struct FreeListEntry { @@ -39,6 +40,10 @@ class SlabAllocator { glcr::ErrorOr Allocate(); + // Stats: + uint64_t SlabCount(); + uint64_t Allocations(); + private: uint64_t elem_size_; glcr::IntrusiveList slabs_; diff --git a/zion/zion.cpp b/zion/zion.cpp index 7f3c035..feb6b13 100644 --- a/zion/zion.cpp +++ b/zion/zion.cpp @@ -55,7 +55,7 @@ extern "C" void zion() { LoadInitProgram(); dbgln("[boot] Allocs during boot:"); - heap.DumpDistribution(); + heap.DumpDebugData(); dbgln("[boot] Init finished, yielding."); gScheduler->Enable();