kernel/eka/memmodel/epoc/flexible/mmu/mpager.cpp
changeset 102 ef2a444a7410
parent 90 947f0dc9f7a8
child 109 b3a1d9898418
equal deleted inserted replaced
90:947f0dc9f7a8 102:ef2a444a7410
    90 					+(4+KPtClusterSize-1)/KPtClusterSize		// page table pages
    90 					+(4+KPtClusterSize-1)/KPtClusterSize		// page table pages
    91 					+(4+KPageTableInfosPerPage-1)/KPageTableInfosPerPage;	// page table info pages
    91 					+(4+KPageTableInfosPerPage-1)/KPageTableInfosPerPage;	// page table info pages
    92 
    92 
    93 #elif defined(__CPU_X86)
    93 #elif defined(__CPU_X86)
    94 
    94 
    95 /*	Need at least 6 mapped pages to guarantee to be able to execute all ARM instructions,
    95 /*	Need at least 6 mapped pages to guarantee to be able to execute all X86 instructions,
    96 	plus enough pages for 6 page tables to map those pages, plus enough pages for the
    96 	plus enough pages for 6 page tables to map those pages, plus enough pages for the
    97 	page table info structures of those page tables.
    97 	page table info structures of those page tables.
    98 	(Worst case is (?) a MOV [X],[Y] instruction with instruction, 'X' and 'Y' all
    98 	(Worst case is (?) a MOV [X],[Y] instruction with instruction, 'X' and 'Y' all
    99 	straddling chunk boundaries.)
    99 	straddling chunk boundaries.)
   100 */
   100 */
   198 		// Allocate a single page
   198 		// Allocate a single page
   199 		TPhysAddr pagePhys;
   199 		TPhysAddr pagePhys;
   200 		TInt r = m.AllocRam(&pagePhys, 1, 
   200 		TInt r = m.AllocRam(&pagePhys, 1, 
   201 							(Mmu::TRamAllocFlags)(EMemAttNormalCached|Mmu::EAllocNoWipe|Mmu::EAllocNoPagerReclaim), 
   201 							(Mmu::TRamAllocFlags)(EMemAttNormalCached|Mmu::EAllocNoWipe|Mmu::EAllocNoPagerReclaim), 
   202 							EPageDiscard);
   202 							EPageDiscard);
   203 		if(r!=KErrNone)
   203 		__NK_ASSERT_ALWAYS(r == KErrNone);
   204 			__NK_ASSERT_ALWAYS(0);
       
   205 		MmuLock::Lock();
   204 		MmuLock::Lock();
   206 		AddAsFreePage(SPageInfo::FromPhysAddr(pagePhys));
   205 		AddAsFreePage(SPageInfo::FromPhysAddr(pagePhys));
   207 		MmuLock::Unlock();
   206 		MmuLock::Unlock();
   208 		}
   207 		}
   209 	RamAllocLock::Unlock();
   208 	RamAllocLock::Unlock();
   212 	TRACEB(("DPager::InitCache() end with young=%d old=%d oldClean=%d oldDirty=%d min=%d free=%d max=%d",iYoungCount,iOldCount,iOldestCleanCount,iOldestDirtyCount,iMinimumPageCount,iNumberOfFreePages,iMaximumPageCount));
   211 	TRACEB(("DPager::InitCache() end with young=%d old=%d oldClean=%d oldDirty=%d min=%d free=%d max=%d",iYoungCount,iOldCount,iOldestCleanCount,iOldestDirtyCount,iMinimumPageCount,iNumberOfFreePages,iMaximumPageCount));
   213 	}
   212 	}
   214 
   213 
   215 
   214 
   216 #ifdef _DEBUG
   215 #ifdef _DEBUG
       
   216 #ifdef FMM_PAGER_CHECK_LISTS
       
   217 TBool CheckList(SDblQueLink* aHead, TUint aCount)
       
   218 	{
       
   219 	SDblQueLink* link = aHead;
       
   220 	while(aCount--)
       
   221 		{
       
   222 		link = link->iNext;
       
   223 		if(link == aHead)
       
   224 			return EFalse;
       
   225 		}
       
   226 	link = link->iNext;
       
   227 	if(link != aHead)
       
   228 		return EFalse;
       
   229 	return ETrue;
       
   230 	}
       
   231 #endif // #ifdef FMM_PAGER_CHECK_LISTS
       
   232 
   217 TBool DPager::CheckLists()
   233 TBool DPager::CheckLists()
   218 	{
   234 	{
   219 #if 0
   235 #ifdef FMM_PAGER_CHECK_LISTS
   220 	__NK_ASSERT_DEBUG(MmuLock::IsHeld());
   236 	__NK_ASSERT_DEBUG(MmuLock::IsHeld());
   221 	SDblQueLink* head = &iOldList.iA;
   237 	if (!CheckList(&iOldList.iA, iOldCount))
   222 	TInt n = iOldCount;
   238 		return EFalse;
   223 	SDblQueLink* link = head;
   239 	if (!CheckList(&iYoungList.iA, iYoungCount))
   224 	while(n--)
   240 		return EFalse;
   225 		{
   241 	if (!CheckList(&iOldestCleanList.iA, iOldestCleanCount))
   226 		link = link->iNext;
   242 		return EFalse;
   227 		if(link==head)
   243 	if (!CheckList(&iOldestDirtyList.iA, iOldestDirtyCount))
   228 			return false;
   244 		return EFalse;
   229 		}
   245 	TRACEP(("DP: y=%d o=%d oc=%d od=%d f=%d", iYoungCount, iOldCount, 
   230 	link = link->iNext;
   246 			iOldestCleanCount, iOldestDirtyCount, iNumberOfFreePages));
   231 	if(link!=head)
   247 	TraceCounts();
   232 		return false;
   248 #endif // #ifdef FMM_PAGER_CHECK_LISTS
   233 
       
   234 	head = &iYoungList.iA;
       
   235 	n = iYoungCount;
       
   236 	link = head;
       
   237 	while(n--)
       
   238 		{
       
   239 		link = link->iNext;
       
   240 		if(link==head)
       
   241 			return false;
       
   242 		}
       
   243 	link = link->iNext;
       
   244 	if(link!=head)
       
   245 		return false;
       
   246 
       
   247 //	TRACEP(("DP: y=%d o=%d f=%d",iYoungCount,iOldCount,iNumberOfFreePages));
       
   248 #endif
       
   249 //	TraceCounts();
       
   250 	return true;
   249 	return true;
   251 	}
   250 	}
   252 
   251 
   253 void DPager::TraceCounts()
   252 void DPager::TraceCounts()
   254 	{
   253 	{
   255 	TRACEP(("DP: y=%d o=%d f=%d min=%d max=%d ml=%d res=%d",
   254 	TRACEP(("DP: y=%d o=%d oc=%d od=%d f=%d min=%d max=%d ml=%d res=%d",
   256 		iYoungCount,iOldCount,iNumberOfFreePages,iMinimumPageCount,
   255 		iYoungCount, iOldCount, iOldestCleanCount, iOldestDirtyCount, 
   257 		iMaximumPageCount,iMinimumPageLimit,iReservePageCount));
   256 		iNumberOfFreePages, iMinimumPageCount, iMaximumPageCount,
   258 	}
   257 		iMinimumPageLimit, iReservePageCount));
   259 
   258 	}
   260 #endif
   259 #endif //#ifdef _DEBUG
   261 
   260 
   262 
   261 
   263 TBool DPager::HaveTooManyPages()
   262 TBool DPager::HaveTooManyPages()
   264 	{
   263 	{
   265 	__NK_ASSERT_DEBUG(RamAllocLock::IsHeld());
   264 	__NK_ASSERT_DEBUG(RamAllocLock::IsHeld());
  1982 	NKern::ThreadEnterCS();
  1981 	NKern::ThreadEnterCS();
  1983 	RamAllocLock::Lock();
  1982 	RamAllocLock::Lock();
  1984 
  1983 
  1985 	MmuLock::Lock();
  1984 	MmuLock::Lock();
  1986 
  1985 
  1987 	__NK_ASSERT_ALWAYS(iYoungOldRatio!=0);
  1986 	__NK_ASSERT_ALWAYS(iYoungOldRatio);
  1988 
  1987 
  1989 	// Make sure aMinimumPageCount is not less than absolute minimum we can cope with...
  1988 	// Make sure aMinimumPageCount is not less than absolute minimum we can cope with...
  1990 	iMinimumPageLimit = iMinYoungPages * (1 + iYoungOldRatio) / iYoungOldRatio
  1989 	iMinimumPageLimit = iMinYoungPages * (1 + iYoungOldRatio) / iYoungOldRatio
  1991 						+ DPageReadRequest::ReservedPagesRequired();
  1990 						+ DPageReadRequest::ReservedPagesRequired();
  1992 	if(iMinimumPageLimit<iAbsoluteMinPageCount)
  1991 	if(iMinimumPageLimit<iAbsoluteMinPageCount)
  1995 		aMinimumPageCount = iMinimumPageLimit+iReservePageCount;
  1994 		aMinimumPageCount = iMinimumPageLimit+iReservePageCount;
  1996 	if(aMaximumPageCount<aMinimumPageCount)
  1995 	if(aMaximumPageCount<aMinimumPageCount)
  1997 		aMaximumPageCount=aMinimumPageCount;
  1996 		aMaximumPageCount=aMinimumPageCount;
  1998 
  1997 
  1999 	// Increase iMaximumPageCount?
  1998 	// Increase iMaximumPageCount?
  2000 	TInt extra = aMaximumPageCount-iMaximumPageCount;
  1999 	if(aMaximumPageCount > iMaximumPageCount)
  2001 	if(extra>0)
  2000 		iMaximumPageCount = aMaximumPageCount;
  2002 		iMaximumPageCount += extra;
       
  2003 
  2001 
  2004 	// Reduce iMinimumPageCount?
  2002 	// Reduce iMinimumPageCount?
  2005 	TInt spare = iMinimumPageCount-aMinimumPageCount;
  2003 	TInt spare = iMinimumPageCount-aMinimumPageCount;
  2006 	if(spare>0)
  2004 	if(spare>0)
  2007 		{
  2005 		{
  2835 
  2833 
  2836 
  2834 
  2837 EXPORT_C TInt DDemandPagingLock::Lock(DThread* aThread, TLinAddr aStart, TInt aSize)
  2835 EXPORT_C TInt DDemandPagingLock::Lock(DThread* aThread, TLinAddr aStart, TInt aSize)
  2838 	{
  2836 	{
  2839 //	TRACEP(("DDemandPagingLock[0x%08x]::Lock(0x%08x,0x%08x,0x%08x)",this,aThread,aStart,aSize));
  2837 //	TRACEP(("DDemandPagingLock[0x%08x]::Lock(0x%08x,0x%08x,0x%08x)",this,aThread,aStart,aSize));
  2840 	if(iLockedPageCount)
  2838 	__NK_ASSERT_ALWAYS(!iLockedPageCount); // lock already used
  2841 		__NK_ASSERT_ALWAYS(0); // lock already used
       
  2842 
  2839 
  2843 	// calculate the number of pages that need to be locked...
  2840 	// calculate the number of pages that need to be locked...
  2844 	TUint mask=KPageMask;
  2841 	TUint mask=KPageMask;
  2845 	TUint offset=aStart&mask;
  2842 	TUint offset=aStart&mask;
  2846 	TInt numPages = (aSize+offset+mask)>>KPageShift;
  2843 	TInt numPages = (aSize+offset+mask)>>KPageShift;
  2847 	if(numPages>iMaxPageCount)
  2844 
  2848 		__NK_ASSERT_ALWAYS(0);
  2845 	// Should never be asked to lock more pages than are allocated to this object.
       
  2846 	__NK_ASSERT_ALWAYS(numPages <= iMaxPageCount);
  2849 
  2847 
  2850 	NKern::ThreadEnterCS();
  2848 	NKern::ThreadEnterCS();
  2851 
  2849 
  2852 	// find mapping which covers the specified region...
  2850 	// find mapping which covers the specified region...
  2853 	TUint offsetInMapping;
  2851 	TUint offsetInMapping;