- Fixed the handling for page file backed sections.

svn path=/trunk/; revision=5121
This commit is contained in:
Hartmut Birr 2003-07-14 20:14:11 +00:00
parent 9789c326b0
commit 3364b9cc5f

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: section.c,v 1.122 2003/07/12 01:55:50 dwelch Exp $ /* $Id: section.c,v 1.123 2003/07/14 20:14:11 hbirr Exp $
* *
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/section.c * FILE: ntoskrnl/mm/section.c
@ -279,8 +279,7 @@ MmUnsharePageEntrySectionSegment(PSECTION_OBJECT Section,
FileOffset = Offset + Segment->FileOffset; FileOffset = Offset + Segment->FileOffset;
IsImageSection = Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE; IsImageSection = Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE;
MmSetPageEntrySectionSegment(Segment, Offset, 0);
Page = (PHYSICAL_ADDRESS)(LONGLONG)PAGE_FROM_SSE(Entry); Page = (PHYSICAL_ADDRESS)(LONGLONG)PAGE_FROM_SSE(Entry);
FileObject = Section->FileObject; FileObject = Section->FileObject;
if (FileObject != NULL) if (FileObject != NULL)
@ -302,10 +301,37 @@ MmUnsharePageEntrySectionSegment(PSECTION_OBJECT Section,
} }
SavedSwapEntry = MmGetSavedSwapEntryPage(Page); SavedSwapEntry = MmGetSavedSwapEntryPage(Page);
if (SavedSwapEntry != 0) if (SavedSwapEntry == 0)
{
if (Segment->Flags & MM_PAGEFILE_SEGMENT)
{
/*
* FIXME:
* Try to page out this page and set the swap entry
* within the section segment. There exist no rmap entry
* for this page. The pager thread can't page out a
* page without a rmap entry.
*/
MmSetPageEntrySectionSegment(Segment, Offset, Entry);
MmReferencePage(Page);
}
else
{
MmSetPageEntrySectionSegment(Segment, Offset, 0);
}
}
else
{ {
MmFreeSwapPage(SavedSwapEntry);
MmSetSavedSwapEntryPage(Page, 0); MmSetSavedSwapEntryPage(Page, 0);
if (Segment->Flags & MM_PAGEFILE_SEGMENT)
{
MmSetPageEntrySectionSegment(Segment, Offset, MAKE_SWAP_SSE(SavedSwapEntry));
}
else
{
MmSetPageEntrySectionSegment(Segment, Offset, 0);
MmFreeSwapPage(SavedSwapEntry);
}
} }
} }
else else
@ -689,9 +715,19 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
SWAPENTRY SwapEntry; SWAPENTRY SwapEntry;
PMDL Mdl; PMDL Mdl;
/*
* Sanity check
*/
if (Segment->Flags & MM_PAGEFILE_SEGMENT)
{
DPRINT1("Found a swaped out private page in a pagefile section.\n");
KeBugCheck(0);
}
MmUnlockSectionSegment(Segment); MmUnlockSectionSegment(Segment);
MmDeletePageFileMapping(AddressSpace->Process, (PVOID)PAddress, &SwapEntry); MmDeletePageFileMapping(AddressSpace->Process, (PVOID)PAddress, &SwapEntry);
MmUnlockAddressSpace(AddressSpace);
Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page); Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -700,7 +736,6 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
Mdl = MmCreateMdl(NULL, NULL, PAGE_SIZE); Mdl = MmCreateMdl(NULL, NULL, PAGE_SIZE);
MmBuildMdlFromPages(Mdl, (PULONG)&Page); MmBuildMdlFromPages(Mdl, (PULONG)&Page);
MmUnlockAddressSpace(AddressSpace);
Status = MmReadFromSwapPage(SwapEntry, Mdl); Status = MmReadFromSwapPage(SwapEntry, Mdl);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -923,9 +958,8 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
* Mark the offset within the section as having valid, in-memory * Mark the offset within the section as having valid, in-memory
* data * data
*/ */
Entry = Page.u.LowPart; Entry = MAKE_SSE(Page.u.LowPart, 1);
MmSetPageEntrySectionSegment(Segment, Offset, Entry); MmSetPageEntrySectionSegment(Segment, Offset, Entry);
MmSharePageEntrySectionSegment(Segment, Offset);
MmUnlockSectionSegment(Segment); MmUnlockSectionSegment(Segment);
Status = MmCreateVirtualMapping(AddressSpace->Process, Status = MmCreateVirtualMapping(AddressSpace->Process,
@ -1009,9 +1043,8 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
* Mark the offset within the section as having valid, in-memory * Mark the offset within the section as having valid, in-memory
* data * data
*/ */
Entry = Page.u.LowPart; Entry = MAKE_SSE(Page.u.LowPart, 1);
MmSetPageEntrySectionSegment(Segment, Offset, Entry); MmSetPageEntrySectionSegment(Segment, Offset, Entry);
MmSharePageEntrySectionSegment(Segment, Offset);
MmUnlockSectionSegment(Segment); MmUnlockSectionSegment(Segment);
/* /*
@ -1407,7 +1440,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
/* /*
* Paging out data mapped read-only is easy. * Paging out data mapped read-only is easy.
*/ */
if (Context.Segment->Protection & (PAGE_READONLY|PAGE_EXECUTE_READ)) if (Context.Segment->Protection & (PAGE_READONLY|PAGE_EXECUTE_READ))
{ {
/* /*
* Read-only data should never be in the swapfile. * Read-only data should never be in the swapfile.
@ -1474,15 +1507,24 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
*/ */
if (!Context.Private && MmGetPageEntrySectionSegment(Context.Segment, Context.Offset) != 0) if (!Context.Private && MmGetPageEntrySectionSegment(Context.Segment, Context.Offset) != 0)
{ {
KeBugCheck(0); if (!(Context.Segment->Flags & MM_PAGEFILE_SEGMENT))
{
CHECKPOINT1;
KeBugCheck(0);
}
} }
/* /*
* If the page wasn't dirty then we can just free it as for a readonly page. * If the page wasn't dirty then we can just free it as for a readonly page.
* Since we unmapped all the mappings above we know it will not suddenly * Since we unmapped all the mappings above we know it will not suddenly
* become dirty. * become dirty.
* If the page is from a pagefile section and has no swap entry,
* we can't free the page at this point.
*/ */
if (!Context.WasDirty) SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress);
if (!Context.WasDirty &&
!(SwapEntry == 0 && Context.Segment->Flags & MM_PAGEFILE_SEGMENT))
{ {
if (Context.Private) if (Context.Private)
{ {
@ -1549,7 +1591,6 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
/* /*
* If necessary, allocate an entry in the paging file for this page * If necessary, allocate an entry in the paging file for this page
*/ */
SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress);
if (SwapEntry == 0) if (SwapEntry == 0)
{ {
SwapEntry = MmAllocSwapPage(); SwapEntry = MmAllocSwapPage();
@ -1588,14 +1629,13 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
MmInsertRmap(PhysicalAddress, MmInsertRmap(PhysicalAddress,
MemoryArea->Process, MemoryArea->Process,
Address); Address);
MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, Entry = MAKE_SSE(PhysicalAddress.u.LowPart, 1);
PhysicalAddress.u.LowPart); MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, Entry);
MmSharePageEntrySectionSegment(Context.Segment, Context.Offset);
} }
PageOp->Status = STATUS_UNSUCCESSFUL; PageOp->Status = STATUS_UNSUCCESSFUL;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
MmReleasePageOp(PageOp); MmReleasePageOp(PageOp);
return(STATUS_PAGEFILE_QUOTA); return(STATUS_PAGEFILE_QUOTA);
} }
} }
@ -1636,9 +1676,8 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
MmInsertRmap(PhysicalAddress, MmInsertRmap(PhysicalAddress,
MemoryArea->Process, MemoryArea->Process,
Address); Address);
MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, Entry = MAKE_SSE(PhysicalAddress.u.LowPart, 1);
PhysicalAddress.u.LowPart); MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, Entry);
MmSharePageEntrySectionSegment(Context.Segment, Context.Offset);
} }
PageOp->Status = STATUS_UNSUCCESSFUL; PageOp->Status = STATUS_UNSUCCESSFUL;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
@ -1787,7 +1826,6 @@ MmWritePageSectionView(PMADDRESS_SPACE AddressSpace,
/* /*
* If necessary, allocate an entry in the paging file for this page * If necessary, allocate an entry in the paging file for this page
*/ */
SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress);
if (SwapEntry == 0) if (SwapEntry == 0)
{ {
SwapEntry = MmAllocSwapPage(); SwapEntry = MmAllocSwapPage();
@ -1984,6 +2022,30 @@ MmpDeleteSection(PVOID ObjectBody)
if (Section->Segment->Flags & MM_PAGEFILE_SEGMENT) if (Section->Segment->Flags & MM_PAGEFILE_SEGMENT)
{ {
ULONG Offset;
ULONG Length;
ULONG Entry;
PMM_SECTION_SEGMENT Segment;
Segment = Section->Segment;
Length = PAGE_ROUND_UP(Segment->Length);
for (Offset = 0; Offset < Length; Offset += PAGE_SIZE)
{
Entry = MmGetPageEntrySectionSegment(Segment, Offset);
if (Entry)
{
if (IS_SWAP_FROM_SSE(Entry))
{
MmFreeSwapPage(SWAPENTRY_FROM_SSE(Entry));
}
else
{
PHYSICAL_ADDRESS Page = (PHYSICAL_ADDRESS)(LONGLONG)PAGE_FROM_SSE(Entry);
MmReleasePageMemoryConsumer(MC_USER, Page);
}
}
}
MmFreePageTablesSectionSegment(Section->Segment); MmFreePageTablesSectionSegment(Section->Segment);
ExFreePool(Section->Segment); ExFreePool(Section->Segment);
} }
@ -3149,6 +3211,14 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
if (SwapEntry != 0) if (SwapEntry != 0)
{ {
/*
* Sanity check
*/
if (Segment->Flags & MM_PAGEFILE_SEGMENT)
{
DPRINT1("Found a swap entry for a page in a pagefile section.\n");
KeBugCheck(0);
}
MmFreeSwapPage(SwapEntry); MmFreeSwapPage(SwapEntry);
} }
else if (PhysAddr.QuadPart != 0) else if (PhysAddr.QuadPart != 0)
@ -3156,6 +3226,14 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
if (IS_SWAP_FROM_SSE(Entry) || if (IS_SWAP_FROM_SSE(Entry) ||
PhysAddr.QuadPart != (PAGE_FROM_SSE(Entry))) PhysAddr.QuadPart != (PAGE_FROM_SSE(Entry)))
{ {
/*
* Sanity check
*/
if (Segment->Flags & MM_PAGEFILE_SEGMENT)
{
DPRINT1("Found a private page in a pagefile section.\n");
KeBugCheck(0);
}
/* /*
* Just dereference private pages * Just dereference private pages
*/ */