--- a/kernel/eka/memmodel/epoc/flexible/mmu/mpager.cpp Tue Aug 31 16:34:26 2010 +0300
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mpager.cpp Wed Sep 01 12:34:56 2010 +0100
@@ -1393,10 +1393,6 @@
TInt r = Kern::AddHalEntry(EHalGroupVM, VMHalFunction, 0);
__NK_ASSERT_ALWAYS(r==KErrNone);
PageCleaningLock::Init();
-#ifdef __DEMAND_PAGING_BENCHMARKS__
- for (TInt i = 0 ; i < EMaxPagingBm ; ++i)
- ResetBenchmarkData((TPagingBenchmark)i);
-#endif
}
@@ -2044,8 +2040,9 @@
}
-DThread* DPager::ResponsibleThread(DThread* aThread, TAny* aExceptionInfo)
+TInt DPager::CheckRealtimeThreadFault(DThread* aThread, TAny* aExceptionInfo)
{
+ // realtime threads shouldn't take paging faults...
DThread* client = aThread->iIpcClient;
// If iIpcClient is set then we are accessing the address space of a remote thread. If we are
@@ -2054,81 +2051,29 @@
TIpcExcTrap* ipcTrap = (TIpcExcTrap*)aThread->iExcTrap;
if (ipcTrap && !ipcTrap->IsTIpcExcTrap())
ipcTrap = 0;
- if (client &&
- (!ipcTrap || ipcTrap->ExcLocation(aThread, aExceptionInfo) == TIpcExcTrap::EExcRemote))
- return client;
- else
- return NULL;
- }
-
-
-TInt DPager::CheckRealtimeThreadFault(DThread* aThread, TAny* aExceptionInfo)
- {
- // realtime threads shouldn't take paging faults...
- DThread* thread = ResponsibleThread(aThread, aExceptionInfo);
-
- const char* message = thread ?
- "Access to Paged Memory (by other thread)" : "Access to Paged Memory";
-
- // kill respsonsible thread...
- if(K::IllegalFunctionForRealtimeThread(thread, message))
+ if (client && (!ipcTrap || ipcTrap->ExcLocation(aThread, aExceptionInfo) == TIpcExcTrap::EExcRemote))
{
- // if we are killing the current thread and we are in a critical section, then the above
- // kill will be deferred and we will continue executing. We will handle this by returning an
- // error which means that the thread will take an exception (which hopefully is XTRAPed!)
-
- // treat memory access as bad...
- return KErrAbort;
+ // kill client thread...
+ if(K::IllegalFunctionForRealtimeThread(client,"Access to Paged Memory (by other thread)"))
+ {
+ // treat memory access as bad...
+ return KErrAbort;
+ }
+ // else thread is in 'warning only' state so allow paging...
}
else
{
- // thread is in 'warning only' state so allow paging...
- return KErrNone;
+ // kill current thread...
+ if(K::IllegalFunctionForRealtimeThread(NULL,"Access to Paged Memory"))
+ {
+ // if current thread is in critical section, then the above kill will be deferred
+ // and we will continue executing. We will handle this by returning an error
+ // which means that the thread will take an exception (which hopefully is XTRAPed!)
+ return KErrAbort;
+ }
+ // else thread is in 'warning only' state so allow paging...
}
- }
-
-
-void DPager::KillResponsibleThread(TPagingErrorContext aContext, TInt aErrorCode,
- TAny* aExceptionInfo)
- {
- const char* message = NULL;
- switch (aContext)
- {
- case EPagingErrorContextRomRead:
- message = "PAGED-ROM-READ";
- break;
- case EPagingErrorContextRomDecompress:
- message = "PAGED-ROM-COMP";
- break;
- case EPagingErrorContextCodeRead:
- message = "PAGED-CODE-READ";
- break;
- case EPagingErrorContextCodeDecompress:
- message = "PAGED-CODE-COMP";
- break;
- case EPagingErrorContextDataRead:
- message = "PAGED-DATA-READ";
- break;
- case EPagingErrorContextDataWrite:
- message = "PAGED-DATA-WRITE";
- break;
- default:
- message = "PAGED-UNKNOWN";
- break;
- }
-
- TPtrC8 category((const unsigned char*)message);
- DThread* thread = ResponsibleThread(TheCurrentThread, aExceptionInfo);
- if (thread)
- {
- NKern::LockSystem();
- thread->Die(EExitPanic, aErrorCode, category);
- }
- else
- {
- TheCurrentThread->SetExitInfo(EExitPanic, aErrorCode, category);
- NKern::DeferredExit();
- }
+ return KErrNone;
}
@@ -2154,16 +2099,6 @@
r = manager->HandleFault(aMemory, aFaultIndex, aMapping, aMapInstanceCount, aAccessPermissions);
TheThrashMonitor.NotifyEndPaging();
-
- // If the paging system encountered an error paging in the memory (as opposed to a thread
- // accessing non-existent memory), then panic the appropriate thread. Unfortunately this
- // situation does occur as media such as eMMC wears out towards the end of its life.
- if (r != KErrNone)
- {
- TPagingErrorContext context = ExtractErrorContext(r);
- if (context != EPagingErrorContextNone)
- KillResponsibleThread(context, ExtractErrorCode(r), aExceptionInfo);
- }
}
return r;
}
@@ -2390,100 +2325,6 @@
}
-TInt DPager::FlushRegion(DMemModelProcess* aProcess, TLinAddr aStartAddress, TUint aSize)
- {
- if (aSize == 0)
- return KErrNone;
-
- // find mapping
- NKern::ThreadEnterCS();
- TUint offsetInMapping;
- TUint mapInstanceCount;
- DMemoryMapping* mapping = MM::FindMappingInProcess(aProcess, aStartAddress, aSize,
- offsetInMapping, mapInstanceCount);
- if (!mapping)
- {
- NKern::ThreadLeaveCS();
- return KErrBadDescriptor;
- }
-
- // check whether memory is demand paged
- MmuLock::Lock();
- DMemoryObject* memory = mapping->Memory();
- if(mapInstanceCount != mapping->MapInstanceCount() || memory == NULL || !memory->IsDemandPaged())
- {
- MmuLock::Unlock();
- mapping->Close();
- NKern::ThreadLeaveCS();
- return KErrNone;
- }
-
- TRACE(("DPager::FlushRegion: %O %08x +%d", aProcess, aStartAddress, aSize));
- if (!K::Initialising)
- TRACE2((" context %T %d", NCurrentThread(), NKern::CurrentContext()));
-
- // why did we not get assertion failures before I added this?
- __NK_ASSERT_DEBUG(!Kern::CurrentThread().IsRealtime());
-
- // acquire necessary locks
- MmuLock::Unlock();
- RamAllocLock::Lock();
- PageCleaningLock::Lock();
- MmuLock::Lock();
-
- // find region in memory object
- TUint startPage = (offsetInMapping >> KPageShift) + mapping->iStartIndex;
- TUint sizeInPages = ((aStartAddress & KPageMask) + aSize - 1) >> KPageShift;
- TUint endPage = startPage + sizeInPages;
- TRACE2(("DPager::FlushRegion: page range is %d to %d", startPage, endPage));
-
- // attempt to flush each page
- TUint index = startPage;
- while (mapping->MapInstanceCount() == mapInstanceCount &&
- mapping->Memory() && index <= endPage)
- {
- TRACE2(("DPager::FlushRegion: flushing page %d", index));
- TPhysAddr physAddr = memory->iPages.PhysAddr(index);
-
- if (physAddr != KPhysAddrInvalid)
- {
- TRACE2(("DPager::FlushRegion: phys addr is %08x", physAddr));
- SPageInfo* pi = SPageInfo::SafeFromPhysAddr(physAddr);
- if (pi)
- {
- __NK_ASSERT_DEBUG(pi->Type() == SPageInfo::EManaged);
- SPageInfo::TPagedState state = pi->PagedState();
- if (state==SPageInfo::EPagedYoung || state==SPageInfo::EPagedOld ||
- state==SPageInfo::EPagedOldestClean || state==SPageInfo::EPagedOldestDirty)
- {
- TRACE2(("DPager::FlushRegion: attempt to steal page"));
- TInt r = StealPage(pi);
- if(r==KErrNone)
- {
- TRACE2(("DPager::FlushRegion: attempt to page out %08x", physAddr));
- AddAsFreePage(pi);
- TRACE2(("DPager::FlushRegion: paged out %08x", physAddr));
- }
- else
- TRACE2(("DPager::FlushRegion: page out %08x failed with %d", physAddr, r));
- }
- }
- }
-
- MmuLock::Flash();
- ++index;
- }
-
- MmuLock::Unlock();
- PageCleaningLock::Unlock();
- RamAllocLock::Unlock();
- mapping->Close();
- NKern::ThreadLeaveCS();
- TRACE2(("DPager::FlushRegion: done"));
- return KErrNone;
- }
-
-
void DPager::GetLiveListInfo(SVMCacheInfo& aInfo)
{
MmuLock::Lock(); // ensure consistent set of values are read...
@@ -2705,18 +2546,7 @@
if ((K::MemModelAttributes & EMemModelAttrDataPaging) == 0)
return KErrNotSupported;
return SetDataWriteSize((TUint)a1);
-
-#ifdef _DEBUG
- case EVMHalDebugSetFail:
- {
- TUint context = (TUint)a1;
- if (context >= EMaxPagingErrorContext)
- return KErrArgument;
- __e32_atomic_store_ord32(&(ThePager.iDebugFailContext), context);
- return KErrNone;
- }
-#endif
-
+
default:
return KErrNotSupported;
}