diff options
author | Doug Gilbert <dgilbert@us.ibm.com> | 2011-12-13 14:46:48 -0600 |
---|---|---|
committer | Douglas R. Gilbert <dgilbert@us.ibm.com> | 2012-01-12 10:46:18 -0600 |
commit | 47f456fec103ec096edb5e0b9fcff54acbcd3d24 (patch) | |
tree | 478f16727ec00b72da727bdffa5d467d131b22be /src | |
parent | b93f3dc742c0fa8d16f130938b56feb48e5bd7d7 (diff) | |
download | talos-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.pm | 75 | ||||
-rw-r--r-- | src/include/kernel/block.H | 2 | ||||
-rw-r--r-- | src/include/kernel/heapmgr.H | 9 | ||||
-rw-r--r-- | src/include/kernel/pagemgr.H | 1 | ||||
-rw-r--r-- | src/kernel/block.C | 6 | ||||
-rw-r--r-- | src/kernel/heapmgr.C | 55 | ||||
-rw-r--r-- | src/kernel/pagemgr.C | 7 |
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); } |