mirror of
https://github.com/reactos/reactos.git
synced 2024-07-27 06:40:45 +00:00
- Fixed the handling for page file backed sections.
svn path=/trunk/; revision=5121
This commit is contained in:
parent
9789c326b0
commit
3364b9cc5f
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue