summaryrefslogtreecommitdiffstats
path: root/src/include/kernel
diff options
context:
space:
mode:
authorMatthew Barth <msbarth@us.ibm.com>2011-09-29 15:42:30 -0500
committerMATTHEW S. BARTH <msbarth@us.ibm.com>2011-10-10 15:51:19 -0500
commit8c062af8b6bd50a59823c7ec430ec5fc019052d2 (patch)
treedbe0625a3024a3737ddfa5d32634ce8225fda991 /src/include/kernel
parent4de170997eee6244b2091bb8bf065ae2da1396d7 (diff)
downloadblackbird-hostboot-8c062af8b6bd50a59823c7ec430ec5fc019052d2.tar.gz
blackbird-hostboot-8c062af8b6bd50a59823c7ec430ec5fc019052d2.zip
Flush/Release/Evict pages functionality
Change-Id: Ic0bb4122164e11f6d13e6850abf8ae9bd32caea2 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/393 Tested-by: Jenkins Server Reviewed-by: MATTHEW S. BARTH <msbarth@us.ibm.com>
Diffstat (limited to 'src/include/kernel')
-rw-r--r--src/include/kernel/basesegment.H28
-rw-r--r--src/include/kernel/block.H63
-rw-r--r--src/include/kernel/blockmsghdlr.H104
-rw-r--r--src/include/kernel/vmmmgr.H36
4 files changed, 198 insertions, 33 deletions
diff --git a/src/include/kernel/basesegment.H b/src/include/kernel/basesegment.H
index 1064e1f82..51e99b0bf 100644
--- a/src/include/kernel/basesegment.H
+++ b/src/include/kernel/basesegment.H
@@ -68,7 +68,7 @@ class BaseSegment : public Segment
/**
* @brief Implementation of the pure-virtual function from Segment.
- * Update LRU statistics on the block that owns the address *
+ * Update LRU statistics on the block that owns the address
*
* @param[in] i_vaddr - Virtual Address of page
* @param[in] i_stats - Usage statistics
@@ -79,7 +79,8 @@ class BaseSegment : public Segment
/**
* @brief Allocates a block of virtual memory of the given size
* @param i_mq[in] - Message queue to be associated with the block
- * @param i_va[in] - Base virtual address of the block to be allocated
+ * @param i_va[in] - Page aligned base virtual address of the block
+ * to be allocated
* @param i_size[in] - Requested virtual memory size of the block
* @return int - 0 for successful block allocation, non-zero otherwise
*/
@@ -92,7 +93,18 @@ class BaseSegment : public Segment
* @return the physical address bound to the virtual address, or
* -EFAULT if i_vaddr not found. @see errno.h
*/
- virtual uint64_t findPhysicalAddress(uint64_t i_vaddr) const;
+ virtual uint64_t findPhysicalAddress(uint64_t i_vaddr) const;
+
+ /**
+ * @brief Remove pages by a specified operation of the given size
+ * @param[in] i_op - Page removal operation to perform
+ * @param[in] i_vaddr - Virtual address associated to page(s)
+ * @param[in] i_size - Size of memory to perform page removal on
+ * @param[in] i_task - Task requesting page removal.
+ * @return int - 0 for successful page removal, non-zero otherwise
+ */
+ static int mmRemovePages(VmmManager::PAGE_REMOVAL_OPS i_op,
+ void* i_vaddr, uint64_t i_size, task_t* i_task);
/**
* @brief Sets the page permissions for a given virtual address and size.
@@ -146,6 +158,16 @@ class BaseSegment : public Segment
uint64_t i_size,
uint64_t i_access_type);
+ /**
+ * @brief Remove pages by a specified operation of the given size
+ * @param[in] i_op - Page removal operation to perform
+ * @param[in] i_vaddr - Virtual address associated to page(s)
+ * @param[in] i_size - Size of memory to perform page removal on
+ * @param[in] i_task - Task requesting page removal.
+ * @return int - 0 for successful page removal, non-zero otherwise
+ */
+ int _mmRemovePages(VmmManager::PAGE_REMOVAL_OPS i_op, void* i_vaddr,
+ uint64_t i_size, task_t* i_task);
};
diff --git a/src/include/kernel/block.H b/src/include/kernel/block.H
index 405791e94..01187617f 100644
--- a/src/include/kernel/block.H
+++ b/src/include/kernel/block.H
@@ -72,7 +72,7 @@ class Block
MessageQueue* i_msgQueue = NULL) :
iv_baseAddr(i_baseAddr), iv_size(i_size),
iv_parent(NULL), iv_nextBlock(NULL), iv_ptes(NULL),
- iv_msgHdlr(NULL)
+ iv_readMsgHdlr(NULL), iv_writeMsgHdlr(NULL)
{ init(i_msgQueue); };
/**
@@ -117,23 +117,6 @@ class Block
bool handlePageFault(task_t* i_task, uint64_t i_addr);
/**
- * @brief Sets the 'present' bit within the Shadow page table
- *
- * @param[in] i_vaddr - Virtual address within the Shadow page table
- */
- void setIsPresent(void* i_vaddr);
-
- /**
- * @brief Adds the page table entry for the given address
- *
- * @param[in] i_vaddr - Virtual address to add to the page table
- *
- * The permissions set within the Shadow page table are used for
- * this address
- */
- void addPTE(void* i_vaddr);
-
- /**
* @brief Locate the physical address of the given virtual address
*
* @param[in] i_vaddr virtual address
@@ -171,9 +154,22 @@ class Block
*/
bool evictPage(ShadowPTE* i_pte);
+ /**
+ * @brief Removes a range of pages within a block of virtual memory
+ * @param[in] i_op - Page removal operation to perform
+ * @param[in] i_vaddr - Virtual address associated to page(s)
+ * @param[in] i_size - Size of memory to perform page removal on
+ * @param[in] i_task - Task requesting page removal.
+ * @return int - 0 for successful page removal, non-zero otherwise
+ */
+ int removePages(VmmManager::PAGE_REMOVAL_OPS i_op, void* i_vaddr,
+ uint64_t i_size, task_t* i_task);
+
friend class Segment;
friend class BaseSegment;
friend class StackSegment;
+ friend class BlockReadMsgHdlr;
+ friend class BlockWriteMsgHdlr;
protected:
/**
@@ -248,6 +244,30 @@ class Block
*/
int mmSetPermission(uint64_t i_va, uint64_t i_size, uint64_t i_access_type);
+ /**
+ * @brief Adds the page table entry for the given address
+ *
+ * @param[in] i_vaddr - Virtual address to add to the page table
+ *
+ * The permissions set within the Shadow page table are used for
+ * this address
+ */
+ void addPTE(void* i_vaddr);
+
+ /**
+ * @brief Sets the 'present' bit within the Shadow page table
+ *
+ * @param[in] i_vaddr - Virtual address within the Shadow page table
+ */
+ void setIsPresent(void* i_vaddr);
+
+ /**
+ * @brief Effectively removes the given page table entry from the
+ * shadow page table
+ * @param[in] i_pte - Shadow page table entry to release
+ */
+ void releasePTE(ShadowPTE* i_pte);
+
private:
/** Base address of the block */
const uint64_t iv_baseAddr;
@@ -261,8 +281,10 @@ class Block
/** Pointer to the Shadow PTE entries. */
ShadowPTE* iv_ptes;
- /** Pointer to the message handler */
- BlockMsgHdlr* iv_msgHdlr;
+ /** Pointer to message handler(read) */
+ BlockReadMsgHdlr* iv_readMsgHdlr;
+ /** Pointer to message handler(write) */
+ BlockWriteMsgHdlr* iv_writeMsgHdlr;
/**
* @brief Finish initialization of block.
@@ -286,7 +308,6 @@ class Block
*/
ShadowPTE* getPTE(uint64_t i_addr) const;
-
Block(const Block&); // prohibit copy.
Block& operator=(const Block&); // prohibit assignment.
diff --git a/src/include/kernel/blockmsghdlr.H b/src/include/kernel/blockmsghdlr.H
index 35348a92f..495ab71c3 100644
--- a/src/include/kernel/blockmsghdlr.H
+++ b/src/include/kernel/blockmsghdlr.H
@@ -29,21 +29,44 @@
#include <stdint.h>
#include <kernel/types.h>
#include <kernel/msghandler.H>
+#include <util/locked/list.H>
//Forward declaration.
class Spinlock;
class MessageQueue;
class Block;
+struct TaskMsgNode
+{
+ //Next pointer for list.
+ TaskMsgNode* next;
+ //Previous pointer for list.
+ TaskMsgNode* prev;
+
+ task_t* key;
+ uint64_t msgCount;
+};
+
+struct PageAddrNode
+{
+ //Next pointer for list.
+ PageAddrNode* next;
+ //Previous pointer for list.
+ PageAddrNode* prev;
+
+ void* key;
+ uint64_t pageAddr;
+};
+
/**
- * @class BlockMsgHdlr
- * @brief Class to handle message data for blocks
+ * @class BlockReadMsgHdlr
+ * @brief Class to handle read messages for blocks
*
* This class extends from the base MessageHandler so the base send/receive
* message functions can be utilized. It overrides how to handle the message
* responses for blocks within the base virtual memory segment.
*/
-class BlockMsgHdlr : public MessageHandler
+class BlockReadMsgHdlr : public MessageHandler
{
public:
@@ -56,13 +79,14 @@ class BlockMsgHdlr : public MessageHandler
* passed directly onto the MessageHandler
* @param[in] i_block - Block to associate this message handler to
*/
- BlockMsgHdlr(Spinlock* i_lock, MessageQueue* i_msgq, Block* i_block) :
- MessageHandler(i_lock,i_msgq), iv_block(i_block) {};
+ BlockReadMsgHdlr(Spinlock* i_lock,MessageQueue* i_msgq,
+ Block* i_block) :
+ MessageHandler(i_lock,i_msgq), iv_block(i_block) {};
/**
* @brief Destructor
*/
- ~BlockMsgHdlr() {};
+ ~BlockReadMsgHdlr() {};
/**
* @brief Handle response to 'send message' associated with this block
@@ -84,4 +108,72 @@ class BlockMsgHdlr : public MessageHandler
Block* const iv_block;
};
+/**
+ * @class BlockWriteMsgHdlr
+ * @brief Class to handle write messages for blocks
+ *
+ * This class extends from the base MessageHandler so the base send/receive
+ * message functions can be utilized. It overrides how to handle the message
+ * responses for blocks within the base virtual memory segment.
+ */
+class BlockWriteMsgHdlr : public MessageHandler
+{
+ public:
+
+ /**
+ * @brief Constructor
+ *
+ * @param[in] i_lock - Subsystem lock for this message handler, passed
+ * directly onto the MessageHandler
+ * @param[in] i_msgq - Queue used to send messages into userspace,
+ * passed directly onto the MessageHandler
+ * @param[in] i_block - Block to associate this message handler to
+ */
+ BlockWriteMsgHdlr(Spinlock* i_lock,MessageQueue* i_msgq,
+ Block* i_block) :
+ MessageHandler(i_lock,i_msgq), iv_block(i_block) {};
+
+ /**
+ * @brief Destructor
+ */
+ ~BlockWriteMsgHdlr() {};
+
+ /**
+ * @brief Handle response to 'send message' associated with this block
+ *
+ * @param[in] i_type - The message type previously sent.
+ * @param[in] i_key - The key value for the received message.
+ * @param[in] i_task - The deferred task.
+ * @param[in] i_rc - The response rc from userspace.
+ *
+ * @return HandleResult - The desired behavior on the 'recv message'
+ * interface for this <key, task> pair.
+ */
+ virtual HandleResult handleResponse(msg_sys_types_t i_type,void* i_key,
+ task_t* i_task,int i_rc);
+
+ /**
+ * @brief Increments the number of messages sent from the given task
+ * @param[in] i_task - Associated task to message sent
+ */
+ void incMsgCount(task_t* i_task);
+
+ /**
+ * @brief Adds the virtual address to page address association for
+ * page removal upon response
+ * @param[in] i_vaddr - Virtual address sent on message
+ * @param[in] i_pgAddr - Page address to be removed
+ */
+ void addVirtAddr(void* i_vaddr,uint64_t i_pgAddr);
+
+ private:
+
+ /* Associated block for this message handler */
+ Block* const iv_block;
+ /* List of associated tasks to number of messages */
+ Util::Locked::List<TaskMsgNode, task_t*> iv_msgGrpList;
+ /* List of associated virtual address to page address */
+ Util::Locked::List<PageAddrNode, void*> iv_va2paList;
+};
+
#endif
diff --git a/src/include/kernel/vmmmgr.H b/src/include/kernel/vmmmgr.H
index ce7aedafb..864eed0fd 100644
--- a/src/include/kernel/vmmmgr.H
+++ b/src/include/kernel/vmmmgr.H
@@ -61,6 +61,23 @@ class VmmManager
CRITICAL,
};
+ /**
+ * Kernel mapped page removal operations
+ *
+ * RELEASE : Writes dirty&write-tracked pages out to a storage device
+ * and removes other pages
+ * FLUSH : Only writes dirty&write-tracked pages out to a storage
+ * device
+ * EVICT : (Kernel) Writes dirty&write-tracked pages out to a storage
+ * device and removes other pages
+ */
+ enum PAGE_REMOVAL_OPS
+ {
+ RELEASE = 0,
+ FLUSH = 1,
+ EVICT = 2,
+ };
+
static void init();
static void init_slb();
@@ -98,7 +115,8 @@ class VmmManager
/**
* @brief Allocates a block of virtual memory of the given size
* @param i_mq[in] - Message queue to be associated with the block
- * @param i_va[in] - Base virtual address of the block to be allocated
+ * @param i_va[in] - Page aligned base virtual address of the block
+ * to be allocated
* @param i_size[in] - Requested virtual memory size of the block
* @return int - 0 for successful block allocation, non-zero otherwise
*/
@@ -127,14 +145,19 @@ class VmmManager
* @param[in] i_op - Page removal operation to perform
* @param[in] i_vaddr - Virtual address associated to page(s)
* @param[in] i_size - Size of memory to perform page removal on
+ * @param[in] i_task - OPTIONAL:Task requesting page removal.
* @return int - 0 for successful page removal, non-zero otherwise
*
* The given virtual address will be 'rounded' down to the nearest page
* boundary, along with the given size will be 'rounded' up to the
* nearest divisible page size.
+ *
+ * When a task is given, it will be deferred until all pages requested
+ * for removal have completed.
*/
- static int mmRemovePages(PAGE_REMOVAL_OPS i_op, void* i_vaddr,
- uint64_t i_size);
+ static int mmRemovePages(VmmManager::PAGE_REMOVAL_OPS i_op,
+ void* i_vaddr, uint64_t i_size,
+ task_t* i_task = NULL);
/**
* @brief Sets the permissions for a given page or range of pages
* @param i_va[in] - Virtual address of the page to update permission
@@ -180,6 +203,13 @@ class VmmManager
/** See flushPageTable */
void _flushPageTable( void );
+ /** See mmAllocBlock */
+ int _mmAllocBlock(MessageQueue* i_mq,void* i_va,uint64_t i_size);
+
+ /** See mmRemovePages */
+ int _mmRemovePages(VmmManager::PAGE_REMOVAL_OPS i_op,void* i_vaddr,
+ uint64_t i_size,task_t* i_task);
+
public:
friend class Block;
OpenPOWER on IntegriCloud