mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
[NTOS:MM][NTOS:CC] Rewrite some cache memory management functions (#7510)
Use section object pointer with byte offset instead of using base address. This simplifies the Mm functions themselves and also the code in Cc that calls them. Also add minor fixes for MmFlushSegment and MmPurgeSegment.
This commit is contained in:
parent
541cb0d9b2
commit
69bf140506
5 changed files with 138 additions and 24 deletions
|
@ -653,7 +653,9 @@ CcCopyWrite (
|
||||||
CurrentOffset += VacbLength;
|
CurrentOffset += VacbLength;
|
||||||
|
|
||||||
/* Tell Mm */
|
/* Tell Mm */
|
||||||
Status = MmMakePagesDirty(NULL, Add2Ptr(Vacb->BaseAddress, VacbOffset), VacbLength);
|
Status = MmMakeSegmentDirty(FileObject->SectionObjectPointer,
|
||||||
|
Vacb->FileOffset.QuadPart + VacbOffset,
|
||||||
|
VacbLength);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
ExRaiseStatus(Status);
|
ExRaiseStatus(Status);
|
||||||
}
|
}
|
||||||
|
@ -913,7 +915,9 @@ CcZeroData (
|
||||||
Length -= VacbLength;
|
Length -= VacbLength;
|
||||||
|
|
||||||
/* Tell Mm */
|
/* Tell Mm */
|
||||||
Status = MmMakePagesDirty(NULL, Add2Ptr(Vacb->BaseAddress, VacbOffset), VacbLength);
|
Status = MmMakeSegmentDirty(FileObject->SectionObjectPointer,
|
||||||
|
Vacb->FileOffset.QuadPart + VacbOffset,
|
||||||
|
VacbLength);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
ExRaiseStatus(Status);
|
ExRaiseStatus(Status);
|
||||||
}
|
}
|
||||||
|
|
|
@ -551,17 +551,18 @@ CcSetDirtyPinnedData (
|
||||||
IN PLARGE_INTEGER Lsn)
|
IN PLARGE_INTEGER Lsn)
|
||||||
{
|
{
|
||||||
PINTERNAL_BCB iBcb = CONTAINING_RECORD(Bcb, INTERNAL_BCB, PFCB);
|
PINTERNAL_BCB iBcb = CONTAINING_RECORD(Bcb, INTERNAL_BCB, PFCB);
|
||||||
|
PROS_VACB Vacb = iBcb->Vacb;
|
||||||
|
|
||||||
CCTRACE(CC_API_DEBUG, "Bcb=%p Lsn=%p\n", Bcb, Lsn);
|
CCTRACE(CC_API_DEBUG, "Bcb=%p Lsn=%p\n", Bcb, Lsn);
|
||||||
|
|
||||||
/* Tell Mm */
|
/* Tell Mm */
|
||||||
MmMakePagesDirty(NULL,
|
MmMakeSegmentDirty(Vacb->SharedCacheMap->FileObject->SectionObjectPointer,
|
||||||
Add2Ptr(iBcb->Vacb->BaseAddress, iBcb->PFCB.MappedFileOffset.QuadPart - iBcb->Vacb->FileOffset.QuadPart),
|
iBcb->PFCB.MappedFileOffset.QuadPart,
|
||||||
iBcb->PFCB.MappedLength);
|
iBcb->PFCB.MappedLength);
|
||||||
|
|
||||||
if (!iBcb->Vacb->Dirty)
|
if (!Vacb->Dirty)
|
||||||
{
|
{
|
||||||
CcRosMarkDirtyVacb(iBcb->Vacb);
|
CcRosMarkDirtyVacb(Vacb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -936,22 +936,22 @@ CcRosEnsureVacbResident(
|
||||||
_In_ ULONG Length
|
_In_ ULONG Length
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
PVOID BaseAddress;
|
PROS_SHARED_CACHE_MAP SharedCacheMap = Vacb->SharedCacheMap;
|
||||||
|
|
||||||
ASSERT((Offset + Length) <= VACB_MAPPING_GRANULARITY);
|
ASSERT((Offset + Length) <= VACB_MAPPING_GRANULARITY);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if ((Vacb->FileOffset.QuadPart + Offset) > Vacb->SharedCacheMap->SectionSize.QuadPart)
|
if ((Vacb->FileOffset.QuadPart + Offset) > SharedCacheMap->SectionSize.QuadPart)
|
||||||
{
|
{
|
||||||
DPRINT1("Vacb read beyond the file size!\n");
|
DPRINT1("Vacb read beyond the file size!\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
BaseAddress = (PVOID)((ULONG_PTR)Vacb->BaseAddress + Offset);
|
|
||||||
|
|
||||||
/* Check if the pages are resident */
|
/* Check if the pages are resident */
|
||||||
if (!MmArePagesResident(NULL, BaseAddress, Length))
|
if (!MmIsDataSectionResident(SharedCacheMap->FileObject->SectionObjectPointer,
|
||||||
|
Vacb->FileOffset.QuadPart + Offset,
|
||||||
|
Length))
|
||||||
{
|
{
|
||||||
if (!Wait)
|
if (!Wait)
|
||||||
{
|
{
|
||||||
|
@ -960,7 +960,6 @@ CcRosEnsureVacbResident(
|
||||||
|
|
||||||
if (!NoRead)
|
if (!NoRead)
|
||||||
{
|
{
|
||||||
PROS_SHARED_CACHE_MAP SharedCacheMap = Vacb->SharedCacheMap;
|
|
||||||
NTSTATUS Status = MmMakeDataSectionResident(SharedCacheMap->FileObject->SectionObjectPointer,
|
NTSTATUS Status = MmMakeDataSectionResident(SharedCacheMap->FileObject->SectionObjectPointer,
|
||||||
Vacb->FileOffset.QuadPart + Offset,
|
Vacb->FileOffset.QuadPart + Offset,
|
||||||
Length,
|
Length,
|
||||||
|
|
|
@ -1502,16 +1502,16 @@ MmMapViewInSystemSpaceEx(
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
MmArePagesResident(
|
MmIsDataSectionResident(
|
||||||
_In_ PEPROCESS Process,
|
_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer,
|
||||||
_In_ PVOID BaseAddress,
|
_In_ LONGLONG Offset,
|
||||||
_In_ ULONG Length);
|
_In_ ULONG Length);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
MmMakePagesDirty(
|
MmMakeSegmentDirty(
|
||||||
_In_ PEPROCESS Process,
|
_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer,
|
||||||
_In_ PVOID Address,
|
_In_ LONGLONG Offset,
|
||||||
_In_ ULONG Length);
|
_In_ ULONG Length);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
|
@ -4775,10 +4775,13 @@ MmCreateSection (OUT PVOID * Section,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This function is not used. It is left for future use, when per-process
|
||||||
|
* address space is considered. */
|
||||||
|
#if 0
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
MmArePagesResident(
|
MmArePagesResident(
|
||||||
_In_ PEPROCESS Process,
|
_In_opt_ PEPROCESS Process,
|
||||||
_In_ PVOID Address,
|
_In_ PVOID Address,
|
||||||
_In_ ULONG Length)
|
_In_ ULONG Length)
|
||||||
{
|
{
|
||||||
|
@ -4826,6 +4829,7 @@ MmArePagesResident(
|
||||||
MmUnlockAddressSpace(AddressSpace);
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
return Ret;
|
return Ret;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Like CcPurgeCache but for the in-memory segment */
|
/* Like CcPurgeCache but for the in-memory segment */
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
|
@ -4859,9 +4863,9 @@ MmPurgeSegment(
|
||||||
/* We must calculate the length for ourselves */
|
/* We must calculate the length for ourselves */
|
||||||
/* FIXME: All of this is suboptimal */
|
/* FIXME: All of this is suboptimal */
|
||||||
ULONG ElemCount = RtlNumberGenericTableElements(&Segment->PageTable);
|
ULONG ElemCount = RtlNumberGenericTableElements(&Segment->PageTable);
|
||||||
/* No page. Nothing to purge */
|
|
||||||
if (!ElemCount)
|
if (!ElemCount)
|
||||||
{
|
{
|
||||||
|
/* No page. Nothing to purge */
|
||||||
MmUnlockSectionSegment(Segment);
|
MmUnlockSectionSegment(Segment);
|
||||||
MmDereferenceSegment(Segment);
|
MmDereferenceSegment(Segment);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -4871,6 +4875,9 @@ MmPurgeSegment(
|
||||||
PurgeEnd.QuadPart = PageTable->FileOffset.QuadPart + _countof(PageTable->PageEntries) * PAGE_SIZE;
|
PurgeEnd.QuadPart = PageTable->FileOffset.QuadPart + _countof(PageTable->PageEntries) * PAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Find byte offset of the page to start */
|
||||||
|
PurgeStart.QuadPart = PAGE_ROUND_DOWN(PurgeStart.QuadPart);
|
||||||
|
|
||||||
while (PurgeStart.QuadPart < PurgeEnd.QuadPart)
|
while (PurgeStart.QuadPart < PurgeEnd.QuadPart)
|
||||||
{
|
{
|
||||||
ULONG_PTR Entry = MmGetPageEntrySectionSegment(Segment, &PurgeStart);
|
ULONG_PTR Entry = MmGetPageEntrySectionSegment(Segment, &PurgeStart);
|
||||||
|
@ -4920,6 +4927,48 @@ MmPurgeSegment(
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
MmIsDataSectionResident(
|
||||||
|
_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer,
|
||||||
|
_In_ LONGLONG Offset,
|
||||||
|
_In_ ULONG Length)
|
||||||
|
{
|
||||||
|
PMM_SECTION_SEGMENT Segment;
|
||||||
|
LARGE_INTEGER RangeStart, RangeEnd;
|
||||||
|
BOOLEAN Ret = TRUE;
|
||||||
|
|
||||||
|
RangeStart.QuadPart = Offset;
|
||||||
|
if (!NT_SUCCESS(RtlLongLongAdd(RangeStart.QuadPart, Length, &RangeEnd.QuadPart)))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
Segment = MiGrabDataSection(SectionObjectPointer);
|
||||||
|
if (!Segment)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Find byte offset of the page to start */
|
||||||
|
RangeStart.QuadPart = PAGE_ROUND_DOWN(RangeStart.QuadPart);
|
||||||
|
|
||||||
|
MmLockSectionSegment(Segment);
|
||||||
|
|
||||||
|
while (RangeStart.QuadPart < RangeEnd.QuadPart)
|
||||||
|
{
|
||||||
|
ULONG_PTR Entry = MmGetPageEntrySectionSegment(Segment, &RangeStart);
|
||||||
|
if ((Entry == 0) || IS_SWAP_FROM_SSE(Entry))
|
||||||
|
{
|
||||||
|
Ret = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
RangeStart.QuadPart += PAGE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
MmUnlockSectionSegment(Segment);
|
||||||
|
MmDereferenceSegment(Segment);
|
||||||
|
|
||||||
|
return Ret;
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
MmMakeDataSectionResident(
|
MmMakeDataSectionResident(
|
||||||
|
@ -4940,6 +4989,63 @@ MmMakeDataSectionResident(
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
MmMakeSegmentDirty(
|
||||||
|
_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer,
|
||||||
|
_In_ LONGLONG Offset,
|
||||||
|
_In_ ULONG Length)
|
||||||
|
{
|
||||||
|
PMM_SECTION_SEGMENT Segment;
|
||||||
|
LARGE_INTEGER RangeStart, RangeEnd;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
RangeStart.QuadPart = Offset;
|
||||||
|
Status = RtlLongLongAdd(RangeStart.QuadPart, Length, &RangeEnd.QuadPart);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
Segment = MiGrabDataSection(SectionObjectPointer);
|
||||||
|
if (!Segment)
|
||||||
|
return STATUS_NOT_MAPPED_VIEW;
|
||||||
|
|
||||||
|
/* Find byte offset of the page to start */
|
||||||
|
RangeStart.QuadPart = PAGE_ROUND_DOWN(RangeStart.QuadPart);
|
||||||
|
|
||||||
|
MmLockSectionSegment(Segment);
|
||||||
|
|
||||||
|
while (RangeStart.QuadPart < RangeEnd.QuadPart)
|
||||||
|
{
|
||||||
|
ULONG_PTR Entry = MmGetPageEntrySectionSegment(Segment, &RangeStart);
|
||||||
|
|
||||||
|
/* Let any pending read proceed */
|
||||||
|
while (MM_IS_WAIT_PTE(Entry))
|
||||||
|
{
|
||||||
|
MmUnlockSectionSegment(Segment);
|
||||||
|
KeDelayExecutionThread(KernelMode, FALSE, &TinyTime);
|
||||||
|
MmLockSectionSegment(Segment);
|
||||||
|
Entry = MmGetPageEntrySectionSegment(Segment, &RangeStart);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We are called from Cc, this can't be backed by the page files */
|
||||||
|
ASSERT(!IS_SWAP_FROM_SSE(Entry));
|
||||||
|
|
||||||
|
/* If there is no page there, there is nothing to make dirty */
|
||||||
|
if (Entry != 0)
|
||||||
|
{
|
||||||
|
/* Dirtify the entry */
|
||||||
|
MmSetPageEntrySectionSegment(Segment, &RangeStart, DIRTY_SSE(Entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
RangeStart.QuadPart += PAGE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
MmUnlockSectionSegment(Segment);
|
||||||
|
MmDereferenceSegment(Segment);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
MmFlushSegment(
|
MmFlushSegment(
|
||||||
|
@ -4991,8 +5097,8 @@ MmFlushSegment(
|
||||||
FlushEnd.QuadPart = PageTable->FileOffset.QuadPart + _countof(PageTable->PageEntries) * PAGE_SIZE;
|
FlushEnd.QuadPart = PageTable->FileOffset.QuadPart + _countof(PageTable->PageEntries) * PAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
FlushStart.QuadPart >>= PAGE_SHIFT;
|
/* Find byte offset of the page to start */
|
||||||
FlushStart.QuadPart <<= PAGE_SHIFT;
|
FlushStart.QuadPart = PAGE_ROUND_DOWN(FlushStart.QuadPart);
|
||||||
|
|
||||||
while (FlushStart.QuadPart < FlushEnd.QuadPart)
|
while (FlushStart.QuadPart < FlushEnd.QuadPart)
|
||||||
{
|
{
|
||||||
|
@ -5197,10 +5303,13 @@ MmCheckDirtySegment(
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This function is not used. It is left for future use, when per-process
|
||||||
|
* address space is considered. */
|
||||||
|
#if 0
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
MmMakePagesDirty(
|
MmMakePagesDirty(
|
||||||
_In_ PEPROCESS Process,
|
_In_opt_ PEPROCESS Process,
|
||||||
_In_ PVOID Address,
|
_In_ PVOID Address,
|
||||||
_In_ ULONG Length)
|
_In_ ULONG Length)
|
||||||
{
|
{
|
||||||
|
@ -5267,6 +5376,7 @@ MmMakePagesDirty(
|
||||||
MmUnlockAddressSpace(AddressSpace);
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
|
|
Loading…
Reference in a new issue