Author: sir_richard
Date: Sat Mar 31 21:27:35 2012
New Revision: 56293
URL: http://svn.reactos.org/svn/reactos?rev=56293&view=rev
Log:
[NTOS]: Partly revert back to old behavior in attempt to fix regression.
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c [iso-8859-1] Sat Mar 31 21:27:35 2012
@@ -1233,6 +1233,9 @@
ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
if (Pfn1->u3.e2.ReferenceCount == 1)
{
+ /* In ReactOS, this path should always be hit with a deleted PFN */
+ ASSERT((MI_IS_PFN_DELETED(Pfn1) == TRUE) || (Pfn1->u3.e1.PrototypePte == 1));
+#if 0 // INVESTIGATE
/* Is there still a PFN for this page? */
if (MI_IS_PFN_DELETED(Pfn1) == TRUE)
{
@@ -1251,6 +1254,7 @@
/* PFN not yet deleted, drop a ref count */
MiDecrementReferenceCount(Pfn1, PageFrameIndex);
}
+#endif
/* Clear the last reference */
Pfn1->u3.e2.ReferenceCount = 0;
@@ -1306,6 +1310,7 @@
}
/* Check to see which list this page should go into */
+ ASSERT(FALSE);
if (Pfn1->u3.e1.Modified == 1)
{
/* Push it into the modified page list */
Author: sir_richard
Date: Sat Mar 31 20:16:32 2012
New Revision: 56292
URL: http://svn.reactos.org/svn/reactos?rev=56292&view=rev
Log:
[NTOS]: Add support for calling NtAllocateVirtualMemory on an ARM3 section that was SEC_RESERVEd.
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/virtual.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/virtual.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/virtual.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/virtual.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/virtual.c [iso-8859-1] Sat Mar 31 20:16:32 2012
@@ -3082,7 +3082,7 @@
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
PETHREAD CurrentThread = PsGetCurrentThread();
KAPC_STATE ApcState;
- ULONG ProtectionMask;
+ ULONG ProtectionMask, QuotaCharge = 0, QuotaFree = 0;
BOOLEAN Attached = FALSE, ChangeProtection = FALSE;
MMPTE TempPte;
PMMPTE PointerPte, PointerPde, LastPte;
@@ -3512,11 +3512,104 @@
Protect);
}
- //
- // This is a specific ReactOS check because we do not support Section VADs
+ // Is this a previously reserved section being committed? If so, enter the
+ // special section path
+ //
+ if (FoundVad->u.VadFlags.PrivateMemory == FALSE)
+ {
+ //
+ // You cannot commit large page sections through this API
+ //
+ if (FoundVad->u.VadFlags.VadType == VadLargePageSection)
+ {
+ DPRINT1("Large page sections cannot be VirtualAlloc'd\n");
+ Status = STATUS_INVALID_PAGE_PROTECTION;
+ goto FailPath;
+ }
+
+ //
+ // You can only use caching flags on a rotate VAD
+ //
+ if ((Protect & (PAGE_NOCACHE | PAGE_WRITECOMBINE)) &&
+ (FoundVad->u.VadFlags.VadType != VadRotatePhysical))
+ {
+ DPRINT1("Cannot use caching flags with anything but rotate VADs\n");
+ Status = STATUS_INVALID_PAGE_PROTECTION;
+ goto FailPath;
+ }
+
+ //
+ // We should make sure that the section's permissions aren't being messed with
+ //
+ if (FoundVad->u.VadFlags.NoChange)
+ {
+ DPRINT1("SEC_NO_CHANGE section being touched. Assuming this is ok\n");
+ }
+
+ //
+ // ARM3 does not support file-backed sections, only shared memory
+ //
+ ASSERT(FoundVad->ControlArea->FilePointer == NULL);
+
+ //
+ // Rotate VADs cannot be guard pages or inaccessible, nor copy on write
+ //
+ if ((FoundVad->u.VadFlags.VadType == VadRotatePhysical) &&
+ (Protect & (PAGE_WRITECOPY | PAGE_EXECUTE_WRITECOPY | PAGE_NOACCESS | PAGE_GUARD)))
+ {
+ DPRINT1("Invalid page protection for rotate VAD\n");
+ Status = STATUS_INVALID_PAGE_PROTECTION;
+ goto FailPath;
+ }
+
+ //
+ // Compute PTE addresses and the quota charge, then grab the commit lock
+ //
+ PointerPte = MI_GET_PROTOTYPE_PTE_FOR_VPN(FoundVad, StartingAddress >> PAGE_SHIFT);
+ LastPte = MI_GET_PROTOTYPE_PTE_FOR_VPN(FoundVad, EndingAddress >> PAGE_SHIFT);
+ QuotaCharge = LastPte - PointerPte + 1;
+ KeAcquireGuardedMutexUnsafe(&MmSectionCommitMutex);
+
+ //
+ // Get the segment template PTE and start looping each page
+ //
+ TempPte = FoundVad->ControlArea->Segment->SegmentPteTemplate;
+ ASSERT(TempPte.u.Long != 0);
+ while (PointerPte <= LastPte)
+ {
+ //
+ // For each non-already-committed page, write the invalid template PTE
+ //
+ if (PointerPte->u.Long == 0)
+ {
+ MI_WRITE_INVALID_PTE(PointerPte, TempPte);
+ }
+ else
+ {
+ QuotaFree++;
+ }
+ PointerPte++;
+ }
+
+ //
+ // Now do the commit accounting and release the lock
+ //
+ ASSERT(QuotaCharge >= QuotaFree);
+ QuotaCharge -= QuotaFree;
+ FoundVad->ControlArea->Segment->NumberOfCommittedPages += QuotaCharge;
+ KeReleaseGuardedMutexUnsafe(&MmSectionCommitMutex);
+
+ //
+ // We are done with committing the section pages
+ //
+ Status = STATUS_SUCCESS;
+ goto FailPath;
+ }
+
+ //
+ // This is a specific ReactOS check because we only use normal VADs
//
ASSERT(FoundVad->u.VadFlags.VadType == VadNone);
- ASSERT(FoundVad->u.VadFlags.PrivateMemory == TRUE);
//
// While this is an actual Windows check
Author: sir_richard
Date: Sat Mar 31 20:08:34 2012
New Revision: 56291
URL: http://svn.reactos.org/svn/reactos?rev=56291&view=rev
Log:
[NTOS]: Add initial support for standby page list and modified page list in the current page list routines. Add support for prototype PTEs in a few more cases, including handling of transition pages. Should not affect any of the current code as those lists/transition pages aren't yet used.
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c [iso-8859-1] Sat Mar 31 20:08:34 2012
@@ -723,13 +723,84 @@
#endif
}
-/* Note: This function is hardcoded only for the zeroed page list, for now */
+VOID
+FASTCALL
+MiInsertStandbyListAtFront(IN PFN_NUMBER PageFrameIndex)
+{
+ PMMPFNLIST ListHead;
+ PFN_NUMBER Flink;
+ PMMPFN Pfn1, Pfn2;
+
+ /* Make sure the lock is held */
+ DPRINT1("Inserting page: %lx into standby list !\n", PageFrameIndex);
+ ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+
+ /* Make sure the PFN is valid */
+ ASSERT((PageFrameIndex != 0) &&
+ (PageFrameIndex <= MmHighestPhysicalPage) &&
+ (PageFrameIndex >= MmLowestPhysicalPage));
+
+ /* Grab the PFN and validate it is the right kind of PFN being inserted */
+ Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
+ ASSERT(Pfn1->u4.MustBeCached == 0);
+ ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
+ ASSERT(Pfn1->u3.e1.PrototypePte == 1);
+ ASSERT(Pfn1->u3.e1.Rom != 1);
+
+ /* One more transition page on a list */
+ MmTransitionSharedPages++;
+
+ /* Get the standby page list and increment its count */
+ ListHead = &MmStandbyPageListByPriority [Pfn1->u4.Priority];
+ ASSERT_LIST_INVARIANT(ListHead);
+ ListHead->Total++;
+
+ /* Make the head of the list point to this page now */
+ Flink = ListHead->Flink;
+ ListHead->Flink = PageFrameIndex;
+
+ /* Make the page point to the previous head, and back to the list */
+ Pfn1->u1.Flink = Flink;
+ Pfn1->u2.Blink = LIST_HEAD;
+
+ /* Was the list empty? */
+ if (Flink != LIST_HEAD)
+ {
+ /* It wasn't, so update the backlink of the previous head page */
+ Pfn2 = MI_PFN_ELEMENT(Flink);
+ Pfn2->u2.Blink = PageFrameIndex;
+ }
+ else
+ {
+ /* It was empty, so have it loop back around to this new page */
+ ListHead->Blink = PageFrameIndex;
+ }
+
+ /* Move the page onto its new location */
+ Pfn1->u3.e1.PageLocation = StandbyPageList;
+
+ /* One more page on the system */
+ MmAvailablePages++;
+
+ /* Check if we've reached the configured low memory threshold */
+ if (MmAvailablePages == MmLowMemoryThreshold)
+ {
+ /* Clear the event, because now we're ABOVE the threshold */
+ KeClearEvent(MiLowMemoryEvent);
+ }
+ else if (MmAvailablePages == MmHighMemoryThreshold)
+ {
+ /* Otherwise check if we reached the high threshold and signal the event */
+ KeSetEvent(MiHighMemoryEvent, 0, FALSE);
+ }
+}
+
VOID
NTAPI
MiInsertPageInList(IN PMMPFNLIST ListHead,
IN PFN_NUMBER PageFrameIndex)
{
- PFN_NUMBER Flink;
+ PFN_NUMBER Flink, LastPage;
PMMPFN Pfn1, Pfn2;
MMLISTS ListName;
PMMCOLOR_TABLES ColorHead;
@@ -751,95 +822,181 @@
ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
ASSERT(Pfn1->u3.e1.Rom != 1);
- /* Only used for zero pages in ReactOS */
+ /* Is a standby or modified page being inserted? */
ListName = ListHead->ListName;
- ASSERT(ListName == ZeroedPageList);
+ if ((ListName == StandbyPageList) || (ListName == ModifiedPageList))
+ {
+ /* If the page is in transition, it must also be a prototype page */
+ if ((Pfn1->OriginalPte.u.Soft.Prototype == 0) &&
+ (Pfn1->OriginalPte.u.Soft.Transition == 1))
+ {
+ /* Crash the system on inconsistency */
+ KeBugCheckEx(MEMORY_MANAGEMENT, 0x8888, 0, 0, 0);
+ }
+ }
+
+ /* Standby pages are prioritized, so we need to get the real head */
+ if (ListHead == &MmStandbyPageListHead)
+ {
+ /* Obviously the prioritized list should still have the same name */
+ ListHead = &MmStandbyPageListByPriority[Pfn1->u4.Priority];
+ ASSERT(ListHead->ListName == ListName);
+ }
+
+ /* Increment the list count */
ListHead->Total++;
+
+ /* Is a modified page being inserted? */
+ if (ListHead == &MmModifiedPageListHead)
+ {
+ /* For now, only single-prototype pages should end up in this path */
+ DPRINT1("Modified page being added: %lx\n", PageFrameIndex);
+ ASSERT(Pfn1->OriginalPte.u.Soft.Prototype == 0);
+
+ /* Modified pages are colored when they are selected for page file */
+ ListHead = &MmModifiedPageListByColor[0];
+ ASSERT (ListHead->ListName == ListName);
+ ListHead->Total++;
+
+ /* Increment the number of paging file modified pages */
+ MmTotalPagesForPagingFile++;
+ }
/* Don't handle bad pages yet yet */
ASSERT(Pfn1->u3.e1.RemovalRequested == 0);
- /* Make the head of the list point to this page now */
- Flink = ListHead->Flink;
- ListHead->Flink = PageFrameIndex;
-
- /* Make the page point to the previous head, and back to the list */
- Pfn1->u1.Flink = Flink;
- Pfn1->u2.Blink = LIST_HEAD;
-
- /* Was the list empty? */
- if (Flink != LIST_HEAD)
- {
- /* It wasn't, so update the backlink of the previous head page */
- Pfn2 = MI_PFN_ELEMENT(Flink);
- Pfn2->u2.Blink = PageFrameIndex;
+ /* Zero pages go to the head, all other pages go to the end */
+ if (ListName == ZeroedPageList)
+ {
+ /* Make the head of the list point to this page now */
+ Flink = ListHead->Flink;
+ ListHead->Flink = PageFrameIndex;
+
+ /* Make the page point to the previous head, and back to the list */
+ Pfn1->u1.Flink = Flink;
+ Pfn1->u2.Blink = LIST_HEAD;
+
+ /* Was the list empty? */
+ if (Flink != LIST_HEAD)
+ {
+ /* It wasn't, so update the backlink of the previous head page */
+ Pfn2 = MI_PFN_ELEMENT(Flink);
+ Pfn2->u2.Blink = PageFrameIndex;
+ }
+ else
+ {
+ /* It was empty, so have it loop back around to this new page */
+ ListHead->Blink = PageFrameIndex;
+ }
}
else
{
- /* It was empty, so have it loop back around to this new page */
+ /* Get the last page on the list */
+ LastPage = ListHead->Blink;
+ if (LastPage != LIST_HEAD)
+ {
+ /* Link us with the previous page, so we're at the end now */
+ MI_PFN_ELEMENT(LastPage)->u1.Flink = PageFrameIndex;
+ }
+ else
+ {
+ /* The list is empty, so we are the first page */
+ ListHead->Flink = PageFrameIndex;
+ }
+
+ /* Now make the list head point back to us (since we go at the end) */
ListHead->Blink = PageFrameIndex;
+ ASSERT_LIST_INVARIANT(ListHead);
+
+ /* And initialize our own list pointers */
+ Pfn1->u1.Flink = LIST_HEAD;
+ Pfn1->u2.Blink = LastPage;
}
/* Move the page onto its new location */
Pfn1->u3.e1.PageLocation = ListName;
- /* One more page on the system */
- MmAvailablePages++;
-
- /* Check if we've reached the configured low memory threshold */
- if (MmAvailablePages == MmLowMemoryThreshold)
- {
- /* Clear the event, because now we're ABOVE the threshold */
- KeClearEvent(MiLowMemoryEvent);
- }
- else if (MmAvailablePages == MmHighMemoryThreshold)
- {
- /* Otherwise check if we reached the high threshold and signal the event */
- KeSetEvent(MiHighMemoryEvent, 0, FALSE);
- }
-
- /* Sanity checks */
- ASSERT(ListName == ZeroedPageList);
- ASSERT(Pfn1->u4.InPageError == 0);
-
- /* Get the page color */
- Color = PageFrameIndex & MmSecondaryColorMask;
-
- /* Get the list for this color */
- ColorHead = &MmFreePagesByColor[ZeroedPageList][Color];
-
- /* Get the old head */
- Flink = ColorHead->Flink;
-
- /* Make this page point back to the list, and point forwards to the old head */
- Pfn1->OriginalPte.u.Long = Flink;
- Pfn1->u4.PteFrame = COLORED_LIST_HEAD;
-
- /* Set the new head */
- ColorHead->Flink = PageFrameIndex;
-
- /* Was the head empty? */
- if (Flink != LIST_HEAD)
- {
- /* No, so make the old head point to this page */
- Pfn2 = MI_PFN_ELEMENT(Flink);
- Pfn2->u4.PteFrame = PageFrameIndex;
- }
- else
- {
- /* Yes, make it loop back to this page */
- ColorHead->Blink = (PVOID)Pfn1;
- }
-
- /* One more paged on the colored list */
- ColorHead->Count++;
+ /* For zero/free pages, we also have to handle the colored lists */
+ if (ListName <= StandbyPageList)
+ {
+ /* One more page on the system */
+ MmAvailablePages++;
+
+ /* Check if we've reached the configured low memory threshold */
+ if (MmAvailablePages == MmLowMemoryThreshold)
+ {
+ /* Clear the event, because now we're ABOVE the threshold */
+ KeClearEvent(MiLowMemoryEvent);
+ }
+ else if (MmAvailablePages == MmHighMemoryThreshold)
+ {
+ /* Otherwise check if we reached the high threshold and signal the event */
+ KeSetEvent(MiHighMemoryEvent, 0, FALSE);
+ }
+
+ /* Sanity checks */
+ ASSERT(ListName == ZeroedPageList);
+ ASSERT(Pfn1->u4.InPageError == 0);
+
+ /* Get the page color */
+ Color = PageFrameIndex & MmSecondaryColorMask;
+
+ /* Get the list for this color */
+ ColorHead = &MmFreePagesByColor[ZeroedPageList][Color];
+
+ /* Get the old head */
+ Flink = ColorHead->Flink;
+
+ /* Make this page point back to the list, and point forwards to the old head */
+ Pfn1->OriginalPte.u.Long = Flink;
+ Pfn1->u4.PteFrame = COLORED_LIST_HEAD;
+
+ /* Set the new head */
+ ColorHead->Flink = PageFrameIndex;
+
+ /* Was the head empty? */
+ if (Flink != LIST_HEAD)
+ {
+ /* No, so make the old head point to this page */
+ Pfn2 = MI_PFN_ELEMENT(Flink);
+ Pfn2->u4.PteFrame = PageFrameIndex;
+ }
+ else
+ {
+ /* Yes, make it loop back to this page */
+ ColorHead->Blink = (PVOID)Pfn1;
+ }
+
+ /* One more paged on the colored list */
+ ColorHead->Count++;
#if MI_TRACE_PFNS
- //ASSERT(MI_PFN_CURRENT_USAGE == MI_USAGE_NOT_SET);
- Pfn1->PfnUsage = MI_USAGE_FREE_PAGE;
- MI_PFN_CURRENT_USAGE = MI_USAGE_NOT_SET;
- RtlZeroMemory(Pfn1->ProcessName, 16);
+ //ASSERT(MI_PFN_CURRENT_USAGE == MI_USAGE_NOT_SET);
+ Pfn1->PfnUsage = MI_USAGE_FREE_PAGE;
+ MI_PFN_CURRENT_USAGE = MI_USAGE_NOT_SET;
+ RtlZeroMemory(Pfn1->ProcessName, 16);
#endif
+ }
+ else if (ListName == ModifiedPageList)
+ {
+ /* In ARM3, page must be destined for page file, and not yet written out */
+ ASSERT(Pfn1->OriginalPte.u.Soft.Prototype == 0);
+ ASSERT(Pfn1->OriginalPte.u.Soft.PageFileHigh == 0);
+
+ /* One more transition page */
+ ASSERT(Pfn1->u3.e1.PrototypePte == 1);
+ MmTransitionSharedPages++;
+
+ /* Increment the number of per-process modified pages */
+ PsGetCurrentProcess()->ModifiedPageCount++;
+
+ /* FIXME: Wake up modified page writer if there are not enough free pages */
+ }
+ else if (ListName == ModifiedNoWritePageList)
+ {
+ /* This list is not yet implemented */
+ ASSERT(FALSE);
+ }
}
VOID
@@ -1020,6 +1177,9 @@
MiDecrementShareCount(IN PMMPFN Pfn1,
IN PFN_NUMBER PageFrameIndex)
{
+ PMMPTE PointerPte;
+ MMPTE TempPte;
+
ASSERT(PageFrameIndex > 0);
ASSERT(MI_PFN_ELEMENT(PageFrameIndex) != NULL);
ASSERT(Pfn1 == MI_PFN_ELEMENT(PageFrameIndex));
@@ -1041,8 +1201,27 @@
ASSERT(Pfn1->u2.ShareCount < 0xF000000);
if (!--Pfn1->u2.ShareCount)
{
- /* ReactOS does not handle these */
- ASSERT(Pfn1->u3.e1.PrototypePte == 0);
+ /* Was this a prototype PTE? */
+ if (Pfn1->u3.e1.PrototypePte)
+ {
+ /* Grab the PTE address and make sure it's in prototype pool */
+ PointerPte = Pfn1->PteAddress;
+ ASSERT((PointerPte >= (PMMPTE)MmPagedPoolStart) && (PointerPte <= (PMMPTE)MmPagedPoolEnd));
+
+ /* The PTE that backs it should also be valdi */
+ PointerPte = MiAddressToPte(PointerPte);
+ ASSERT(PointerPte->u.Hard.Valid == 1);
+
+ /* Get the original prototype PTE and turn it into a transition PTE */
+ PointerPte = Pfn1->PteAddress;
+ TempPte = *PointerPte;
+ TempPte.u.Soft.Transition = 1;
+ TempPte.u.Soft.Valid = 0;
+ TempPte.u.Soft.Prototype = 0;
+ TempPte.u.Soft.Protection = Pfn1->OriginalPte.u.Soft.Protection;
+ MI_WRITE_INVALID_PTE(PointerPte, TempPte);
+ DPRINT1("Marking PTE: %p as transition (%p - %lx)\n", PointerPte, Pfn1, MiGetPfnEntryIndex(Pfn1));
+ }
/* Put the page in transition */
Pfn1->u3.e1.PageLocation = TransitionPage;
@@ -1054,8 +1233,24 @@
ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
if (Pfn1->u3.e2.ReferenceCount == 1)
{
- /* In ReactOS, this path should always be hit with a deleted PFN */
- ASSERT((MI_IS_PFN_DELETED(Pfn1) == TRUE) || (Pfn1->u3.e1.PrototypePte == 1));
+ /* Is there still a PFN for this page? */
+ if (MI_IS_PFN_DELETED(Pfn1) == TRUE)
+ {
+ /* Clear the last reference */
+ Pfn1->u3.e2.ReferenceCount = 0;
+ ASSERT(Pfn1->OriginalPte.u.Soft.Prototype == 0);
+
+ /* Mark the page temporarily as valid, we're going to make it free soon */
+ Pfn1->u3.e1.PageLocation = ActiveAndValid;
+
+ /* Bring it back into the free list */
+ MiInsertPageInFreeList(PageFrameIndex);
+ }
+ else
+ {
+ /* PFN not yet deleted, drop a ref count */
+ MiDecrementReferenceCount(Pfn1, PageFrameIndex);
+ }
/* Clear the last reference */
Pfn1->u3.e2.ReferenceCount = 0;
@@ -1110,12 +1305,18 @@
return;
}
- /* We don't have a modified list yet */
- ASSERT(Pfn1->u3.e1.Modified == 0);
- ASSERT(Pfn1->u3.e1.RemovalRequested == 0);
-
- /* FIXME: Normally it would go on the standby list, but we're pushing it on the free list */
- MiInsertPageInFreeList(PageFrameIndex);
+ /* Check to see which list this page should go into */
+ if (Pfn1->u3.e1.Modified == 1)
+ {
+ /* Push it into the modified page list */
+ MiInsertPageInList(&MmModifiedPageListHead, PageFrameIndex);
+ }
+ else
+ {
+ /* Otherwise, insert this page into the standby list */
+ ASSERT(Pfn1->u3.e1.RemovalRequested == 0);
+ MiInsertStandbyListAtFront(PageFrameIndex);
+ }
}
VOID
Author: sir_richard
Date: Sat Mar 31 20:07:29 2012
New Revision: 56290
URL: http://svn.reactos.org/svn/reactos?rev=56290&view=rev
Log:
[NTOS]: Support getting the protection mask for other kinds of VADs in NtQueryVirtualMemory, instead of an ASSERT.
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/virtual.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/virtual.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/virtual.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/virtual.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/virtual.c [iso-8859-1] Sat Mar 31 20:07:29 2012
@@ -1430,8 +1430,20 @@
return Status;
}
- /* This must be a VM VAD */
- ASSERT(Vad->u.VadFlags.PrivateMemory);
+ /* Set the correct memory type based on what kind of VAD this is */
+ if ((Vad->u.VadFlags.PrivateMemory) ||
+ (Vad->u.VadFlags.VadType == VadRotatePhysical))
+ {
+ MemoryInfo.Type = MEM_PRIVATE;
+ }
+ else if (Vad->u.VadFlags.VadType == VadImageMap)
+ {
+ MemoryInfo.Type = MEM_IMAGE;
+ }
+ else
+ {
+ MemoryInfo.Type = MEM_MAPPED;
+ }
/* Lock the address space of the process */
MmLockAddressSpace(&TargetProcess->Vm);
Author: akhaldi
Date: Sat Mar 31 19:01:26 2012
New Revision: 56289
URL: http://svn.reactos.org/svn/reactos?rev=56289&view=rev
Log:
[CMAKE]
* The def file is also an external object (that should be added to the link command directly).
Modified:
trunk/reactos/cmake/gcc.cmake
Modified: trunk/reactos/cmake/gcc.cmake
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/cmake/gcc.cmake?rev=56289&…
==============================================================================
--- trunk/reactos/cmake/gcc.cmake [iso-8859-1] (original)
+++ trunk/reactos/cmake/gcc.cmake [iso-8859-1] Sat Mar 31 19:01:26 2012
@@ -243,6 +243,7 @@
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_file}.def ${CMAKE_CURRENT_BINARY_DIR}/${_file}_stubs.c
COMMAND native-spec2def -n=${_dllname} --kill-at -a=${ARCH2} -d=${CMAKE_CURRENT_BINARY_DIR}/${_file}.def -s=${CMAKE_CURRENT_BINARY_DIR}/${_file}_stubs.c ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} native-spec2def)
+ set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${_file}.def PROPERTIES EXTERNAL_OBJECT TRUE)
if(__add_importlib)
# generate the def for the export lib
Author: cgutman
Date: Fri Mar 30 18:09:16 2012
New Revision: 56284
URL: http://svn.reactos.org/svn/reactos?rev=56284&view=rev
Log:
[NTOSKRNL]
- The legacy ROS Mm uses structures known as page ops to track operations on a page such as page out, page in, and access fault. The idea is that each operation is forced to wait until the page has completed all other pending operations to start its work. The problem was that the page op's completion event was a NotificationEvent instead of a SynchronizationEvent. This caused all operations to proceed at the same time if they were waiting on a single page op to begin. Now that is fixed and page ops proceed one after another as intended. This bug has been around since r9077.
- When waiting for sections to be unmapped or destroyed, the Mm waits for pending page operations to complete. The problem is that MmUnmapViewOfSection had a critical bug in which it forgot to dereference the page op it just retrieved. This caused zombie page ops to be stuck to that particular address if there were any pending operations at the time of the MmUnmapViewOfSection call. As a result, section destruction to bug check due to the hung page op after waiting 10 seconds for the operation to complete. This bug has been around since r18849.
- Due to the combined effects of the above bugs, sometimes unmapping or freeing a section would hang the system or bug check the system (remember the "Failed to wait for page op" messages?). This was evident in smiley_'s theme work when many applications calling FreeLibrary at the same time would trigger this bug. There are likely many more cases that triggered this series of events which either could never be replicated or simply could not be explained.
Modified:
trunk/reactos/ntoskrnl/mm/pageop.c
trunk/reactos/ntoskrnl/mm/section.c
Modified: trunk/reactos/ntoskrnl/mm/pageop.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/pageop.c?rev=5…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/pageop.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/pageop.c [iso-8859-1] Fri Mar 30 18:09:16 2012
@@ -239,7 +239,7 @@
PageOp->Status = STATUS_PENDING;
PageOp->OpType = OpType;
PageOp->MArea = MArea;
- KeInitializeEvent(&PageOp->CompletionEvent, NotificationEvent, FALSE);
+ KeInitializeEvent(&PageOp->CompletionEvent, SynchronizationEvent, FALSE);
MmPageOpHashTable[Hash] = PageOp;
(void)InterlockedIncrementUL(&MArea->PageOpCount);
Modified: trunk/reactos/ntoskrnl/mm/section.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/section.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/section.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/section.c [iso-8859-1] Fri Mar 30 18:09:16 2012
@@ -4254,6 +4254,7 @@
KeBugCheck(MEMORY_MANAGEMENT);
}
MmLockAddressSpace(AddressSpace);
+ MmspCompleteAndReleasePageOp(PageOp);
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace,
BaseAddress);
if (MemoryArea == NULL ||