summaryrefslogtreecommitdiffstats
path: root/src/include/kernel/pagemgr.H
diff options
context:
space:
mode:
authorDoug Gilbert <dgilbert@us.ibm.com>2012-06-27 17:59:25 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-07-11 08:18:00 -0500
commita23283c6facfee055c9c6d43e23a04ca02edc467 (patch)
tree51c7e8e5af9344041941a140be33950159b00972 /src/include/kernel/pagemgr.H
parent2a37ac4be40500b6849444168181931202892a96 (diff)
downloadtalos-hostboot-a23283c6facfee055c9c6d43e23a04ca02edc467.tar.gz
talos-hostboot-a23283c6facfee055c9c6d43e23a04ca02edc467.zip
Improve memory page manager for low memory situations
RTC: 40831 Change-Id: I7889f91eec44a10d56ffc94e03c7557f8085100a Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/1272 Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com> Tested-by: Jenkins Server Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/include/kernel/pagemgr.H')
-rw-r--r--src/include/kernel/pagemgr.H189
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
OpenPOWER on IntegriCloud