mirror of
https://github.com/reactos/reactos.git
synced 2025-06-03 00:10:39 +00:00
[NTOS/MM]
- Call the right delete routine for ARM3 section object - Properly free the pages of pagefile-backed segments when those are deleted - Put the right assert at the right place in MmUnlinkPageFromList - Remove DPRINT from previous commit which is interesting but noisy svn path=/trunk/; revision=63822
This commit is contained in:
parent
9aec0d47eb
commit
9b201b7180
6 changed files with 105 additions and 12 deletions
|
@ -2274,6 +2274,12 @@ MiLocateSubsection(
|
|||
IN ULONG_PTR Vpn
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
MiDeleteARM3Section(
|
||||
PVOID ObjectBody
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
MiQueryMemorySectionName(
|
||||
|
|
|
@ -338,10 +338,11 @@ MiUnlinkPageFromList(IN PMMPFN Pfn)
|
|||
|
||||
/* We are not on a list anymore */
|
||||
Pfn->u1.Flink = Pfn->u2.Blink = 0;
|
||||
ASSERT_LIST_INVARIANT(ListHead);
|
||||
|
||||
/* Remove one entry from the list */
|
||||
ListHead->Total--;
|
||||
|
||||
ASSERT_LIST_INVARIANT(ListHead);
|
||||
}
|
||||
|
||||
PFN_NUMBER
|
||||
|
@ -1234,6 +1235,9 @@ MiDecrementShareCount(IN PMMPFN Pfn1,
|
|||
0);
|
||||
}
|
||||
|
||||
/* Page should at least have one reference */
|
||||
ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
|
||||
|
||||
/* Check if the share count is now 0 */
|
||||
ASSERT(Pfn1->u2.ShareCount < 0xF000000);
|
||||
if (!--Pfn1->u2.ShareCount)
|
||||
|
@ -1257,7 +1261,7 @@ MiDecrementShareCount(IN PMMPFN Pfn1,
|
|||
TempPte.u.Soft.Prototype = 0;
|
||||
TempPte.u.Soft.Protection = Pfn1->OriginalPte.u.Soft.Protection;
|
||||
MI_WRITE_INVALID_PTE(PointerPte, TempPte);
|
||||
DPRINT("Marking PTE: %p as transition (%p - %lx)\n", PointerPte, Pfn1, MiGetPfnEntryIndex(Pfn1));
|
||||
DPRINT1("Marking PTE: %p as transition (%p - %lx)\n", PointerPte, Pfn1, MiGetPfnEntryIndex(Pfn1));
|
||||
}
|
||||
|
||||
/* Put the page in transition */
|
||||
|
@ -1266,8 +1270,6 @@ MiDecrementShareCount(IN PMMPFN Pfn1,
|
|||
/* PFN lock must be held */
|
||||
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
|
||||
|
||||
/* Page should at least have one reference */
|
||||
ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
|
||||
if (Pfn1->u3.e2.ReferenceCount == 1)
|
||||
{
|
||||
/* Is there still a PFN for this page? */
|
||||
|
|
|
@ -608,6 +608,8 @@ MiSegmentDelete(IN PSEGMENT Segment)
|
|||
SEGMENT_FLAGS SegmentFlags;
|
||||
PSUBSECTION Subsection;
|
||||
PMMPTE PointerPte, LastPte, PteForProto;
|
||||
PMMPFN Pfn1;
|
||||
PFN_NUMBER PageFrameIndex;
|
||||
MMPTE TempPte;
|
||||
KIRQL OldIrql;
|
||||
|
||||
|
@ -621,7 +623,7 @@ MiSegmentDelete(IN PSEGMENT Segment)
|
|||
|
||||
/* These things are not supported yet */
|
||||
ASSERT(ControlArea->DereferenceList.Flink == NULL);
|
||||
ASSERT(!(ControlArea->u.Flags.Image) & !(ControlArea->u.Flags.File));
|
||||
ASSERT(!(ControlArea->u.Flags.Image) && !(ControlArea->u.Flags.File));
|
||||
ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
|
||||
ASSERT(ControlArea->u.Flags.Rom == 0);
|
||||
|
||||
|
@ -661,7 +663,52 @@ MiSegmentDelete(IN PSEGMENT Segment)
|
|||
TempPte = *PointerPte;
|
||||
ASSERT(SegmentFlags.LargePages == 0);
|
||||
ASSERT(TempPte.u.Hard.Valid == 0);
|
||||
ASSERT(TempPte.u.Soft.Prototype == 1);
|
||||
|
||||
/* See if we should clean things up */
|
||||
if (!(ControlArea->u.Flags.Image) && !(ControlArea->u.Flags.File))
|
||||
{
|
||||
/*
|
||||
* This is a section backed by the pagefile. Now that it doesn't exist anymore,
|
||||
* we can give everything back to the system.
|
||||
*/
|
||||
ASSERT(TempPte.u.Soft.Prototype == 0);
|
||||
|
||||
if (TempPte.u.Soft.Transition == 1)
|
||||
{
|
||||
/* We can give the page back for other use */
|
||||
DPRINT1("Releasing page for transition PTE %p\n", PointerPte);
|
||||
PageFrameIndex = PFN_FROM_PTE(&TempPte);
|
||||
Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
|
||||
|
||||
/* As this is a paged-backed section, nobody should reference it anymore (no cache or whatever) */
|
||||
ASSERT(Pfn1->u3.ReferenceCount == 0);
|
||||
|
||||
/* And it should be in standby or modified list */
|
||||
ASSERT((Pfn1->u3.e1.PageLocation == ModifiedPageList) || (Pfn1->u3.e1.PageLocation == StandbyPageList));
|
||||
|
||||
/* Unlink it and put it back in free list */
|
||||
MiUnlinkPageFromList(Pfn1);
|
||||
|
||||
/* Temporarily mark this as active and make it free again */
|
||||
Pfn1->u3.e1.PageLocation = ActiveAndValid;
|
||||
MI_SET_PFN_DELETED(Pfn1);
|
||||
|
||||
MiInsertPageInFreeList(PageFrameIndex);
|
||||
}
|
||||
else if (TempPte.u.Soft.PageFileHigh != 0)
|
||||
{
|
||||
/* Should not happen for now */
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* unsupported for now */
|
||||
ASSERT(FALSE);
|
||||
|
||||
/* File-backed section must have prototype PTEs */
|
||||
ASSERT(TempPte.u.Soft.Prototype == 1);
|
||||
}
|
||||
|
||||
/* Zero the PTE and keep going */
|
||||
PointerPte->u.Long = 0;
|
||||
|
@ -3050,6 +3097,34 @@ MmCommitSessionMappedView(IN PVOID MappedBase,
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
MiDeleteARM3Section(PVOID ObjectBody)
|
||||
{
|
||||
PSECTION SectionObject;
|
||||
PCONTROL_AREA ControlArea;
|
||||
KIRQL OldIrql;
|
||||
|
||||
SectionObject = (PSECTION)ObjectBody;
|
||||
|
||||
/* Lock the PFN database */
|
||||
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
|
||||
|
||||
ASSERT(SectionObject->Segment);
|
||||
ASSERT(SectionObject->Segment->ControlArea);
|
||||
|
||||
ControlArea = SectionObject->Segment->ControlArea;
|
||||
|
||||
/* Dereference */
|
||||
ControlArea->NumberOfSectionReferences--;
|
||||
ControlArea->NumberOfUserReferences--;
|
||||
|
||||
ASSERT(ControlArea->u.Flags.BeingDeleted == 0);
|
||||
|
||||
/* Check it. It will delete it if there is no more reference to it */
|
||||
MiCheckControlArea(ControlArea, OldIrql);
|
||||
}
|
||||
|
||||
/* SYSTEM CALLS ***************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
|
|
|
@ -423,10 +423,18 @@ MiDeletePte(IN PMMPTE PointerPte,
|
|||
/* Drop the reference on the page table. */
|
||||
MiDecrementShareCount(MiGetPfnEntry(Pfn1->u4.PteFrame), Pfn1->u4.PteFrame);
|
||||
|
||||
ASSERT(Pfn1->u3.e1.PrototypePte == 0);
|
||||
|
||||
/* Make the page free. For prototypes, it will be made free when deleting the section object */
|
||||
if (Pfn1->u2.ShareCount == 0)
|
||||
{
|
||||
NT_ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
|
||||
/* Mark the page temporarily as valid, we're going to make it free soon */
|
||||
|
||||
/* And it should be in standby or modified list */
|
||||
ASSERT((Pfn1->u3.e1.PageLocation == ModifiedPageList) || (Pfn1->u3.e1.PageLocation == StandbyPageList));
|
||||
|
||||
/* Unlink it and put it back in free list */
|
||||
MiUnlinkPageFromList(Pfn1);
|
||||
Pfn1->u3.e1.PageLocation = ActiveAndValid;
|
||||
|
||||
/* Bring it back into the free list */
|
||||
|
|
|
@ -356,8 +356,6 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait,
|
|||
}
|
||||
|
||||
|
||||
extern MMPFNLIST MmModifiedPageListByColor[];
|
||||
|
||||
VOID NTAPI
|
||||
MiBalancerThread(PVOID Unused)
|
||||
{
|
||||
|
@ -427,9 +425,6 @@ MiBalancerThread(PVOID Unused)
|
|||
KeBugCheck(NO_PAGES_AVAILABLE);
|
||||
}
|
||||
} while (InitialTarget != 0);
|
||||
|
||||
if (MmModifiedPageListByColor[0].Total != 0)
|
||||
DPRINT1("There are %u pages ready to be paged out in the modified list.\n", MmModifiedPageListByColor[0].Total);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -2624,6 +2624,13 @@ MmpDeleteSection(PVOID ObjectBody)
|
|||
{
|
||||
PROS_SECTION_OBJECT Section = (PROS_SECTION_OBJECT)ObjectBody;
|
||||
|
||||
/* Check if it's an ARM3, or ReactOS section */
|
||||
if (!MiIsRosSectionObject(Section))
|
||||
{
|
||||
MiDeleteARM3Section(ObjectBody);
|
||||
return;
|
||||
}
|
||||
|
||||
DPRINT("MmpDeleteSection(ObjectBody %p)\n", ObjectBody);
|
||||
if (Section->AllocationAttributes & SEC_IMAGE)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue