diff options
Diffstat (limited to 'src/include/kernel/pagemgr.H')
-rw-r--r-- | src/include/kernel/pagemgr.H | 189 |
1 files changed, 145 insertions, 44 deletions
diff --git a/src/include/kernel/pagemgr.H b/src/include/kernel/pagemgr.H index e0d2aa1fa..6676a469c 100644 --- a/src/include/kernel/pagemgr.H +++ b/src/include/kernel/pagemgr.H @@ -1,25 +1,26 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/include/kernel/pagemgr.H $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2010 - 2011 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/include/kernel/pagemgr.H $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2010-2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ #ifndef __KERNEL_PAGEMGR_H #define __KERNEL_PAGEMGR_H @@ -32,17 +33,118 @@ #include <util/align.H> #include <sys/vfs.h> +/** @class PageManagerCore + * @brief Manages the allocation of memory pages + */ +class PageManagerCore +{ + public: + enum + { + BUCKETS = 16, + }; + + struct page_t + { + page_t* next; //!< Next block of pages + page_t* prev; //!< Prev block of pages + page_t* key; //!< Key for pqueue + }; + + /** + * Default Constructor + */ + PageManagerCore() + : iv_available(0) {} + + /** + * Add memory to the page manager + * @param[in] i_addr, The start address of the memory to add + * @param[in] i_pageCount, The number of pages to add + * @note i_addr must be on a page boundary + */ + void addMemory( size_t i_addr, size_t i_pageCount ); + + /** + * Destructor + */ + ~PageManagerCore( void ) {} + + /** + * Request page allocations + * @param[in] i_pageCount, The number of pages requested + * @return a pointer to the requested allocation | NULL + * if the request could not be satisfied. + */ + page_t * allocatePage( size_t i_pageCount ); + + /** + * 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 + */ + void freePage( void * i_page, size_t i_pageCount ); + + /** + * Coalesce pages in the page manager (defrag) + */ + void coalesce( void ); + + /** + * Query the the current number of pages in the page manager + */ + ALWAYS_INLINE + size_t getFreePageCount() const { return iv_available; } + + /** + * Get the start of memory after the code + */ + ALWAYS_INLINE uint64_t firstPageAddr( void ) const + { + return ALIGN_PAGE(VFS_LAST_ADDRESS); + } + + private: + + size_t iv_available; //!< free pages + Util::Lockfree::Stack<page_t> iv_heap[BUCKETS]; //!< The heap + + /** + * Find a page of proper size + * @param[in] the Size + * @return a page ptr to a page of size pages + */ + page_t* pop_bucket(size_t); + + /** + * Add a pages to the page manager + * @param[in] ptr to the allocation + * @param[in] The number of pages + */ + void push_bucket(page_t*, size_t); +}; + /** @class PageManager * @brief Manages the allocation of memory pages. */ - class PageManager { public: static void init(); + /** + * Allocate pages + * @param[in] n, Requested allocation in pages + * @return pointer to requested memory + */ static void* allocatePage(size_t n = 1); + + /** + * Return pages to the pagemanager + * @param[in] ptr to storage to release + * @param[in] n, size in pages + */ static void freePage(void*, size_t n = 1); /** @@ -67,9 +169,12 @@ class PageManager enum { MEMLEN = VmmManager::MBOX_DMA_ADDR, - BUCKETS = 16, + RESERVED_PAGES = 4, }; + static size_t cv_coalesce_count; //!< running coalesced counter + static size_t cv_low_page_count; //!< lowest page count + protected: PageManager(); @@ -77,19 +182,25 @@ class PageManager private: - void* _allocatePage(size_t); - void _freePage(void*, size_t); + void* _allocatePage(size_t); //!< see allocatePage() + void _freePage(void*, size_t); //!< see freePage() void _coalesce( void ); //!< see coalesce() + /** + * Query if in kernel mode + * @return [true | false] + */ + bool queryKernelMode() const; + /** see queryAvail() */ ALWAYS_INLINE uint64_t _queryAvail() const { return (100*iv_pagesAvail)/iv_pagesTotal; } - ALWAYS_INLINE uint64_t firstPageAddr( void ) + ALWAYS_INLINE uint64_t firstPageAddr( void ) const { - return ALIGN_PAGE(VFS_LAST_ADDRESS); + return iv_heap.firstPageAddr(); } /** see availPages() */ @@ -98,24 +209,14 @@ class PageManager return iv_pagesAvail; } - /** Statistics on number of free pages (for debug) */ - uint64_t iv_pagesAvail; - /** Total number of pages */ - uint64_t iv_pagesTotal; - - static size_t cv_coalesce_count; //!< running coalesced counter - static size_t cv_low_page_count; //!< lowest page count + // Private data - struct page_t - { - page_t* next; //!< Next block of pages - page_t* prev; //!< Prev block of pages - page_t* key; //!< Key for pqueue - }; - Util::Lockfree::Stack<page_t> first_page[BUCKETS]; + uint64_t iv_pagesAvail; //!< free pages (for debug) + uint64_t iv_pagesTotal; //!< Total number o fpages + uint64_t iv_lock; //!< lock for checking low heap - page_t* pop_bucket(size_t); - void push_bucket(page_t*, size_t); + PageManagerCore iv_heap; //!< Main heap + PageManagerCore iv_heapKernel; //!< kernel heap for out-of-mem }; #endif |