52 Memory for page tables and page table info objects is managed by |
52 Memory for page tables and page table info objects is managed by |
53 #ThePageTableMemoryManager. When allocating memory for demand paged use, this |
53 #ThePageTableMemoryManager. When allocating memory for demand paged use, this |
54 uses memory from #ThePager which will reclaim paged memory if necessary. |
54 uses memory from #ThePager which will reclaim paged memory if necessary. |
55 Providing the live list always has #DPager::iMinYoungPages, this guarantees that |
55 Providing the live list always has #DPager::iMinYoungPages, this guarantees that |
56 handling page faults can never fail by running out of memory. |
56 handling page faults can never fail by running out of memory. |
57 |
|
58 TODO: In really pathological situations page table allocation can fail due to |
|
59 being out of virtual address space to map the table, this needs to be prevented |
|
60 from happening when handling demand paging faults. |
|
61 */ |
57 */ |
62 |
58 |
63 |
59 |
64 PageTableAllocator PageTables; |
60 PageTableAllocator PageTables; |
65 |
61 |
120 { } |
116 { } |
121 |
117 |
122 |
118 |
123 virtual TInt MovePage( DMemoryObject* aMemory, SPageInfo* aOldPageInfo, |
119 virtual TInt MovePage( DMemoryObject* aMemory, SPageInfo* aOldPageInfo, |
124 TPhysAddr& aNewPage, TUint aBlockZoneId, TBool aBlockRest); |
120 TPhysAddr& aNewPage, TUint aBlockZoneId, TBool aBlockRest); |
|
121 |
|
122 virtual TInt MoveAndAllocPage(DMemoryObject* aMemory, SPageInfo* aPageInfo, TZonePageType aType); |
125 public: |
123 public: |
126 /** |
124 /** |
127 Allocate a page of RAM for storing page tables in. |
125 Allocate a page of RAM for storing page tables in. |
128 |
126 |
129 @param aMemory A memory object associated with this manager. |
127 @param aMemory A memory object associated with this manager. |
265 // cleanup... |
263 // cleanup... |
266 aMemory->iPages.RemovePageEnd(aIndex,r); |
264 aMemory->iPages.RemovePageEnd(aIndex,r); |
267 return r; |
265 return r; |
268 } |
266 } |
269 |
267 |
|
268 |
270 TInt DPageTableMemoryManager::MovePage( DMemoryObject* aMemory, SPageInfo* aOldPageInfo, |
269 TInt DPageTableMemoryManager::MovePage( DMemoryObject* aMemory, SPageInfo* aOldPageInfo, |
271 TPhysAddr& aNewPage, TUint aBlockZoneId, TBool aBlockRest) |
270 TPhysAddr& aNewPage, TUint aBlockZoneId, TBool aBlockRest) |
272 { |
271 { |
273 // This could be a demand paged page table info which can be discarded |
272 // This could be a demand paged page table info which can be discarded |
274 // but let the PageTableAllocator handle that. |
273 // but let the PageTableAllocator handle that. |
275 return ::PageTables.MovePage(aMemory, aOldPageInfo, aBlockZoneId, aBlockRest); |
274 return ::PageTables.MovePage(aMemory, aOldPageInfo, aBlockZoneId, aBlockRest); |
276 } |
275 } |
|
276 |
|
277 |
|
278 TInt DPageTableMemoryManager::MoveAndAllocPage(DMemoryObject* aMemory, SPageInfo* aPageInfo, TZonePageType aPageType) |
|
279 { |
|
280 // This could be a demand paged page table info which can be discarded |
|
281 // but let the PageTableAllocator handle that. |
|
282 return ::PageTables.MoveAndAllocPage(aMemory, aPageInfo, aPageType); |
|
283 } |
277 |
284 |
278 |
285 |
279 // |
286 // |
280 // PageTableAllocator |
287 // PageTableAllocator |
281 // |
288 // |
1179 |
1186 |
1180 |
1187 |
1181 TInt PageTableAllocator::MovePage(DMemoryObject* aMemory, SPageInfo* aOldPageInfo, |
1188 TInt PageTableAllocator::MovePage(DMemoryObject* aMemory, SPageInfo* aOldPageInfo, |
1182 TUint aBlockZoneId, TBool aBlockRest) |
1189 TUint aBlockZoneId, TBool aBlockRest) |
1183 { |
1190 { |
|
1191 __NK_ASSERT_DEBUG(MmuLock::IsHeld()); |
1184 // We don't move page table or page table info pages, however, if this page |
1192 // We don't move page table or page table info pages, however, if this page |
1185 // is demand paged then we may be able to discard it. |
1193 // is demand paged then we may be able to discard it. |
1186 MmuLock::Lock(); |
|
1187 if (aOldPageInfo->Owner() == iPageTableInfoMemory) |
1194 if (aOldPageInfo->Owner() == iPageTableInfoMemory) |
1188 { |
1195 { |
1189 if (!(iPtPageAllocator.IsDemandPagedPtInfo(aOldPageInfo))) |
1196 if (!(iPtPageAllocator.IsDemandPagedPtInfo(aOldPageInfo))) |
1190 { |
1197 { |
1191 MmuLock::Unlock(); |
1198 MmuLock::Unlock(); |
1208 return KErrInUse; |
1215 return KErrInUse; |
1209 } |
1216 } |
1210 // Let the pager discard the page as it controls the size of the live list. |
1217 // Let the pager discard the page as it controls the size of the live list. |
1211 // If the size of the live list allows then eventually |
1218 // If the size of the live list allows then eventually |
1212 // PageTableAllocator::StealPage() will be invoked on this page. |
1219 // PageTableAllocator::StealPage() will be invoked on this page. |
1213 return ThePager.DiscardPage(aOldPageInfo, aBlockZoneId, aBlockRest); |
1220 TUint moveDisFlags = (aBlockRest)? M::EMoveDisBlockRest : 0; |
|
1221 return ThePager.DiscardPage(aOldPageInfo, aBlockZoneId, moveDisFlags); |
|
1222 } |
|
1223 |
|
1224 |
|
1225 TInt PageTableAllocator::MoveAndAllocPage(DMemoryObject* aMemory, SPageInfo* aPageInfo, TZonePageType aPageType) |
|
1226 { |
|
1227 TInt r = MovePage(aMemory, aPageInfo, KRamZoneInvalidId, EFalse); |
|
1228 if (r == KErrNone) |
|
1229 { |
|
1230 TheMmu.MarkPageAllocated(aPageInfo->PhysAddr(), aPageType); |
|
1231 } |
|
1232 return r; |
1214 } |
1233 } |
1215 |
1234 |
1216 |
1235 |
1217 TInt PageTableAllocator::PinPageTable(TPte* aPageTable, TPinArgs& aPinArgs) |
1236 TInt PageTableAllocator::PinPageTable(TPte* aPageTable, TPinArgs& aPinArgs) |
1218 { |
1237 { |