diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/include/kernel/pagemgr.H | 11 | ||||
-rw-r--r-- | src/kernel/pagemgr.C | 21 |
2 files changed, 23 insertions, 9 deletions
diff --git a/src/include/kernel/pagemgr.H b/src/include/kernel/pagemgr.H index dcd14c456..95bb2fb65 100644 --- a/src/include/kernel/pagemgr.H +++ b/src/include/kernel/pagemgr.H @@ -5,7 +5,9 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* COPYRIGHT International Business Machines Corp. 2010,2014 */ +/* Contributors Listed Below - COPYRIGHT 2010,2015 */ +/* [+] International Business Machines Corp. */ +/* */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); */ /* you may not use this file except in compliance with the License. */ @@ -81,8 +83,13 @@ class PageManagerCore * Return page allocations to the page manager * @param[in] i_page, pointer to the allocation * @param[in] i_pageCount, the number of pages in the allocation + * @param[in] i_overAllocated, whether pages to free are the being + * returned because the intial allocation was larger than needed */ - void freePage( void * i_page, size_t i_pageCount ); + void freePage( + void* i_page, + size_t i_pageCount, + bool i_overAllocated = false ); /** * Coalesce pages in the page manager (defrag) diff --git a/src/kernel/pagemgr.C b/src/kernel/pagemgr.C index c6a65dd92..c5e7d6960 100644 --- a/src/kernel/pagemgr.C +++ b/src/kernel/pagemgr.C @@ -98,7 +98,7 @@ PageManagerCore::page_t * PageManagerCore::allocatePage( size_t i_pageCount ) freePage(reinterpret_cast<void*>( reinterpret_cast<uintptr_t>(page) + (i_pageCount*PAGESIZE)), - bucket_size - i_pageCount); + bucket_size - i_pageCount,true); } } @@ -107,7 +107,10 @@ PageManagerCore::page_t * PageManagerCore::allocatePage( size_t i_pageCount ) -void PageManagerCore::freePage( void * i_page, size_t i_pageCount ) +void PageManagerCore::freePage( + void* i_page, + size_t i_pageCount, + bool i_overAllocated) { if ((NULL == i_page) || (0 == i_pageCount)) return; @@ -115,7 +118,10 @@ void PageManagerCore::freePage( void * i_page, size_t i_pageCount ) __builtin_clzl(i_pageCount)); size_t bucket_size = ((size_t)1) << which_bucket; - push_bucket((page_t*)i_page, which_bucket); + push_bucket( + (page_t*)(reinterpret_cast<uintptr_t>(i_page) + + (i_overAllocated ? ((i_pageCount-bucket_size)*PAGESIZE) : 0)), + which_bucket); // Update statistics. __sync_add_and_fetch(&iv_available, bucket_size); @@ -124,10 +130,11 @@ void PageManagerCore::freePage( void * i_page, size_t i_pageCount ) // spare pages to free. ie. the non-2^k portion of i_pageCount. if (bucket_size != i_pageCount) { - freePage(reinterpret_cast<void*>( - reinterpret_cast<uintptr_t>(i_page) + - (bucket_size*PAGESIZE)), - i_pageCount - bucket_size); + freePage( + reinterpret_cast<void*>( + reinterpret_cast<uintptr_t>(i_page) + + (i_overAllocated ? 0 : (bucket_size*PAGESIZE))), + i_pageCount - bucket_size, i_overAllocated); } return; |