summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDoug Gilbert <dgilbert@us.ibm.com>2011-12-13 14:46:48 -0600
committerDouglas R. Gilbert <dgilbert@us.ibm.com>2012-01-12 10:46:18 -0600
commit47f456fec103ec096edb5e0b9fcff54acbcd3d24 (patch)
tree478f16727ec00b72da727bdffa5d467d131b22be /src
parentb93f3dc742c0fa8d16f130938b56feb48e5bd7d7 (diff)
downloadtalos-hostboot-47f456fec103ec096edb5e0b9fcff54acbcd3d24.tar.gz
talos-hostboot-47f456fec103ec096edb5e0b9fcff54acbcd3d24.zip
Tool to display memory statistics
Change-Id: Iaac392b9f4287ba888e454532c4061d6a14c6e5c Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/593 Tested-by: Jenkins Server Reviewed-by: Douglas R. Gilbert <dgilbert@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/build/debug/Hostboot/MemStats.pm75
-rw-r--r--src/include/kernel/block.H2
-rw-r--r--src/include/kernel/heapmgr.H9
-rw-r--r--src/include/kernel/pagemgr.H1
-rw-r--r--src/kernel/block.C6
-rw-r--r--src/kernel/heapmgr.C55
-rw-r--r--src/kernel/pagemgr.C7
7 files changed, 124 insertions, 31 deletions
diff --git a/src/build/debug/Hostboot/MemStats.pm b/src/build/debug/Hostboot/MemStats.pm
new file mode 100644
index 000000000..415cceb01
--- /dev/null
+++ b/src/build/debug/Hostboot/MemStats.pm
@@ -0,0 +1,75 @@
+use strict;
+
+package Hostboot::MemStats;
+use Exporter;
+our @EXPORT_OK = ('main');
+
+sub main
+{
+ my @page_manager_addr =
+ ::findSymbolAddress("Singleton<PageManager>::instance()::instance");
+
+ my $free_pages =
+ ::read64 @page_manager_addr;
+
+ my $total_pages =
+ ::read64 ($page_manager_addr[0] + 8, 8);
+
+ my $free_min =
+ ::read64 ::findSymbolAddress("PageManager::cv_low_page_count");
+
+ my $page_coal =
+ ::read64 ::findSymbolAddress("PageManager::cv_coalesce_count");
+
+ my $big_heap_pages_used =
+ ::read32 ::findSymbolAddress("HeapManager::cv_largeheap_page_count");
+
+ my $big_heap_max =
+ ::read32 ::findSymbolAddress("HeapManager::cv_largeheap_page_max");
+
+ my $small_heap_pages_used =
+ ::read32 ::findSymbolAddress("HeapManager::cv_smallheap_page_count");
+
+ my $heap_coal =
+ ::read32 ::findSymbolAddress("HeapManager::cv_coalesce_count");
+
+ my $heap_free =
+ ::read32 ::findSymbolAddress("HeapManager::cv_free_bytes");
+
+ my $heap_free_chunks =
+ ::read32 ::findSymbolAddress("HeapManager::cv_free_chunks");
+
+ my $heap_total = $big_heap_pages_used + $small_heap_pages_used;
+ my $heap_max = $big_heap_max + $small_heap_pages_used;
+
+
+ my $castout_ro =
+ ::read32 ::findSymbolAddress("Block::cv_ro_evict_req");
+
+ my $castout_rw =
+ ::read32 ::findSymbolAddress("Block::cv_rw_evict_req");
+
+
+ ::userDisplay "===================================================\n";
+ ::userDisplay "MemStats:\n";
+ ::userDisplay " Total pages available: $total_pages\n";
+ ::userDisplay " Free pages: $free_pages\n";
+ ::userDisplay " Free pages Low mark: $free_min\n";
+ ::userDisplay " Page chunks coalesced: $page_coal\n";
+ ::userDisplay "\nHeap:\n";
+ ::userDisplay " Pages used by heap: $heap_total\n";
+ ::userDisplay " Max. Pages used by heap: $heap_max\n";
+ ::userDisplay " heap free bytes/chunks $heap_free/$heap_free_chunks (valid only after a coalescing)\n";
+ ::userDisplay " Heap chunks coalesced: $heap_coal\n";
+ ::userDisplay "\nVirtual Memory Manager page eviction requests:\n";
+ ::userDisplay " RO page requests: $castout_ro\n";
+ ::userDisplay " RW page requests: $castout_rw\n";
+ ::userDisplay "===================================================\n";
+
+}
+
+sub help
+{
+ ::userDisplay "Tool: MemStats\n";
+ ::userDisplay "\tDisplays Hostboot memory usage information\n";
+}
diff --git a/src/include/kernel/block.H b/src/include/kernel/block.H
index df48c6b27..48e27b803 100644
--- a/src/include/kernel/block.H
+++ b/src/include/kernel/block.H
@@ -295,6 +295,8 @@ class Block
/** Pointer to message handler(write) */
BlockWriteMsgHdlr* iv_writeMsgHdlr;
+ static uint32_t cv_ro_evict_req; //!< memstat ro eviction requests
+ static uint32_t cv_rw_evict_req; //!< memstat rw eviction requests
/**
* @brief Finish initialization of block.
*
diff --git a/src/include/kernel/heapmgr.H b/src/include/kernel/heapmgr.H
index a2509e060..56652ea66 100644
--- a/src/include/kernel/heapmgr.H
+++ b/src/include/kernel/heapmgr.H
@@ -211,8 +211,11 @@ class HeapManager
Util::Lockfree::Stack<big_chunk_t> big_chunk_stack; //!< big chunk dir
static const size_t cv_chunk_size[BUCKETS];//!< The bucket sizes
- static size_t cv_coalesce_count; //!< coalesced chunk count
- static size_t cv_free_bytes; //!< Only valid after coalesce()
- static size_t cv_free_chunks; //!< Only valid after coalesce()
+ static uint32_t cv_coalesce_count; //!< coalesced chunk count
+ static uint32_t cv_free_bytes; //!< Only valid after coalesce()
+ static uint32_t cv_free_chunks; //!< Only valid after coalesce()
+ static uint32_t cv_smallheap_page_count; //!< # of pages being used
+ static uint32_t cv_largeheap_page_count; //!< # of pages being used
+ static uint32_t cv_largeheap_page_max; //!< Max # of pages used
};
#endif
diff --git a/src/include/kernel/pagemgr.H b/src/include/kernel/pagemgr.H
index 41fb1e493..aec4470d2 100644
--- a/src/include/kernel/pagemgr.H
+++ b/src/include/kernel/pagemgr.H
@@ -104,6 +104,7 @@ class PageManager
uint64_t iv_pagesTotal;
static size_t cv_coalesce_count; //!< running coalesced counter
+ static size_t cv_low_page_count; //!< lowest page count
struct page_t
{
diff --git a/src/kernel/block.C b/src/kernel/block.C
index 8f94b45d3..221d536e1 100644
--- a/src/kernel/block.C
+++ b/src/kernel/block.C
@@ -39,6 +39,10 @@
#include <util/align.H>
#include <kernel/basesegment.H>
+// Track eviction requests due to aging pages
+uint32_t Block::cv_ro_evict_req = 0;
+uint32_t Block::cv_rw_evict_req = 0;
+
Block::~Block()
{
// Release shadow PTE array.
@@ -356,6 +360,7 @@ void Block::castOutPages(uint64_t i_type)
this->removePages(VmmManager::EVICT,l_vaddr,
PAGESIZE,NULL);
//printk("+");
+ ++cv_rw_evict_req;
}
}
else // ro and/or executable
@@ -366,6 +371,7 @@ void Block::castOutPages(uint64_t i_type)
l_vaddr = reinterpret_cast<void*>(page);
this->removePages(VmmManager::EVICT,l_vaddr,
PAGESIZE,NULL);
+ ++cv_ro_evict_req;
}
}
}
diff --git a/src/kernel/heapmgr.C b/src/kernel/heapmgr.C
index aa69d52ad..309b8ea99 100644
--- a/src/kernel/heapmgr.C
+++ b/src/kernel/heapmgr.C
@@ -39,11 +39,8 @@ void * g_smallHeapPages[SMALL_HEAP_PAGES_TRACKED];
uint16_t g_bucket_counts[HeapManager::BUCKETS];
uint32_t g_smallheap_allocated = 0; // sum of currently allocated
uint32_t g_smallheap_alloc_hw = 0; // allocated high water
-uint32_t g_smallheap_pages = 0; // total bytes high water (pages used)
uint32_t g_smallheap_count = 0; // # of chunks allocated
-uint32_t g_big_chunks = 0;
-uint32_t g_bigheap_highwater = 0;
#endif
const size_t HeapManager::cv_chunk_size[BUCKETS] =
@@ -62,9 +59,12 @@ const size_t HeapManager::cv_chunk_size[BUCKETS] =
HeapManager::BUCKET_SIZE11
};
-size_t HeapManager::cv_coalesce_count = 0;
-size_t HeapManager::cv_free_bytes;
-size_t HeapManager::cv_free_chunks;
+uint32_t HeapManager::cv_coalesce_count = 0;
+uint32_t HeapManager::cv_free_bytes;
+uint32_t HeapManager::cv_free_chunks;
+uint32_t HeapManager::cv_smallheap_page_count = 0;
+uint32_t HeapManager::cv_largeheap_page_count = 0;
+uint32_t HeapManager::cv_largeheap_page_max = 0;
void HeapManager::init()
@@ -161,11 +161,10 @@ void* HeapManager::_reallocBig(void* i_ptr, size_t i_sz)
size_t new_size = ALIGN_PAGE(i_sz)/PAGESIZE;
if(new_size > bc->page_count)
{
-#ifdef HOSTBOOT_DEBUG
- __sync_add_and_fetch(&g_big_chunks,new_size-bc->page_count);
- if(g_bigheap_highwater < g_big_chunks)
- g_bigheap_highwater = g_big_chunks;
-#endif
+ __sync_add_and_fetch(&cv_largeheap_page_count,new_size-bc->page_count);
+ if(cv_largeheap_page_max < cv_largeheap_page_count)
+ cv_largeheap_page_max = cv_largeheap_page_count;
+
new_ptr = PageManager::allocatePage(new_size);
memcpy(new_ptr,i_ptr,bc->page_count*PAGESIZE);
@@ -251,7 +250,10 @@ void HeapManager::newPage()
size_t remaining = PAGESIZE;
#ifdef HOSTBOOT_DEBUG
- uint32_t idx = __sync_fetch_and_add(&g_smallheap_pages,1);
+ uint32_t idx =
+#endif
+ __sync_fetch_and_add(&cv_smallheap_page_count,1);
+#ifdef HOSTBOOT_DEBUG
if(idx < SMALL_HEAP_PAGES_TRACKED)
g_smallHeapPages[idx] = page;
#endif
@@ -394,7 +396,7 @@ void HeapManager::_coalesce()
cv_free_bytes += bucketByteSize(c->bucket) - 8;
c = c_next;
}
- printkd("HeapMgr coalesced total %ld\n",cv_coalesce_count);
+ printkd("HeapMgr coalesced total %d\n",cv_coalesce_count);
test_pages(); /*no effect*/ // BEAM fix.
}
@@ -403,14 +405,14 @@ void HeapManager::stats()
coalesce(); // collects some of the stats
printkd("Memory Heap Stats:\n");
- printkd(" %d Large heap pages allocated.\n",g_big_chunks);
- printkd(" %d Large heap max allocated.\n",g_bigheap_highwater);
- printkd(" %d Small heap pages.\n",g_smallheap_pages);
+ printkd(" %d Large heap pages allocated.\n",cv_largeheap_page_count);
+ printkd(" %d Large heap max allocated.\n",cv_largeheap_page_max);
+ printkd(" %d Small heap pages.\n",cv_smallheap_page_count);
printkd(" %d Small heap bytes max allocated\n",g_smallheap_alloc_hw);
printkd(" %d Small heap bytes allocated in %d chunks\n",
g_smallheap_allocated,g_smallheap_count);
- printkd(" %ld Small heap free bytes in %ld chunks\n",cv_free_bytes,cv_free_chunks);
- printkd(" %ld Small heap total chunks coalesced\n",cv_coalesce_count);
+ printkd(" %d Small heap free bytes in %d chunks\n",cv_free_bytes,cv_free_chunks);
+ printkd(" %d Small heap total chunks coalesced\n",cv_coalesce_count);
printkd("Small heap bucket profile:\n");
for(size_t i = 0; i < BUCKETS; ++i)
{
@@ -429,7 +431,7 @@ void HeapManager::test_pages()
for(size_t i = 0; i < BUCKETS; ++i)
g_bucket_counts[i] = 0;
- size_t max_idx = g_smallheap_pages;
+ size_t max_idx = cv_smallheap_page_count;
if(max_idx > SMALL_HEAP_PAGES_TRACKED) max_idx = SMALL_HEAP_PAGES_TRACKED;
for(size_t i = 0; i < max_idx; ++i)
{
@@ -468,12 +470,10 @@ void* HeapManager::_allocateBig(size_t i_sz)
{
size_t pages = ALIGN_PAGE(i_sz)/PAGESIZE;
void* v = PageManager::allocatePage(pages);
-#ifdef HOSTBOOT_DEBUG
- //printk("HEAPAB %p:%ld:%ld wasted %ld\n",v,pages,i_sz, pages*PAGESIZE - i_sz);
- __sync_add_and_fetch(&g_big_chunks,pages);
- if(g_bigheap_highwater < g_big_chunks)
- g_bigheap_highwater = g_big_chunks;
-#endif
+
+ __sync_add_and_fetch(&cv_largeheap_page_count,pages);
+ if(cv_largeheap_page_max < cv_largeheap_page_count)
+ cv_largeheap_page_max = cv_largeheap_page_count;
// If already have unused big_chunk_t object available then use it
// otherwise create a new one.
@@ -513,9 +513,8 @@ bool HeapManager::_freeBig(void* i_ptr)
{
if(bc->addr == i_ptr)
{
-#ifdef HOSTBOOT_DEBUG
- __sync_sub_and_fetch(&g_big_chunks,bc->page_count);
-#endif
+ __sync_sub_and_fetch(&cv_largeheap_page_count,bc->page_count);
+
size_t page_count = bc->page_count;
bc->page_count = 0;
bc->addr = NULL;
diff --git a/src/kernel/pagemgr.C b/src/kernel/pagemgr.C
index ca5dca055..6b36a1054 100644
--- a/src/kernel/pagemgr.C
+++ b/src/kernel/pagemgr.C
@@ -28,6 +28,7 @@
#include <util/locked/pqueue.H>
size_t PageManager::cv_coalesce_count = 0;
+size_t PageManager::cv_low_page_count = -1;
void PageManager::init()
{
@@ -67,6 +68,7 @@ PageManager::PageManager() : iv_pagesAvail(0), iv_pagesTotal(0)
iv_pagesTotal = length;
// Update statistics.
__sync_add_and_fetch(&iv_pagesAvail, length);
+ cv_low_page_count = iv_pagesAvail;
// Display.
printk("Initializing PageManager with %zd pages starting at %lx...",
@@ -122,6 +124,10 @@ void* PageManager::_allocatePage(size_t n)
// Update statistics.
__sync_sub_and_fetch(&iv_pagesAvail, n);
+ if(iv_pagesAvail < cv_low_page_count)
+ {
+ cv_low_page_count = iv_pagesAvail;
+ }
return page;
}
@@ -237,6 +243,7 @@ void PageManager::_coalesce( void )
}
}
printkd("PAGEMGR coalesced total %ld\n", cv_coalesce_count);
+ printkd("PAGEMGR low page count %ld\n",cv_low_page_count);
}
OpenPOWER on IntegriCloud