Skip to content

Commit 5599318

Browse files
committed
[NTOSKRNL/MM]
- finally, release user shared data at process address space cleanup. - release PDE pages that might not be freed at process end. - Let the caller handle PDE release when deleting a PTE - restore Richard's ASSERT : All user PDE pages are now freed! svn path=/trunk/; revision=55770
1 parent 680e460 commit 5599318

File tree

7 files changed

+97
-67
lines changed

7 files changed

+97
-67
lines changed

reactos/ntoskrnl/mm/ARM3/pfnlist.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -931,8 +931,11 @@ MiDecrementShareCount(IN PMMPFN Pfn1,
931931
ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
932932
if (Pfn1->u3.e2.ReferenceCount == 1)
933933
{
934-
/* In ReactOS, this path should always be hit with a deleted PFN */
935-
ASSERT(MI_IS_PFN_DELETED(Pfn1) == TRUE);
934+
if(Pfn1->u3.e1.PrototypePte == 0)
935+
{
936+
/* In ReactOS, this path should always be hit with a deleted PFN */
937+
ASSERT(MI_IS_PFN_DELETED(Pfn1) == TRUE);
938+
}
936939

937940
/* Clear the last reference */
938941
Pfn1->u3.e2.ReferenceCount = 0;

reactos/ntoskrnl/mm/ARM3/procsup.c

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1349,6 +1349,8 @@ MmCleanProcessAddressSpace(IN PEPROCESS Process)
13491349
/* Free the VAD memory */
13501350
ExFreePool(Vad);
13511351
}
1352+
/* Delete the shared user data section */
1353+
MiDeleteVirtualAddresses(USER_SHARED_DATA, USER_SHARED_DATA, NULL);
13521354

13531355
/* Release the address space */
13541356
MmUnlockAddressSpace(&Process->Vm);
@@ -1363,14 +1365,6 @@ MmDeleteProcessAddressSpace2(IN PEPROCESS Process)
13631365
PFN_NUMBER PageFrameIndex;
13641366

13651367
//ASSERT(Process->CommitCharge == 0);
1366-
1367-
/* Delete the shared user data section (Should be done in clean, not delete) */
1368-
ASSERT(MmHighestUserAddress > (PVOID)USER_SHARED_DATA);
1369-
KeAttachProcess(&Process->Pcb);
1370-
//DPRINT1("Killing shared user data page no longer works -- has someone changed ARM3 in a way to make this fail now?\n");
1371-
//MiDeleteVirtualAddresses(USER_SHARED_DATA, USER_SHARED_DATA, NULL);
1372-
//DPRINT1("Done\n");
1373-
KeDetachProcess();
13741368

13751369
/* Acquire the PFN lock */
13761370
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
@@ -1407,11 +1401,8 @@ MmDeleteProcessAddressSpace2(IN PEPROCESS Process)
14071401
MiDecrementShareCount(Pfn1, PageFrameIndex);
14081402
MiDecrementShareCount(Pfn1, PageFrameIndex);
14091403

1410-
/* HACK: In Richard's original patch this ASSERT did work */
1411-
//DPRINT1("Ref count: %lx %lx\n", Pfn1->u3.e2.ReferenceCount, Pfn1->u2.ShareCount);
1412-
//ASSERT((Pfn1->u3.e2.ReferenceCount == 0) || (Pfn1->u3.e1.WriteInProgress));
1413-
if(!((Pfn1->u3.e2.ReferenceCount == 0) || (Pfn1->u3.e1.WriteInProgress)))
1414-
DPRINT1("Ref count: %lx %lx\n", Pfn1->u3.e2.ReferenceCount, Pfn1->u2.ShareCount);
1404+
/* Page table is now dead. Bye bye... */
1405+
ASSERT((Pfn1->u3.e2.ReferenceCount == 0) || (Pfn1->u3.e1.WriteInProgress));
14151406
}
14161407
else
14171408
{

reactos/ntoskrnl/mm/ARM3/virtual.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,9 +258,6 @@ MiDeletePte(IN PMMPTE PointerPte,
258258
#if (_MI_PAGING_LEVELS == 2)
259259
}
260260
#endif
261-
/* Drop the reference on the page table. */
262-
MiDecrementShareCount(MiGetPfnEntry(PFN_FROM_PTE(PointerPde)), PFN_FROM_PTE(PointerPde));
263-
264261
/* Drop the share count */
265262
MiDecrementShareCount(Pfn1, PageFrameIndex);
266263

reactos/ntoskrnl/mm/balance.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,9 @@ MmRebalanceMemoryConsumers(VOID)
250250
{
251251
/* Clean up the unused PDEs */
252252
ULONG_PTR Address;
253+
PEPROCESS Process = PsGetCurrentProcess();
254+
255+
/* Acquire PFN lock */
253256
KIRQL OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
254257
PMMPDE pointerPde;
255258
for(Address = (ULONG_PTR)MI_LOWEST_VAD_ADDRESS;
@@ -260,10 +263,11 @@ MmRebalanceMemoryConsumers(VOID)
260263
{
261264
pointerPde = MiAddressToPde(Address);
262265
if(pointerPde->u.Hard.Valid)
263-
MiDeletePte(pointerPde, MiPdeToPte(pointerPde), PsGetCurrentProcess(), NULL);
266+
MiDeletePte(pointerPde, MiPdeToPte(pointerPde), Process, NULL);
264267
ASSERT(pointerPde->u.Hard.Valid == 0);
265268
}
266269
}
270+
/* Release lock */
267271
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
268272
}
269273
#endif

reactos/ntoskrnl/mm/i386/page.c

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,10 @@ MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
248248
PMMPDE PdeBase;
249249
ULONG PdeOffset = MiGetPdeOffset(Address);
250250

251+
/* Nobody but page fault should ask for creating the PDE,
252+
* Which imples that Process is the current one */
253+
ASSERT(Create == FALSE);
254+
251255
PdeBase = MmCreateHyperspaceMapping(PTE_TO_PFN(Process->Pcb.DirectoryTableBase[0]));
252256
if (PdeBase == NULL)
253257
{
@@ -256,24 +260,8 @@ MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
256260
PointerPde = PdeBase + PdeOffset;
257261
if (PointerPde->u.Hard.Valid == 0)
258262
{
259-
/* Nobody but page fault should ask for creating the PDE,
260-
* Which imples that Process is the current one */
261263
MmDeleteHyperspaceMapping(PdeBase);
262-
if(Create == FALSE)
263-
return NULL;
264-
else
265-
{
266-
KAPC_STATE ApcState;
267-
PULONG ret;
268-
/* Attach to process */
269-
KeStackAttachProcess(&Process->Pcb, &ApcState);
270-
271-
/* Retry */
272-
ret = MmGetPageTableForProcess(Process, Address, TRUE);
273-
274-
/* Get Back to original process */
275-
KeUnstackDetachProcess(&ApcState);
276-
}
264+
return NULL;
277265
}
278266
else
279267
{
@@ -717,9 +705,10 @@ MmCreatePageFileMapping(PEPROCESS Process,
717705
KeBugCheck(MEMORY_MANAGEMENT);
718706
}
719707

720-
Pt = MmGetPageTableForProcess(Process, Address, TRUE);
708+
Pt = MmGetPageTableForProcess(Process, Address, FALSE);
721709
if (Pt == NULL)
722710
{
711+
/* Nobody should page out an address that hasn't even been mapped */
723712
KeBugCheck(MEMORY_MANAGEMENT);
724713
}
725714
Pte = InterlockedExchangePte(Pt, SwapEntry << 1);

reactos/ntoskrnl/mm/marea.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,6 +1066,37 @@ MmDeleteProcessAddressSpace(PEPROCESS Process)
10661066
KeBugCheck(MEMORY_MANAGEMENT);
10671067
}
10681068
}
1069+
1070+
#if (_MI_PAGING_LEVELS == 2)
1071+
{
1072+
KIRQL OldIrql;
1073+
PMMPDE pointerPde;
1074+
/* Attach to Process */
1075+
KeAttachProcess(&Process->Pcb);
1076+
1077+
/* Acquire PFN lock */
1078+
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
1079+
1080+
for(Address = MI_LOWEST_VAD_ADDRESS;
1081+
Address < MM_HIGHEST_VAD_ADDRESS;
1082+
Address =(PVOID)((ULONG_PTR)Address + (PAGE_SIZE * PTE_COUNT)))
1083+
{
1084+
/* At this point all references should be dead */
1085+
ASSERT(MmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)] == 0);
1086+
pointerPde = MiAddressToPde(Address);
1087+
/* Unlike in ARM3, we don't necesarrily free the PDE page as soon as reference reaches 0,
1088+
* so we must clean up a bit when process closes */
1089+
if(pointerPde->u.Hard.Valid)
1090+
MiDeletePte(pointerPde, MiPdeToPte(pointerPde), Process, NULL);
1091+
ASSERT(pointerPde->u.Hard.Valid == 0);
1092+
}
1093+
/* Release lock */
1094+
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
1095+
1096+
/* Detach */
1097+
KeDetachProcess();
1098+
}
1099+
#endif
10691100

10701101
MmUnlockAddressSpace(&Process->Vm);
10711102

reactos/ntoskrnl/mm/section.c

Lines changed: 45 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ typedef struct
119119
ULONG Offset;
120120
BOOLEAN WasDirty;
121121
BOOLEAN Private;
122+
PEPROCESS CallingProcess;
122123
}
123124
MM_SECTION_PAGEOUT_CONTEXT;
124125

@@ -2052,10 +2053,11 @@ MmPageOutDeleteMapping(PVOID Context, PEPROCESS Process, PVOID Address)
20522053
}
20532054

20542055
#if (_MI_PAGING_LEVELS == 2)
2055-
if(Address < MmSystemRangeStart)
2056+
/* If this is for the calling process, we take care of te reference in the main function */
2057+
if((Address < MmSystemRangeStart) && (Process != PageOutContext->CallingProcess))
20562058
{
2057-
if(Process->VmDeleted) DPRINT1("deleted!!!");
20582059
Process->Vm.VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)]--;
2060+
ASSERT(Process->Vm.VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)] < PTE_COUNT);
20592061
}
20602062
#endif
20612063

@@ -2091,6 +2093,7 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
20912093
*/
20922094
Context.Segment = MemoryArea->Data.SectionData.Segment;
20932095
Context.Section = MemoryArea->Data.SectionData.Section;
2096+
Context.CallingProcess = Process;
20942097

20952098
Context.Offset = (ULONG)((ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
20962099
+ MemoryArea->Data.SectionData.ViewOffset);
@@ -2223,6 +2226,14 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
22232226
}
22242227
if (!Context.WasDirty && SwapEntry != 0)
22252228
{
2229+
#if (_MI_PAGING_LEVELS == 2)
2230+
/* We keep the pagefile index global to the segment, not in the PTE */
2231+
if(Address < MmSystemRangeStart)
2232+
{
2233+
Process->Vm.VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)]--;
2234+
ASSERT(Process->Vm.VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)] < PTE_COUNT);
2235+
}
2236+
#endif
22262237
MmSetSavedSwapEntryPage(Page, 0);
22272238
MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, MAKE_SWAP_SSE(SwapEntry));
22282239
MmReleasePageMemoryConsumer(MC_USER, Page);
@@ -2241,6 +2252,14 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
22412252
}
22422253
if (!Context.WasDirty || SwapEntry != 0)
22432254
{
2255+
#if (_MI_PAGING_LEVELS == 2)
2256+
/* We keep the pagefile index global to the segment, not in the PTE */
2257+
if(Address < MmSystemRangeStart)
2258+
{
2259+
Process->Vm.VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)]--;
2260+
ASSERT(Process->Vm.VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)] < PTE_COUNT);
2261+
}
2262+
#endif
22442263
MmSetSavedSwapEntryPage(Page, 0);
22452264
if (SwapEntry != 0)
22462265
{
@@ -2254,6 +2273,14 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
22542273
}
22552274
else if (!Context.Private && DirectMapped)
22562275
{
2276+
#if (_MI_PAGING_LEVELS == 2)
2277+
/* Read only page, no need for a pagefile entry -> PDE-- */
2278+
if(Address < MmSystemRangeStart)
2279+
{
2280+
Process->Vm.VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)]--;
2281+
ASSERT(Process->Vm.VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)] < PTE_COUNT);
2282+
}
2283+
#endif
22572284
if (SwapEntry != 0)
22582285
{
22592286
DPRINT1("Found a swapentry for a non private and direct mapped page (address %x)\n",
@@ -2282,6 +2309,14 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
22822309
Address);
22832310
KeBugCheck(MEMORY_MANAGEMENT);
22842311
}
2312+
#if (_MI_PAGING_LEVELS == 2)
2313+
/* Non dirty, non private, non direct-mapped -> PDE-- */
2314+
if(Address < MmSystemRangeStart)
2315+
{
2316+
Process->Vm.VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)]--;
2317+
ASSERT(Process->Vm.VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)] < PTE_COUNT);
2318+
}
2319+
#endif
22852320
MmReleasePageMemoryConsumer(MC_USER, Page);
22862321
PageOp->Status = STATUS_SUCCESS;
22872322
MmspCompleteAndReleasePageOp(PageOp);
@@ -2291,13 +2326,6 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
22912326
{
22922327
MmSetSavedSwapEntryPage(Page, 0);
22932328
MmLockAddressSpace(AddressSpace);
2294-
#if (_MI_PAGING_LEVELS == 2)
2295-
/* Page table was dereferenced while deleting the RMAP */
2296-
if(Address < MmSystemRangeStart)
2297-
{
2298-
AddressSpace->VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)]++;
2299-
}
2300-
#endif
23012329
Status = MmCreatePageFileMapping(Process,
23022330
Address,
23032331
SwapEntry);
@@ -2325,13 +2353,6 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
23252353
/*
23262354
* For private pages restore the old mappings.
23272355
*/
2328-
#if (_MI_PAGING_LEVELS == 2)
2329-
/* Page table was dereferenced while deleting the RMAP */
2330-
if(Address < MmSystemRangeStart)
2331-
{
2332-
AddressSpace->VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)]++;
2333-
}
2334-
#endif
23352356
if (Context.Private)
23362357
{
23372358
Status = MmCreateVirtualMapping(Process,
@@ -2382,13 +2403,6 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
23822403
* As above: undo our actions.
23832404
* FIXME: Also free the swap page.
23842405
*/
2385-
#if (_MI_PAGING_LEVELS == 2)
2386-
/* Page table was dereferenced while deleting the RMAP */
2387-
if(Address < MmSystemRangeStart)
2388-
{
2389-
AddressSpace->VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)]++;
2390-
}
2391-
#endif
23922406
MmLockAddressSpace(AddressSpace);
23932407
if (Context.Private)
23942408
{
@@ -2440,13 +2454,6 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
24402454
if (Context.Private)
24412455
{
24422456
MmLockAddressSpace(AddressSpace);
2443-
#if (_MI_PAGING_LEVELS == 2)
2444-
/* Page table was dereferenced while deleting the RMAP */
2445-
if(Address < MmSystemRangeStart)
2446-
{
2447-
AddressSpace->VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)]++;
2448-
}
2449-
#endif
24502457
Status = MmCreatePageFileMapping(Process,
24512458
Address,
24522459
SwapEntry);
@@ -2458,6 +2465,14 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
24582465
}
24592466
else
24602467
{
2468+
#if (_MI_PAGING_LEVELS == 2)
2469+
/* We keep the pagefile index global to the segment, not in the PTE */
2470+
if(Address < MmSystemRangeStart)
2471+
{
2472+
Process->Vm.VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)]--;
2473+
ASSERT(Process->Vm.VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)] < PTE_COUNT);
2474+
}
2475+
#endif
24612476
Entry = MAKE_SWAP_SSE(SwapEntry);
24622477
MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, Entry);
24632478
}

0 commit comments

Comments
 (0)