kernel/eka/memmodel/epoc/flexible/mmu/mptalloc.cpp
branchGCC_SURGE
changeset 221 39b39e1a406e
parent 201 43365a9b78a3
--- a/kernel/eka/memmodel/epoc/flexible/mmu/mptalloc.cpp	Wed Jul 21 14:46:58 2010 +0100
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mptalloc.cpp	Thu Jul 22 16:46:39 2010 +0100
@@ -54,10 +54,6 @@
 uses memory from #ThePager which will reclaim paged memory if necessary.
 Providing the live list always has #DPager::iMinYoungPages, this guarantees that
 handling page faults can never fail by running out of memory.
-
-TODO: In really pathological situations page table allocation can fail due to
-being out of virtual address space to map the table, this needs to be prevented
-from happening when handling demand paging faults.
 */
 
 
@@ -122,6 +118,8 @@
 
 	virtual TInt MovePage(	DMemoryObject* aMemory, SPageInfo* aOldPageInfo, 
 							TPhysAddr& aNewPage, TUint aBlockZoneId, TBool aBlockRest);
+
+	virtual TInt MoveAndAllocPage(DMemoryObject* aMemory, SPageInfo* aPageInfo, TZonePageType aType);
 public:
 	/**
 	Allocate a page of RAM for storing page tables in.
@@ -267,13 +265,22 @@
 	return r;
 	}
 
+
 TInt DPageTableMemoryManager::MovePage(	DMemoryObject* aMemory, SPageInfo* aOldPageInfo, 
 										TPhysAddr& aNewPage, TUint aBlockZoneId, TBool aBlockRest)
-		{
-		// This could be a demand paged page table info which can be discarded 
-		// but let the PageTableAllocator handle that.
-		return ::PageTables.MovePage(aMemory, aOldPageInfo, aBlockZoneId, aBlockRest);
-		}
+	{
+	// This could be a demand paged page table info which can be discarded 
+	// but let the PageTableAllocator handle that.
+	return ::PageTables.MovePage(aMemory, aOldPageInfo, aBlockZoneId, aBlockRest);
+	}
+
+
+TInt DPageTableMemoryManager::MoveAndAllocPage(DMemoryObject* aMemory, SPageInfo* aPageInfo, TZonePageType aPageType)
+	{
+	// This could be a demand paged page table info which can be discarded 
+	// but let the PageTableAllocator handle that.
+	return ::PageTables.MoveAndAllocPage(aMemory, aPageInfo, aPageType);
+	}
 
 
 //
@@ -1181,9 +1188,9 @@
 TInt PageTableAllocator::MovePage(DMemoryObject* aMemory, SPageInfo* aOldPageInfo, 
 									TUint aBlockZoneId, TBool aBlockRest)
 	{
+	__NK_ASSERT_DEBUG(MmuLock::IsHeld());
 	// We don't move page table or page table info pages, however, if this page 
 	// is demand paged then we may be able to discard it.
-	MmuLock::Lock();
 	if (aOldPageInfo->Owner() == iPageTableInfoMemory)
 		{
 		if (!(iPtPageAllocator.IsDemandPagedPtInfo(aOldPageInfo)))
@@ -1210,7 +1217,19 @@
 	// Let the pager discard the page as it controls the size of the live list.
 	// If the size of the live list allows then eventually 
 	// PageTableAllocator::StealPage() will be invoked on this page.
-	return ThePager.DiscardPage(aOldPageInfo, aBlockZoneId, aBlockRest);
+	TUint moveDisFlags = (aBlockRest)? M::EMoveDisBlockRest : 0;
+	return ThePager.DiscardPage(aOldPageInfo, aBlockZoneId, moveDisFlags);
+	}
+
+
+TInt PageTableAllocator::MoveAndAllocPage(DMemoryObject* aMemory, SPageInfo* aPageInfo, TZonePageType aPageType)
+	{
+	TInt r = MovePage(aMemory, aPageInfo, KRamZoneInvalidId, EFalse);
+	if (r == KErrNone)
+		{
+		TheMmu.MarkPageAllocated(aPageInfo->PhysAddr(), aPageType);
+		}
+	return r;
 	}