mirror of
https://github.com/reactos/reactos.git
synced 2025-06-10 12:24:48 +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
|
IN ULONG_PTR Vpn
|
||||||
);
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
MiDeleteARM3Section(
|
||||||
|
PVOID ObjectBody
|
||||||
|
);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
MiQueryMemorySectionName(
|
MiQueryMemorySectionName(
|
||||||
|
|
|
@ -338,10 +338,11 @@ MiUnlinkPageFromList(IN PMMPFN Pfn)
|
||||||
|
|
||||||
/* We are not on a list anymore */
|
/* We are not on a list anymore */
|
||||||
Pfn->u1.Flink = Pfn->u2.Blink = 0;
|
Pfn->u1.Flink = Pfn->u2.Blink = 0;
|
||||||
ASSERT_LIST_INVARIANT(ListHead);
|
|
||||||
|
|
||||||
/* Remove one entry from the list */
|
/* Remove one entry from the list */
|
||||||
ListHead->Total--;
|
ListHead->Total--;
|
||||||
|
|
||||||
|
ASSERT_LIST_INVARIANT(ListHead);
|
||||||
}
|
}
|
||||||
|
|
||||||
PFN_NUMBER
|
PFN_NUMBER
|
||||||
|
@ -1234,6 +1235,9 @@ MiDecrementShareCount(IN PMMPFN Pfn1,
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Page should at least have one reference */
|
||||||
|
ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
|
||||||
|
|
||||||
/* Check if the share count is now 0 */
|
/* Check if the share count is now 0 */
|
||||||
ASSERT(Pfn1->u2.ShareCount < 0xF000000);
|
ASSERT(Pfn1->u2.ShareCount < 0xF000000);
|
||||||
if (!--Pfn1->u2.ShareCount)
|
if (!--Pfn1->u2.ShareCount)
|
||||||
|
@ -1257,7 +1261,7 @@ MiDecrementShareCount(IN PMMPFN Pfn1,
|
||||||
TempPte.u.Soft.Prototype = 0;
|
TempPte.u.Soft.Prototype = 0;
|
||||||
TempPte.u.Soft.Protection = Pfn1->OriginalPte.u.Soft.Protection;
|
TempPte.u.Soft.Protection = Pfn1->OriginalPte.u.Soft.Protection;
|
||||||
MI_WRITE_INVALID_PTE(PointerPte, TempPte);
|
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 */
|
/* Put the page in transition */
|
||||||
|
@ -1266,8 +1270,6 @@ MiDecrementShareCount(IN PMMPFN Pfn1,
|
||||||
/* PFN lock must be held */
|
/* PFN lock must be held */
|
||||||
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
|
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
|
||||||
|
|
||||||
/* Page should at least have one reference */
|
|
||||||
ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
|
|
||||||
if (Pfn1->u3.e2.ReferenceCount == 1)
|
if (Pfn1->u3.e2.ReferenceCount == 1)
|
||||||
{
|
{
|
||||||
/* Is there still a PFN for this page? */
|
/* Is there still a PFN for this page? */
|
||||||
|
|
|
@ -608,6 +608,8 @@ MiSegmentDelete(IN PSEGMENT Segment)
|
||||||
SEGMENT_FLAGS SegmentFlags;
|
SEGMENT_FLAGS SegmentFlags;
|
||||||
PSUBSECTION Subsection;
|
PSUBSECTION Subsection;
|
||||||
PMMPTE PointerPte, LastPte, PteForProto;
|
PMMPTE PointerPte, LastPte, PteForProto;
|
||||||
|
PMMPFN Pfn1;
|
||||||
|
PFN_NUMBER PageFrameIndex;
|
||||||
MMPTE TempPte;
|
MMPTE TempPte;
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
|
|
||||||
|
@ -621,7 +623,7 @@ MiSegmentDelete(IN PSEGMENT Segment)
|
||||||
|
|
||||||
/* These things are not supported yet */
|
/* These things are not supported yet */
|
||||||
ASSERT(ControlArea->DereferenceList.Flink == NULL);
|
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.GlobalOnlyPerSession == 0);
|
||||||
ASSERT(ControlArea->u.Flags.Rom == 0);
|
ASSERT(ControlArea->u.Flags.Rom == 0);
|
||||||
|
|
||||||
|
@ -661,7 +663,52 @@ MiSegmentDelete(IN PSEGMENT Segment)
|
||||||
TempPte = *PointerPte;
|
TempPte = *PointerPte;
|
||||||
ASSERT(SegmentFlags.LargePages == 0);
|
ASSERT(SegmentFlags.LargePages == 0);
|
||||||
ASSERT(TempPte.u.Hard.Valid == 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 */
|
/* Zero the PTE and keep going */
|
||||||
PointerPte->u.Long = 0;
|
PointerPte->u.Long = 0;
|
||||||
|
@ -3050,6 +3097,34 @@ MmCommitSessionMappedView(IN PVOID MappedBase,
|
||||||
return STATUS_SUCCESS;
|
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 ***************************************************************/
|
/* SYSTEM CALLS ***************************************************************/
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
|
@ -423,10 +423,18 @@ MiDeletePte(IN PMMPTE PointerPte,
|
||||||
/* Drop the reference on the page table. */
|
/* Drop the reference on the page table. */
|
||||||
MiDecrementShareCount(MiGetPfnEntry(Pfn1->u4.PteFrame), Pfn1->u4.PteFrame);
|
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)
|
if (Pfn1->u2.ShareCount == 0)
|
||||||
{
|
{
|
||||||
NT_ASSERT(Pfn1->u3.e2.ReferenceCount == 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;
|
Pfn1->u3.e1.PageLocation = ActiveAndValid;
|
||||||
|
|
||||||
/* Bring it back into the free list */
|
/* Bring it back into the free list */
|
||||||
|
|
|
@ -356,8 +356,6 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extern MMPFNLIST MmModifiedPageListByColor[];
|
|
||||||
|
|
||||||
VOID NTAPI
|
VOID NTAPI
|
||||||
MiBalancerThread(PVOID Unused)
|
MiBalancerThread(PVOID Unused)
|
||||||
{
|
{
|
||||||
|
@ -427,9 +425,6 @@ MiBalancerThread(PVOID Unused)
|
||||||
KeBugCheck(NO_PAGES_AVAILABLE);
|
KeBugCheck(NO_PAGES_AVAILABLE);
|
||||||
}
|
}
|
||||||
} while (InitialTarget != 0);
|
} 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
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -2624,6 +2624,13 @@ MmpDeleteSection(PVOID ObjectBody)
|
||||||
{
|
{
|
||||||
PROS_SECTION_OBJECT Section = (PROS_SECTION_OBJECT)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);
|
DPRINT("MmpDeleteSection(ObjectBody %p)\n", ObjectBody);
|
||||||
if (Section->AllocationAttributes & SEC_IMAGE)
|
if (Section->AllocationAttributes & SEC_IMAGE)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue