summaryrefslogtreecommitdiffstats
path: root/src/kernel/block.C
diff options
context:
space:
mode:
authorDoug Gilbert <dgilbert@us.ibm.com>2011-09-12 12:47:53 -0500
committerDouglas R. Gilbert <dgilbert@us.ibm.com>2011-09-19 16:05:34 -0500
commitde8a529d349aebb344979609055f123c196ccfe3 (patch)
treeb91665407f69730aaba8da794afc47240997dd47 /src/kernel/block.C
parentb754f8b47e343f449e5f05f67b948513363abd12 (diff)
downloadtalos-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.C99
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;
+}
OpenPOWER on IntegriCloud