kernel/eka/memmodel/epoc/flexible/mmu/mmu.cpp
branchRCL_3
changeset 24 41f0cfe18c80
parent 22 2f92ad2dc5db
child 26 c734af59ce98
equal deleted inserted replaced
23:1df514389a47 24:41f0cfe18c80
   888 		TPhysAddr pagePhys = *pages++;
   888 		TPhysAddr pagePhys = *pages++;
   889 		__NK_ASSERT_DEBUG(pagePhys!=KPhysAddrInvalid);
   889 		__NK_ASSERT_DEBUG(pagePhys!=KPhysAddrInvalid);
   890 		SPageInfo* pi = SPageInfo::FromPhysAddr(pagePhys);
   890 		SPageInfo* pi = SPageInfo::FromPhysAddr(pagePhys);
   891 		PageFreed(pi);
   891 		PageFreed(pi);
   892 
   892 
   893 		// If this is an old page of a page being moved that was previously pinned
   893 		switch (ThePager.PageFreed(pi))
   894 		// then make sure it is freed as discardable otherwise despite DPager::DonatePages()
   894 			{
   895 		// having marked it as discardable it would be freed as movable.
   895 			case KErrNone: 
   896 		__NK_ASSERT_DEBUG(pi->PagedState() != SPageInfo::EPagedPinnedMoved || aCount == 1);
   896 				--aCount; // pager has dealt with this page, so one less for us
   897 		if (pi->PagedState() == SPageInfo::EPagedPinnedMoved)
   897 				break;
   898 			aZonePageType = EPageDiscard;
   898 			case KErrCompletion:
   899 
   899 				// This was a pager controlled page but it is no longer required.
   900 		if(ThePager.PageFreed(pi)==KErrNone)
   900 				__NK_ASSERT_DEBUG(aZonePageType == EPageMovable || aZonePageType == EPageDiscard);
   901 			--aCount; // pager has dealt with this page, so one less for us
   901 				__NK_ASSERT_DEBUG(pi->PagedState() == SPageInfo::EUnpaged);
   902 		else
   902 				if (aZonePageType == EPageMovable)
   903 			{
   903 					{// This page was donated to the pager so have to free it here
   904 			// All paged pages should have been dealt with by the pager above.
   904 					// as aZonePageType is incorrect for this page but aPages may 
   905 			__NK_ASSERT_DEBUG(pi->PagedState() == SPageInfo::EUnpaged);
   905 					// contain a mixture of movable and discardable pages.
   906 			*pagesOut++ = pagePhys; // store page address for freeing later
   906 					MmuLock::Unlock();
       
   907 					iRamPageAllocator->FreeRamPages(&pagePhys, 1, EPageDiscard);
       
   908 					aCount--; // We've freed this page here so one less to free later
       
   909 					flash = 0;	// reset flash count as we released the mmulock.
       
   910 					MmuLock::Lock();
       
   911 					break;
       
   912 					}
       
   913 				// fall through..
       
   914 			default:
       
   915 				// Free this page..
       
   916 				__NK_ASSERT_DEBUG(pi->PagedState() == SPageInfo::EUnpaged);
       
   917 				*pagesOut++ = pagePhys; // store page address for freeing later
   907 			}
   918 			}
   908 		}
   919 		}
   909 	MmuLock::Unlock();
   920 	MmuLock::Unlock();
   910 
   921 
   911 	iRamPageAllocator->FreeRamPages(aPages, aCount, aZonePageType);
   922 	iRamPageAllocator->FreeRamPages(aPages, aCount, aZonePageType);
   920 	if(K::CheckForSimulatedAllocFail())
   931 	if(K::CheckForSimulatedAllocFail())
   921 		{
   932 		{
   922 		__KTRACE_OPT(KMMU,Kern::Printf("Mmu::AllocContiguousRam returns simulated OOM %d",KErrNoMemory));
   933 		__KTRACE_OPT(KMMU,Kern::Printf("Mmu::AllocContiguousRam returns simulated OOM %d",KErrNoMemory));
   923 		return KErrNoMemory;
   934 		return KErrNoMemory;
   924 		}
   935 		}
   925 	// Only the page sets EAllocNoPagerReclaim and it shouldn't allocate contiguous ram.
   936 	// Only the pager sets EAllocNoPagerReclaim and it shouldn't allocate contiguous ram.
   926 	__NK_ASSERT_DEBUG(!(aFlags&EAllocNoPagerReclaim));
   937 	__NK_ASSERT_DEBUG(!(aFlags&EAllocNoPagerReclaim));
   927 #endif
   938 #endif
   928 	TInt r = iRamPageAllocator->AllocContiguousRam(aCount, aPhysAddr, EPageFixed, aAlign+KPageShift);
   939 	TInt r = iRamPageAllocator->AllocContiguousRam(aCount, aPhysAddr, EPageFixed, aAlign+KPageShift);
   929 	if(r==KErrNoMemory && aCount > KMaxFreeableContiguousPages)
   940 	if(r==KErrNoMemory && aCount > KMaxFreeableContiguousPages)
   930 		{
   941 		{
   931 		// flush paging cache and retry...
   942 		// flush paging cache and retry...
       
   943 		RamAllocLock::Unlock();
   932 		ThePager.FlushAll();
   944 		ThePager.FlushAll();
       
   945 		RamAllocLock::Lock();
   933 		r = iRamPageAllocator->AllocContiguousRam(aCount, aPhysAddr, EPageFixed, aAlign+KPageShift);
   946 		r = iRamPageAllocator->AllocContiguousRam(aCount, aPhysAddr, EPageFixed, aAlign+KPageShift);
   934 		}
   947 		}
   935 	if(r!=KErrNone)
   948 	if(r!=KErrNone)
   936 		iRamAllocFailed = ETrue;
   949 		iRamAllocFailed = ETrue;
   937 	else
   950 	else
   938 		PagesAllocated((TPhysAddr*)(aPhysAddr|1), aCount, aFlags);
   951 		PagesAllocated((TPhysAddr*)(aPhysAddr|1), aCount, aFlags);
   939 	__KTRACE_OPT(KMMU,Kern::Printf("AllocContiguouseRam returns %d and aPhysAddr=0x%08x",r,aPhysAddr));
   952 	__KTRACE_OPT(KMMU,Kern::Printf("AllocContiguousRam returns %d and aPhysAddr=0x%08x",r,aPhysAddr));
   940 	return r;
   953 	return r;
   941 	}
   954 	}
   942 
   955 
   943 
   956 
   944 void Mmu::FreeContiguousRam(TPhysAddr aPhysAddr, TUint aCount)
   957 void Mmu::FreeContiguousRam(TPhysAddr aPhysAddr, TUint aCount)