[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.
This commit is contained in:
parent
4657c46f73
commit
6d27ee5dc5
|
@ -141,7 +141,7 @@ extern "C" void interrupt_apic_timer(InterruptFrame*) {
|
||||||
cnt++;
|
cnt++;
|
||||||
if (cnt % 20 == 0) {
|
if (cnt % 20 == 0) {
|
||||||
if (cnt == 20) {
|
if (cnt == 20) {
|
||||||
KernelHeap::DumpDistribution();
|
KernelHeap::DumpDebugData();
|
||||||
}
|
}
|
||||||
dbgln("timer: {}s", cnt * 50 / 1000);
|
dbgln("timer: {}s", cnt * 50 / 1000);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include "debug/debug.h"
|
#include "debug/debug.h"
|
||||||
#include "memory/paging_util.h"
|
#include "memory/paging_util.h"
|
||||||
|
|
||||||
#define K_HEAP_DEBUG 0
|
#define K_HEAP_DEBUG 1
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -38,9 +38,6 @@ void KernelHeap::InitializeSlabAllocators() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void* KernelHeap::Allocate(uint64_t size) {
|
void* KernelHeap::Allocate(uint64_t size) {
|
||||||
#if K_HEAP_DEBUG
|
|
||||||
dbgln("Alloc ({x})", size);
|
|
||||||
#endif
|
|
||||||
if ((size <= 8) && slab_8_) {
|
if ((size <= 8) && slab_8_) {
|
||||||
auto ptr_or = slab_8_->Allocate();
|
auto ptr_or = slab_8_->Allocate();
|
||||||
if (ptr_or.ok()) {
|
if (ptr_or.ok()) {
|
||||||
|
@ -77,31 +74,58 @@ void* KernelHeap::Allocate(uint64_t size) {
|
||||||
#endif
|
#endif
|
||||||
EnsureResident(next_addr_, size);
|
EnsureResident(next_addr_, size);
|
||||||
uint64_t address = next_addr_;
|
uint64_t address = next_addr_;
|
||||||
|
alloc_count_ += 1;
|
||||||
next_addr_ += size;
|
next_addr_ += size;
|
||||||
return reinterpret_cast<void*>(address);
|
return reinterpret_cast<void*>(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KernelHeap::DumpDistribution() {
|
void KernelHeap::DumpDebugData() {
|
||||||
#if K_HEAP_DEBUG
|
#if K_HEAP_DEBUG
|
||||||
uint64_t* distributions = gKernelHeap->distributions;
|
gKernelHeap->DumpDebugDataInternal();
|
||||||
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]);
|
|
||||||
#endif
|
#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) {
|
void KernelHeap::RecordSize(uint64_t size) {
|
||||||
size -= 1;
|
size -= 1;
|
||||||
size >>= 2;
|
size >>= 3;
|
||||||
uint64_t index = 0;
|
uint64_t index = 0;
|
||||||
while (size && index < 11) {
|
while (size && index < 11) {
|
||||||
size >>= 1;
|
size >>= 1;
|
||||||
|
|
|
@ -14,30 +14,33 @@ class KernelHeap {
|
||||||
|
|
||||||
void Free(void* address);
|
void Free(void* address);
|
||||||
|
|
||||||
static void DumpDistribution();
|
static void DumpDebugData();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint64_t next_addr_;
|
uint64_t next_addr_;
|
||||||
uint64_t upper_bound_;
|
uint64_t upper_bound_;
|
||||||
|
|
||||||
|
uint64_t alloc_count_ = 0;
|
||||||
|
|
||||||
glcr::UniquePtr<SlabAllocator> slab_8_;
|
glcr::UniquePtr<SlabAllocator> slab_8_;
|
||||||
glcr::UniquePtr<SlabAllocator> slab_16_;
|
glcr::UniquePtr<SlabAllocator> slab_16_;
|
||||||
glcr::UniquePtr<SlabAllocator> slab_32_;
|
glcr::UniquePtr<SlabAllocator> slab_32_;
|
||||||
|
|
||||||
// Distribution collection for the purpose of investigating a slab allocator.
|
// Distribution collection for the purpose of investigating a slab allocator.
|
||||||
// 0: 0-4B
|
// 0: 0-8B
|
||||||
// 1: 4B-8B
|
// 1: 8B-16B
|
||||||
// 2: 8B-16B
|
// 2: 16B-32B
|
||||||
// 3: 16B-32B
|
// 3: 32B-64B
|
||||||
// 4: 32B-64B
|
// 4: 64B-128B
|
||||||
// 5: 64B-128B
|
// 5: 128B-256B
|
||||||
// 6: 128B-256B
|
// 6: 256B-512B
|
||||||
// 7: 256B-512B
|
// 7: 512B-1KiB
|
||||||
// 8: 512B-1KiB
|
// 8: 1KiB-2KiB
|
||||||
// 9: 1KiB-2KiB
|
// 9: 2KiB-4KiB
|
||||||
// 10: 2KiB-4KiB
|
// 10: 4KiB+
|
||||||
// 11: 4KiB+
|
uint64_t distributions[11];
|
||||||
uint64_t distributions[12];
|
|
||||||
|
|
||||||
void RecordSize(uint64_t size);
|
void RecordSize(uint64_t size);
|
||||||
|
|
||||||
|
void DumpDebugDataInternal();
|
||||||
};
|
};
|
||||||
|
|
|
@ -93,3 +93,23 @@ glcr::ErrorOr<void*> SlabAllocator::Allocate() {
|
||||||
slabs_.PushFront(glcr::AdoptPtr(new (next_slab) Slab(elem_size_)));
|
slabs_.PushFront(glcr::AdoptPtr(new (next_slab) Slab(elem_size_)));
|
||||||
return slabs_.PeekFront()->Allocate();
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ class Slab : public glcr::RefCounted<Slab>,
|
||||||
void Free(void* addr);
|
void Free(void* addr);
|
||||||
|
|
||||||
bool IsFull();
|
bool IsFull();
|
||||||
|
uint64_t Allocations() { return num_allocated_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct FreeListEntry {
|
struct FreeListEntry {
|
||||||
|
@ -39,6 +40,10 @@ class SlabAllocator {
|
||||||
|
|
||||||
glcr::ErrorOr<void*> Allocate();
|
glcr::ErrorOr<void*> Allocate();
|
||||||
|
|
||||||
|
// Stats:
|
||||||
|
uint64_t SlabCount();
|
||||||
|
uint64_t Allocations();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint64_t elem_size_;
|
uint64_t elem_size_;
|
||||||
glcr::IntrusiveList<Slab> slabs_;
|
glcr::IntrusiveList<Slab> slabs_;
|
||||||
|
|
|
@ -55,7 +55,7 @@ extern "C" void zion() {
|
||||||
LoadInitProgram();
|
LoadInitProgram();
|
||||||
|
|
||||||
dbgln("[boot] Allocs during boot:");
|
dbgln("[boot] Allocs during boot:");
|
||||||
heap.DumpDistribution();
|
heap.DumpDebugData();
|
||||||
|
|
||||||
dbgln("[boot] Init finished, yielding.");
|
dbgln("[boot] Init finished, yielding.");
|
||||||
gScheduler->Enable();
|
gScheduler->Enable();
|
||||||
|
|
Loading…
Reference in New Issue