diff options
| author | Matthew Barth <msbarth@us.ibm.com> | 2011-09-29 15:42:30 -0500 |
|---|---|---|
| committer | MATTHEW S. BARTH <msbarth@us.ibm.com> | 2011-10-10 15:51:19 -0500 |
| commit | 8c062af8b6bd50a59823c7ec430ec5fc019052d2 (patch) | |
| tree | dbe0625a3024a3737ddfa5d32634ce8225fda991 /src/include/kernel | |
| parent | 4de170997eee6244b2091bb8bf065ae2da1396d7 (diff) | |
| download | blackbird-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.H | 28 | ||||
| -rw-r--r-- | src/include/kernel/block.H | 63 | ||||
| -rw-r--r-- | src/include/kernel/blockmsghdlr.H | 104 | ||||
| -rw-r--r-- | src/include/kernel/vmmmgr.H | 36 |
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; |

