kernel/eka/memmodel/epoc/flexible/mmu/mptalloc.h
changeset 33 0173bcd7697c
parent 0 a41df078684a
child 117 5b5d147c7838
equal deleted inserted replaced
31:56f325a607ea 33:0173bcd7697c
    42 /**
    42 /**
    43 The maximum number of pages required to pin a single page table.
    43 The maximum number of pages required to pin a single page table.
    44 */
    44 */
    45 const TUint KNumPagesToPinOnePageTable = 2; // 1 page table page + 1 page table info page
    45 const TUint KNumPagesToPinOnePageTable = 2; // 1 page table page + 1 page table info page
    46 
    46 
       
    47 /**
       
    48 The minimum number of unpinned paged page table pages required so a page fault 
       
    49 can't fail to allocate a page table.
       
    50 */
       
    51 const TUint KMinUnpinnedPagedPtPages = KMaxCpus;
       
    52 
    47 
    53 
    48 /**
    54 /**
    49 Class for allocating MMU page tables.
    55 Class for allocating MMU page tables.
    50 */
    56 */
    51 class PageTableAllocator
    57 class PageTableAllocator
   157 	@param aPageTable	Virtual address of the page table,
   163 	@param aPageTable	Virtual address of the page table,
   158 	@param aPinArgs		The resources to use for pinning. This must have
   164 	@param aPinArgs		The resources to use for pinning. This must have
   159 						at least #KNumPagesToPinOnePageTable replacement
   165 						at least #KNumPagesToPinOnePageTable replacement
   160 						pages available.
   166 						pages available.
   161 	*/
   167 	*/
   162 	static void PinPageTable(TPte* aPageTable, TPinArgs& aPinArgs);
   168 	TInt PinPageTable(TPte* aPageTable, TPinArgs& aPinArgs);
   163 
   169 
   164 	/**
   170 	/**
   165 	Unpin the RAM page containing a page table, as well as the RAM page
   171 	Unpin the RAM page containing a page table, as well as the RAM page
   166 	containing its #SPageTableInfo structure.
   172 	containing its #SPageTableInfo structure.
   167 	This reverses the action of #PinPageTable.
   173 	This reverses the action of #PinPageTable.
   170 	@param aPinArgs		The resources to use for pinning. The replacement
   176 	@param aPinArgs		The resources to use for pinning. The replacement
   171 						pages count in this will be incremented for each
   177 						pages count in this will be incremented for each
   172 						completely unpinned, e.g. those which can be reused
   178 						completely unpinned, e.g. those which can be reused
   173 						as new replacement pages or freed.
   179 						as new replacement pages or freed.
   174 	*/
   180 	*/
   175 	static void UnpinPageTable(TPte* aPageTable, TPinArgs& aPinArgs);
   181 	void UnpinPageTable(TPte* aPageTable, TPinArgs& aPinArgs);
   176 
   182 
   177 private:
   183 private:
   178 	/**
   184 	/**
   179 	Sub-allocator used for managing page tables of a given 'pagedness' (paged/not-paged).
   185 	Sub-allocator used for managing page tables of a given 'pagedness' (paged/not-paged).
   180 	Each allocator maintains a list free page tables (#iFreeList) from which it can allocate.
   186 	Each allocator maintains a list free page tables (#iFreeList) from which it can allocate.
   356 		{
   362 		{
   357 	public:
   363 	public:
   358 		void Init2(TUint aNumInitPages);
   364 		void Init2(TUint aNumInitPages);
   359 		TInt Alloc(TBool aDemandPaged);
   365 		TInt Alloc(TBool aDemandPaged);
   360 		void Free(TUint aPageIndex, TBool aDemandPaged);
   366 		void Free(TUint aPageIndex, TBool aDemandPaged);
   361 		TBool IsDemandPaged(SPageInfo* aPageInfo)
   367 		
   362 			{// Is the highest page table index this page table info page can reference 
   368 		/**
       
   369 		Determine if the page table info page is paged.
       
   370 		
       
   371 		@param aPageInfo Pointer to the SPageInfo of the page table info page.
       
   372 		@return ETrue if the page table info page is paged, EFalse otherwise.
       
   373 		@pre MmuLock is held.
       
   374 		*/
       
   375 		inline TBool IsDemandPagedPtInfo(SPageInfo* aPageInfo)
       
   376 			{
       
   377 			// Is the highest page table index this page table info page can reference 
   363 			// allocated within the demand paged region of the page table address space.
   378 			// allocated within the demand paged region of the page table address space.
   364 			TUint groupIndex = aPageInfo->Index();
   379 			TUint groupIndex = aPageInfo->Index();
   365 			return ((groupIndex+1) * KPageTableGroupSize)-1 >= iUpperWaterMark;
   380 			return ((groupIndex+1) * KPageTableGroupSize)-1 >= iUpperWaterMark;
   366 			}
   381 			}
       
   382 
       
   383 		/**
       
   384 		Determine if the page table page is paged.
       
   385 		
       
   386 		@param aPageInfo Pointer to the SPageInfo of the page table info page.
       
   387 		@return ETrue if the page table page is paged, EFalse otherwise.
       
   388 		@pre MmuLock is held.	
       
   389 		*/
       
   390 		inline TBool IsDemandPagedPt(SPageInfo* aPageInfo)
       
   391 			{
       
   392 			return aPageInfo->Index() >= iUpperWaterMark;
       
   393 			}
       
   394 
       
   395 		/**
       
   396 		Get a random paged page table page.
       
   397 		
       
   398 		@return The index of a paged page table page.
       
   399 		@pre All paged page table pages are allocated.
       
   400 		@pre Page tables lock is held.
       
   401 		*/
       
   402 		TUint RandomPagedPtPage();
       
   403 
       
   404 		/**
       
   405 		Increase the count of pinned paged page table pages.
       
   406 		
       
   407 		@return KErrNone on success, KErrNoMemory if too many pages are already pinned.
       
   408 		@pre MmuLock is held
       
   409 		*/
       
   410 		inline TInt PtPagePinCountInc()
       
   411 			{
       
   412 			if (AtPinnedPagedPtsLimit(iUpperWaterMark, iLowerWaterMark, iPinnedPageTablePages + 1))
       
   413 				{
       
   414 				return KErrNoMemory;
       
   415 				}
       
   416 			iPinnedPageTablePages++;
       
   417 			return KErrNone;
       
   418 			}
       
   419 
       
   420 		/**
       
   421 		Decrease the count of pinned paged page table pages.
       
   422 		
       
   423 		@pre MmuLock is held
       
   424 		*/
       
   425 		inline void PtPagePinCountDec()
       
   426 			{
       
   427 			__NK_ASSERT_DEBUG(iPinnedPageTablePages);	// Can't be zero.
       
   428 			iPinnedPageTablePages--;
       
   429 			}
       
   430 
       
   431 	private:
       
   432 		/**
       
   433 		Check whether it is safe to pin a paged page table or reduce the amount of 
       
   434 		virtual address space available to paged page tables.  By checking that we 
       
   435 		either have spare virtual address space to increase the	amount of paged page 
       
   436 		tables or that there are already enough unpinned paged page tables.
       
   437 		
       
   438 		@return ETrue if there isn't or EFalse if it is ok to pin more paged page
       
   439 				tables or increase the number of unpaged page tables.
       
   440 		*/
       
   441 		TBool AtPinnedPagedPtsLimit(TUint aUpperWaterMark, TUint aLowerWaterMark, TUint aPinnedPtPages)
       
   442 			{
       
   443 			TUint adjustedUpperWaterMark = aUpperWaterMark & ~(KPageTableGroupSize - 1);
       
   444 			TUint availPagedPtPages = KMaxPageTablePages - adjustedUpperWaterMark;
       
   445 			TUint availUnpinnedPagedPtPages = availPagedPtPages - aPinnedPtPages;
       
   446 			// This check is sufficient as we only increase the pinned paged page table 
       
   447 			// pages or unpaged page table pages one at a time.
       
   448 			return (aLowerWaterMark + 1 == adjustedUpperWaterMark && 
       
   449 					availUnpinnedPagedPtPages < KMinUnpinnedPagedPtPages);
       
   450 			}
       
   451 
   367 	private:
   452 	private:
   368 		TBitMapAllocator* iLowerAllocator; ///< Allocator for unpaged page tables
   453 		TBitMapAllocator* iLowerAllocator; ///< Allocator for unpaged page tables
   369 		TUint iLowerWaterMark; ///< Highest page index allocated by iLowerAllocator
   454 		TUint iLowerWaterMark; ///< Highest page index allocated by iLowerAllocator
   370 		TBitMapAllocator* iUpperAllocator; ///< Allocator for demand paged page tables
   455 		TBitMapAllocator* iUpperAllocator; ///< Allocator for demand paged page tables
   371 		TUint iUpperWaterMark; ///< Lowest page index allocated by iUpperAllocator
   456 		TUint iUpperWaterMark; ///< Lowest page index allocated by iUpperAllocator
       
   457 		TUint iPinnedPageTablePages; ///< The number of pinned paged page table pages.
   372 		};
   458 		};
   373 
   459 
   374 	/**
   460 	/**
   375 	Allocator for page indexes within #iPageTableMemory.
   461 	Allocator for page indexes within #iPageTableMemory.
   376 	*/
   462 	*/