- 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
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
MmCheckForPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
PMM_SECTION_SEGMENT Segment, ULONG Offset);

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* 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
* FILE: ntoskrnl/mm/anonmem.c
@ -287,7 +287,7 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
*/
PageOp = MmGetPageOp(MemoryArea, (ULONG)MemoryArea->Process->UniqueProcessId,
(PVOID)PAGE_ROUND_DOWN(Address), NULL, 0,
MM_PAGEOP_PAGEIN);
MM_PAGEOP_PAGEIN, FALSE);
if (PageOp == NULL)
{
DPRINT1("MmGetPageOp failed");

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* 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
* FILE: ntoskrnl/mm/balance.c
@ -111,6 +111,7 @@ MmReleasePageMemoryConsumer(ULONG Consumer, PHYSICAL_ADDRESS Page)
PMM_ALLOCATION_REQUEST Request;
PLIST_ENTRY Entry;
KIRQL oldIrql;
ULONG OldAvailable;
#if defined(__GNUC__)
if (Page.QuadPart == 0LL)
@ -126,8 +127,8 @@ MmReleasePageMemoryConsumer(ULONG Consumer, PHYSICAL_ADDRESS Page)
if (MmGetReferenceCountPage(Page) == 1)
{
InterlockedDecrement((LONG *)&MiMemoryConsumers[Consumer].PagesUsed);
InterlockedIncrement((LONG *)&MiNrAvailablePages);
if (IsListEmpty(&AllocationListHead))
OldAvailable = InterlockedIncrement((LONG *)&MiNrAvailablePages);
if (IsListEmpty(&AllocationListHead) || OldAvailable + 1 < MiMinimumAvailablePages)
{
KeReleaseSpinLock(&AllocationListLock, oldIrql);
MmDereferencePage(Page);
@ -349,7 +350,7 @@ MiBalancerThread(PVOID Unused)
{
/* MiBalancerEvent */
CHECKPOINT;
while (MiNrAvailablePages < MiMinimumAvailablePages)
while (MiNrAvailablePages < MiMinimumAvailablePages + 5)
{
for (i = 0; i < MC_MAXIMUM; i++)
{
@ -370,7 +371,7 @@ MiBalancerThread(PVOID Unused)
else if (Status == STATUS_SUCCESS + 1)
{
/* MiBalancerTimer */
ShouldRun = MiNrAvailablePages < MiMinimumAvailablePages ? TRUE : FALSE;
ShouldRun = MiNrAvailablePages < MiMinimumAvailablePages + 5 ? TRUE : FALSE;
for (i = 0; i < MC_MAXIMUM; i++)
{
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
* PROJECT: ReactOS kernel
@ -134,7 +134,7 @@ MmCheckForPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
PMM_PAGEOP
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
* 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.
*/
if (PageOp != NULL)
{
if (First)
{
PageOp = NULL;
}
else
{
PageOp->ReferenceCount++;
}
KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
return(PageOp);
}
@ -203,6 +210,7 @@ MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
if (PageOp == NULL)
{
KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
KEBUGCHECK(0);
return(NULL);
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* 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
* PROJECT: ReactOS kernel
@ -140,24 +140,11 @@ MmWritePagePhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress)
*/
PageOp = MmGetPageOp(MemoryArea, 0, 0,
MemoryArea->Data.SectionData.Segment,
Offset, MM_PAGEOP_PAGEOUT);
Offset, MM_PAGEOP_PAGEOUT, TRUE);
if (PageOp == NULL)
{
DPRINT1("MmGetPageOp failed\n");
KEBUGCHECK(0);
}
if (PageOp->Thread != PsGetCurrentThread())
{
MmUnlockAddressSpace(AddressSpace);
Status = KeWaitForSingleObject(&PageOp->CompletionEvent,
0,
KernelMode,
FALSE,
NULL);
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
MmReleasePageOp(PageOp);
if (Address < (PVOID)KERNEL_BASE)
{
ObDereferenceObject(Process);
@ -179,11 +166,10 @@ MmWritePagePhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress)
else if (Type == MEMORY_AREA_VIRTUAL_MEMORY)
{
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);
if (Address < (PVOID)KERNEL_BASE)
{
@ -278,16 +264,9 @@ MmPageOutPhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress)
*/
PageOp = MmGetPageOp(MemoryArea, 0, 0,
MemoryArea->Data.SectionData.Segment,
Offset, MM_PAGEOP_PAGEOUT);
Offset, MM_PAGEOP_PAGEOUT, TRUE);
if (PageOp == NULL)
{
DPRINT1("MmGetPageOp failed\n");
KEBUGCHECK(0);
}
if (PageOp->Thread != PsGetCurrentThread())
{
MmReleasePageOp(PageOp);
MmUnlockAddressSpace(AddressSpace);
if (Address < (PVOID)KERNEL_BASE)
{
@ -310,17 +289,10 @@ MmPageOutPhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress)
else if (Type == MEMORY_AREA_VIRTUAL_MEMORY)
{
PageOp = MmGetPageOp(MemoryArea, Address < (PVOID)KERNEL_BASE ? Process->UniqueProcessId : 0,
Address, NULL, 0, MM_PAGEOP_PAGEOUT);
if (PageOp->Thread != PsGetCurrentThread())
Address, NULL, 0, MM_PAGEOP_PAGEOUT, TRUE);
if (PageOp == NULL)
{
MmUnlockAddressSpace(AddressSpace);
Status = KeWaitForSingleObject(&PageOp->CompletionEvent,
0,
KernelMode,
FALSE,
NULL);
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
MmReleasePageOp(PageOp);
if (Address < (PVOID)KERNEL_BASE)
{
ObDereferenceObject(Process);

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* 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
* FILE: ntoskrnl/mm/section.c
@ -673,7 +673,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
/*
* 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)
{
DPRINT1("MmGetPageOp failed\n");
@ -1274,7 +1274,7 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
* Get or create a pageop
*/
PageOp = MmGetPageOp(MemoryArea, 0, 0, Segment, Offset,
MM_PAGEOP_ACCESSFAULT);
MM_PAGEOP_ACCESSFAULT, FALSE);
if (PageOp == NULL)
{
DPRINT1("MmGetPageOp failed\n");