- Made it possible to allocate a pageop only if no other pageop for the given address exist.

- Try to pageout a page only if no other access to the page exist.
- Gave a free page only to the next waiting request (in MmReleasePageMemoryConsumer),
  if sufficient free pages are available.

svn path=/trunk/; revision=8546
This commit is contained in:
Hartmut Birr 2004-03-05 11:31:59 +00:00
parent 35cd217de4
commit 30264d875a
6 changed files with 32 additions and 51 deletions

View file

@ -445,7 +445,7 @@ MmReleasePageOp(PMM_PAGEOP PageOp);
PMM_PAGEOP PMM_PAGEOP
MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address, MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
PMM_SECTION_SEGMENT Segment, ULONG Offset, ULONG OpType); PMM_SECTION_SEGMENT Segment, ULONG Offset, ULONG OpType, BOOL First);
PMM_PAGEOP PMM_PAGEOP
MmCheckForPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address, MmCheckForPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
PMM_SECTION_SEGMENT Segment, ULONG Offset); PMM_SECTION_SEGMENT Segment, ULONG Offset);

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: anonmem.c,v 1.24 2003/12/31 05:33:03 jfilby Exp $ /* $Id: anonmem.c,v 1.25 2004/03/05 11:31:59 hbirr Exp $
* *
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/anonmem.c * FILE: ntoskrnl/mm/anonmem.c
@ -287,7 +287,7 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
*/ */
PageOp = MmGetPageOp(MemoryArea, (ULONG)MemoryArea->Process->UniqueProcessId, PageOp = MmGetPageOp(MemoryArea, (ULONG)MemoryArea->Process->UniqueProcessId,
(PVOID)PAGE_ROUND_DOWN(Address), NULL, 0, (PVOID)PAGE_ROUND_DOWN(Address), NULL, 0,
MM_PAGEOP_PAGEIN); MM_PAGEOP_PAGEIN, FALSE);
if (PageOp == NULL) if (PageOp == NULL)
{ {
DPRINT1("MmGetPageOp failed"); DPRINT1("MmGetPageOp failed");

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: balance.c,v 1.25 2003/12/30 18:52:05 fireball Exp $ /* $Id: balance.c,v 1.26 2004/03/05 11:31:59 hbirr Exp $
* *
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/balance.c * FILE: ntoskrnl/mm/balance.c
@ -111,6 +111,7 @@ MmReleasePageMemoryConsumer(ULONG Consumer, PHYSICAL_ADDRESS Page)
PMM_ALLOCATION_REQUEST Request; PMM_ALLOCATION_REQUEST Request;
PLIST_ENTRY Entry; PLIST_ENTRY Entry;
KIRQL oldIrql; KIRQL oldIrql;
ULONG OldAvailable;
#if defined(__GNUC__) #if defined(__GNUC__)
if (Page.QuadPart == 0LL) if (Page.QuadPart == 0LL)
@ -126,8 +127,8 @@ MmReleasePageMemoryConsumer(ULONG Consumer, PHYSICAL_ADDRESS Page)
if (MmGetReferenceCountPage(Page) == 1) if (MmGetReferenceCountPage(Page) == 1)
{ {
InterlockedDecrement((LONG *)&MiMemoryConsumers[Consumer].PagesUsed); InterlockedDecrement((LONG *)&MiMemoryConsumers[Consumer].PagesUsed);
InterlockedIncrement((LONG *)&MiNrAvailablePages); OldAvailable = InterlockedIncrement((LONG *)&MiNrAvailablePages);
if (IsListEmpty(&AllocationListHead)) if (IsListEmpty(&AllocationListHead) || OldAvailable + 1 < MiMinimumAvailablePages)
{ {
KeReleaseSpinLock(&AllocationListLock, oldIrql); KeReleaseSpinLock(&AllocationListLock, oldIrql);
MmDereferencePage(Page); MmDereferencePage(Page);
@ -349,7 +350,7 @@ MiBalancerThread(PVOID Unused)
{ {
/* MiBalancerEvent */ /* MiBalancerEvent */
CHECKPOINT; CHECKPOINT;
while (MiNrAvailablePages < MiMinimumAvailablePages) while (MiNrAvailablePages < MiMinimumAvailablePages + 5)
{ {
for (i = 0; i < MC_MAXIMUM; i++) for (i = 0; i < MC_MAXIMUM; i++)
{ {
@ -370,7 +371,7 @@ MiBalancerThread(PVOID Unused)
else if (Status == STATUS_SUCCESS + 1) else if (Status == STATUS_SUCCESS + 1)
{ {
/* MiBalancerTimer */ /* MiBalancerTimer */
ShouldRun = MiNrAvailablePages < MiMinimumAvailablePages ? TRUE : FALSE; ShouldRun = MiNrAvailablePages < MiMinimumAvailablePages + 5 ? TRUE : FALSE;
for (i = 0; i < MC_MAXIMUM; i++) for (i = 0; i < MC_MAXIMUM; i++)
{ {
if (MiMemoryConsumers[i].Trim != NULL) if (MiMemoryConsumers[i].Trim != NULL)

View file

@ -1,4 +1,4 @@
/* $Id: pageop.c,v 1.18 2003/10/12 17:05:48 hbirr Exp $ /* $Id: pageop.c,v 1.19 2004/03/05 11:31:59 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -134,7 +134,7 @@ MmCheckForPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
PMM_PAGEOP PMM_PAGEOP
MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address, MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
PMM_SECTION_SEGMENT Segment, ULONG Offset, ULONG OpType) PMM_SECTION_SEGMENT Segment, ULONG Offset, ULONG OpType, BOOL First)
/* /*
* FUNCTION: Get a page operation descriptor corresponding to * FUNCTION: Get a page operation descriptor corresponding to
* the memory area and either the segment, offset pair or the * the memory area and either the segment, offset pair or the
@ -190,8 +190,15 @@ MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
* and return it. * and return it.
*/ */
if (PageOp != NULL) if (PageOp != NULL)
{
if (First)
{
PageOp = NULL;
}
else
{ {
PageOp->ReferenceCount++; PageOp->ReferenceCount++;
}
KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
return(PageOp); return(PageOp);
} }
@ -203,6 +210,7 @@ MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
if (PageOp == NULL) if (PageOp == NULL)
{ {
KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
KEBUGCHECK(0);
return(NULL); return(NULL);
} }

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: rmap.c,v 1.26 2003/12/30 18:52:05 fireball Exp $ /* $Id: rmap.c,v 1.27 2004/03/05 11:31:59 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top directory * COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -140,24 +140,11 @@ MmWritePagePhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress)
*/ */
PageOp = MmGetPageOp(MemoryArea, 0, 0, PageOp = MmGetPageOp(MemoryArea, 0, 0,
MemoryArea->Data.SectionData.Segment, MemoryArea->Data.SectionData.Segment,
Offset, MM_PAGEOP_PAGEOUT); Offset, MM_PAGEOP_PAGEOUT, TRUE);
if (PageOp == NULL) if (PageOp == NULL)
{
DPRINT1("MmGetPageOp failed\n");
KEBUGCHECK(0);
}
if (PageOp->Thread != PsGetCurrentThread())
{ {
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
Status = KeWaitForSingleObject(&PageOp->CompletionEvent,
0,
KernelMode,
FALSE,
NULL);
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
MmReleasePageOp(PageOp);
if (Address < (PVOID)KERNEL_BASE) if (Address < (PVOID)KERNEL_BASE)
{ {
ObDereferenceObject(Process); ObDereferenceObject(Process);
@ -179,11 +166,10 @@ MmWritePagePhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress)
else if (Type == MEMORY_AREA_VIRTUAL_MEMORY) else if (Type == MEMORY_AREA_VIRTUAL_MEMORY)
{ {
PageOp = MmGetPageOp(MemoryArea, Address < (PVOID)KERNEL_BASE ? Process->UniqueProcessId : 0, PageOp = MmGetPageOp(MemoryArea, Address < (PVOID)KERNEL_BASE ? Process->UniqueProcessId : 0,
Address, NULL, 0, MM_PAGEOP_PAGEOUT); Address, NULL, 0, MM_PAGEOP_PAGEOUT, TRUE);
if (PageOp->Thread != PsGetCurrentThread()) if (PageOp == NULL)
{ {
MmReleasePageOp(PageOp);
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
if (Address < (PVOID)KERNEL_BASE) if (Address < (PVOID)KERNEL_BASE)
{ {
@ -278,16 +264,9 @@ MmPageOutPhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress)
*/ */
PageOp = MmGetPageOp(MemoryArea, 0, 0, PageOp = MmGetPageOp(MemoryArea, 0, 0,
MemoryArea->Data.SectionData.Segment, MemoryArea->Data.SectionData.Segment,
Offset, MM_PAGEOP_PAGEOUT); Offset, MM_PAGEOP_PAGEOUT, TRUE);
if (PageOp == NULL) if (PageOp == NULL)
{ {
DPRINT1("MmGetPageOp failed\n");
KEBUGCHECK(0);
}
if (PageOp->Thread != PsGetCurrentThread())
{
MmReleasePageOp(PageOp);
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
if (Address < (PVOID)KERNEL_BASE) if (Address < (PVOID)KERNEL_BASE)
{ {
@ -310,17 +289,10 @@ MmPageOutPhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress)
else if (Type == MEMORY_AREA_VIRTUAL_MEMORY) else if (Type == MEMORY_AREA_VIRTUAL_MEMORY)
{ {
PageOp = MmGetPageOp(MemoryArea, Address < (PVOID)KERNEL_BASE ? Process->UniqueProcessId : 0, PageOp = MmGetPageOp(MemoryArea, Address < (PVOID)KERNEL_BASE ? Process->UniqueProcessId : 0,
Address, NULL, 0, MM_PAGEOP_PAGEOUT); Address, NULL, 0, MM_PAGEOP_PAGEOUT, TRUE);
if (PageOp->Thread != PsGetCurrentThread()) if (PageOp == NULL)
{ {
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
Status = KeWaitForSingleObject(&PageOp->CompletionEvent,
0,
KernelMode,
FALSE,
NULL);
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
MmReleasePageOp(PageOp);
if (Address < (PVOID)KERNEL_BASE) if (Address < (PVOID)KERNEL_BASE)
{ {
ObDereferenceObject(Process); ObDereferenceObject(Process);

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.145 2004/03/04 00:07:02 navaraf Exp $ /* $Id: section.c,v 1.146 2004/03/05 11:31:59 hbirr Exp $
* *
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/section.c * FILE: ntoskrnl/mm/section.c
@ -673,7 +673,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
/* /*
* Get or create a page operation descriptor * Get or create a page operation descriptor
*/ */
PageOp = MmGetPageOp(MemoryArea, 0, 0, Segment, Offset, MM_PAGEOP_PAGEIN); PageOp = MmGetPageOp(MemoryArea, 0, 0, Segment, Offset, MM_PAGEOP_PAGEIN, FALSE);
if (PageOp == NULL) if (PageOp == NULL)
{ {
DPRINT1("MmGetPageOp failed\n"); DPRINT1("MmGetPageOp failed\n");
@ -1274,7 +1274,7 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
* Get or create a pageop * Get or create a pageop
*/ */
PageOp = MmGetPageOp(MemoryArea, 0, 0, Segment, Offset, PageOp = MmGetPageOp(MemoryArea, 0, 0, Segment, Offset,
MM_PAGEOP_ACCESSFAULT); MM_PAGEOP_ACCESSFAULT, FALSE);
if (PageOp == NULL) if (PageOp == NULL)
{ {
DPRINT1("MmGetPageOp failed\n"); DPRINT1("MmGetPageOp failed\n");