diff options
author | Doug Gilbert <dgilbert@us.ibm.com> | 2011-09-12 12:47:53 -0500 |
---|---|---|
committer | Douglas R. Gilbert <dgilbert@us.ibm.com> | 2011-09-19 16:05:34 -0500 |
commit | de8a529d349aebb344979609055f123c196ccfe3 (patch) | |
tree | b91665407f69730aaba8da794afc47240997dd47 /src/kernel/block.C | |
parent | b754f8b47e343f449e5f05f67b948513363abd12 (diff) | |
download | talos-hostboot-de8a529d349aebb344979609055f123c196ccfe3.tar.gz talos-hostboot-de8a529d349aebb344979609055f123c196ccfe3.zip |
Mechanism to detect low memory and cast out older page
Change-Id: Icce8e01f3d1cd2942f2b9ff802993da0441535ee
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/344
Tested-by: Jenkins Server
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Reviewed-by: Douglas R. Gilbert <dgilbert@us.ibm.com>
Diffstat (limited to 'src/kernel/block.C')
-rw-r--r-- | src/kernel/block.C | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/src/kernel/block.C b/src/kernel/block.C index 59a7892f2..63c1fae92 100644 --- a/src/kernel/block.C +++ b/src/kernel/block.C @@ -108,6 +108,15 @@ bool Block::handlePageFault(task_t* i_task, uint64_t i_addr) } else { + // Test code @TODO remove - SET up ro pages to test cast out pages + //if(pte->getPage() == 0) + //{ + // void* l_page = PageManager::allocatePage(); + // memset(l_page,'U',PAGESIZE); + // pte->setPageAddr(reinterpret_cast<uint64_t>(l_page)); + // pte->setPresent(true); + // pte->setWritable(false); + //} return false; //TODO - Swap kernel base block pages for user pages } } @@ -301,3 +310,93 @@ void Block::updateRefCount( uint64_t i_vaddr, spte->setDirty( i_stats.C ); } + +bool Block::evictPage(ShadowPTE* i_pte) +{ + ShadowPTE* pte = i_pte; + bool do_cast_out = false; + + if(!pte->isWritable()) // ro, executable + { + do_cast_out = true; + } + else // is writable... + { + // if pte->isWriteTracked() flush then cast out + } + + if(do_cast_out) + { + PageTableManager::delEntry(pte->getPageAddr()); + PageManager::freePage(reinterpret_cast<void*>(pte->getPageAddr())); + pte->setPresent(false); + pte->setPageAddr(NULL); + } + + return do_cast_out; +} + +size_t Block::castOutPages(uint64_t i_type) +{ + size_t cast_out = 0; + // drill down + if(iv_nextBlock) + { + cast_out += iv_nextBlock->castOutPages(i_type); + } + + // TODO We will eventually need to skip other blocks as well, such as + // when the memory space grows. + if(iv_baseAddr != 0) // Skip base area + { + bool is_cast_out = false; + size_t rw_constraint = 5; + size_t ro_constraint = 3; + + if(i_type == VmmManager::CRITICAL) + { + rw_constraint = 2; + ro_constraint = 1; + } + //printk("Block = %p:%ld\n",(void*)iv_baseAddr,iv_size / PAGESIZE); + for(uint64_t page = iv_baseAddr; + page < (iv_baseAddr + iv_size); + page += PAGESIZE) + { + ShadowPTE* pte = getPTE(page); + if (pte->isPresent() && (0 != pte->getPageAddr())) + { + //if(pte->isExecutable()) printk("x"); + //else if(pte->isWritable()) printk("w"); + //else printk("r"); + //printk("%d",(int)pte->getLRU()); + + if(pte->isWritable()) + { + if((pte->getLRU() > rw_constraint) && pte->isWriteTracked()) + { + is_cast_out = evictPage(pte); + //printk("+"); + } + } + else // ro and/or executable + { + if(pte->getLRU() > ro_constraint) + { + is_cast_out = evictPage(pte); + } + } + + if(is_cast_out) + { + //printk("-"); + ++cast_out; + is_cast_out = false; + } + } + } + //printk("\n"); + } + + return cast_out; +} |