- Fixed deadlock in pager thread.

- Added some more debugging checks.

svn path=/trunk/; revision=5107
This commit is contained in:
David Welch 2003-07-13 14:36:32 +00:00
parent 988c5bb9eb
commit b2730a4d61
6 changed files with 89 additions and 19 deletions

View File

@ -640,5 +640,9 @@ VOID
MiStartPagerThread(VOID); MiStartPagerThread(VOID);
VOID VOID
MmSetLRULastPage(PHYSICAL_ADDRESS PhysicalAddress); MmSetLRULastPage(PHYSICAL_ADDRESS PhysicalAddress);
VOID
MmRawDeleteVirtualMapping(PVOID Address);
VOID
MiStopPagerThread(VOID);
#endif #endif

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.18 2003/07/12 01:52:10 dwelch Exp $ /* $Id: balance.c,v 1.19 2003/07/13 14:36:32 dwelch Exp $
* *
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/balance.c * FILE: ntoskrnl/mm/balance.c
@ -181,10 +181,6 @@ MmRebalanceMemoryConsumers(VOID)
Target = Target - NrFreedPages; Target = Target - NrFreedPages;
} }
} }
if (Target > 0)
{
KeBugCheck(0);
}
} }
NTSTATUS NTSTATUS
@ -264,6 +260,7 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait,
MmTransferOwnershipPage(Page, Consumer); MmTransferOwnershipPage(Page, Consumer);
*AllocatedPage = Page; *AllocatedPage = Page;
InterlockedDecrement((LONG *)&MiPagesRequired); InterlockedDecrement((LONG *)&MiPagesRequired);
MiStopPagerThread();
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }

View File

@ -553,6 +553,11 @@ MmMarkPageMapped(PHYSICAL_ADDRESS PhysicalAddress)
if (Start < MmPageArraySize) if (Start < MmPageArraySize)
{ {
KeAcquireSpinLock(&PageListLock, &oldIrql); KeAcquireSpinLock(&PageListLock, &oldIrql);
if (MmPageArray[Start].Flags.Type == MM_PHYSICAL_PAGE_FREE)
{
DbgPrint("Mapping non-used page\n");
KeBugCheck(0);
}
MmPageArray[Start].MapCount++; MmPageArray[Start].MapCount++;
KeReleaseSpinLock(&PageListLock, oldIrql); KeReleaseSpinLock(&PageListLock, oldIrql);
} }
@ -563,10 +568,20 @@ MmMarkPageUnmapped(PHYSICAL_ADDRESS PhysicalAddress)
{ {
ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE; ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE;
KIRQL oldIrql; KIRQL oldIrql;
if (Start < MmPageArraySize) if (Start < MmPageArraySize)
{ {
KeAcquireSpinLock(&PageListLock, &oldIrql); KeAcquireSpinLock(&PageListLock, &oldIrql);
if (MmPageArray[Start].Flags.Type == MM_PHYSICAL_PAGE_FREE)
{
DbgPrint("Unmapping non-used page\n");
KeBugCheck(0);
}
if (MmPageArray[Start].MapCount == 0)
{
DbgPrint("Unmapping not mapped page\n");
KeBugCheck(0);
}
MmPageArray[Start].MapCount--; MmPageArray[Start].MapCount--;
KeReleaseSpinLock(&PageListLock, oldIrql); KeReleaseSpinLock(&PageListLock, oldIrql);
} }
@ -620,7 +635,7 @@ MmReferencePage(PHYSICAL_ADDRESS PhysicalAddress)
KIRQL oldIrql; KIRQL oldIrql;
DPRINT("MmReferencePage(PhysicalAddress %x)\n", PhysicalAddress); DPRINT("MmReferencePage(PhysicalAddress %x)\n", PhysicalAddress);
if (PhysicalAddress.u.LowPart == 0) if (PhysicalAddress.u.LowPart == 0)
{ {
KeBugCheck(0); KeBugCheck(0);
@ -871,6 +886,11 @@ MmAllocPage(ULONG Consumer, SWAPENTRY SavedSwapEntry)
DbgPrint("Got non-free page from freelist\n"); DbgPrint("Got non-free page from freelist\n");
KeBugCheck(0); KeBugCheck(0);
} }
if (PageDescriptor->MapCount != 0)
{
DbgPrint("Got mapped page from freelist\n");
KeBugCheck(0);
}
PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_USED; PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_USED;
PageDescriptor->Flags.Consumer = Consumer; PageDescriptor->Flags.Consumer = Consumer;
PageDescriptor->ReferenceCount = 1; PageDescriptor->ReferenceCount = 1;
@ -891,6 +911,11 @@ MmAllocPage(ULONG Consumer, SWAPENTRY SavedSwapEntry)
{ {
MiZeroPage(PageOffset); MiZeroPage(PageOffset);
} }
if (PageDescriptor->MapCount != 0)
{
DbgPrint("Returning mapped page.\n");
KeBugCheck(0);
}
return(PageOffset); return(PageOffset);
} }
@ -953,6 +978,11 @@ MmZeroPageThreadMain(PVOID Ignored)
memset(Address, 0, PAGE_SIZE); memset(Address, 0, PAGE_SIZE);
MmDeleteVirtualMapping(NULL, (PVOID)Address, FALSE, NULL, NULL); MmDeleteVirtualMapping(NULL, (PVOID)Address, FALSE, NULL, NULL);
KeAcquireSpinLock(&PageListLock, &oldIrql); KeAcquireSpinLock(&PageListLock, &oldIrql);
if (PageDescriptor->MapCount != 0)
{
DbgPrint("Mapped page on freelist.\n");
KeBugCheck(0);
}
PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_FREE; PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_FREE;
InsertHeadList(&FreeZeroedPageListHead, ListEntry); InsertHeadList(&FreeZeroedPageListHead, ListEntry);
} }

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: page.c,v 1.54 2003/07/11 01:23:15 royce Exp $ /* $Id: page.c,v 1.55 2003/07/13 14:36:32 dwelch Exp $
* *
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/i386/page.c * FILE: ntoskrnl/mm/i386/page.c
@ -442,6 +442,38 @@ MmDisableVirtualMapping(PEPROCESS Process, PVOID Address, BOOL* WasDirty, PHYSIC
} }
} }
VOID
MmRawDeleteVirtualMapping(PVOID Address)
{
PULONG Pde, kePde;
/*
* Set the page directory entry, we may have to copy the entry from
* the global page directory.
*/
Pde = ADDR_TO_PDE(Address);
if (*Pde == 0 && Address >= (PVOID)KERNEL_BASE)
{
kePde = MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(Address);
if (*kePde != 0)
{
*Pde = *kePde;
FLUSH_TLB;
}
}
if (*Pde == 0)
{
return;
}
/*
* Set the entry to zero
*/
*ADDR_TO_PTE(Address) = 0;
FLUSH_TLB;
}
VOID VOID
MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage, MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage,
BOOL* WasDirty, PHYSICAL_ADDRESS* PhysicalAddr) BOOL* WasDirty, PHYSICAL_ADDRESS* PhysicalAddr)

View File

@ -1,4 +1,4 @@
/* $Id: mminit.c,v 1.52 2003/07/10 21:05:03 royce Exp $ /* $Id: mminit.c,v 1.53 2003/07/13 14:36:32 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top directory * COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -386,7 +386,7 @@ VOID MmInit1(ULONG FirstKrnlPhysAddr,
i<(KERNEL_BASE + 2 * PAGE_TABLE_SIZE); i<(KERNEL_BASE + 2 * PAGE_TABLE_SIZE);
i=i+PAGE_SIZE) i=i+PAGE_SIZE)
{ {
MmDeleteVirtualMapping(NULL, (PVOID)(i), FALSE, NULL, NULL); MmRawDeleteVirtualMapping((PVOID)(i));
} }
DPRINT("Almost done MmInit()\n"); DPRINT("Almost done MmInit()\n");
#ifndef MP #ifndef MP

View File

@ -1,4 +1,4 @@
/* $Id: pager.c,v 1.12 2003/07/12 01:52:10 dwelch Exp $ /* $Id: pager.c,v 1.13 2003/07/13 14:36:32 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -25,7 +25,7 @@ static HANDLE PagerThreadHandle;
static CLIENT_ID PagerThreadId; static CLIENT_ID PagerThreadId;
static KEVENT PagerThreadEvent; static KEVENT PagerThreadEvent;
static BOOLEAN PagerThreadShouldTerminate; static BOOLEAN PagerThreadShouldTerminate;
static ULONG PagerThreadWorking; static ULONG PagerThreadWorkCount;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
@ -40,13 +40,19 @@ MiStartPagerThread(VOID)
{ {
ULONG WasWorking; ULONG WasWorking;
WasWorking = InterlockedExchange(&PagerThreadWorking, 1); WasWorking = InterlockedIncrement(&PagerThreadWorkCount);
if (WasWorking == 0) if (WasWorking == 1)
{ {
KeSetEvent(&PagerThreadEvent, IO_NO_INCREMENT, FALSE); KeSetEvent(&PagerThreadEvent, IO_NO_INCREMENT, FALSE);
} }
} }
VOID
MiStopPagerThread(VOID)
{
(VOID)InterlockedDecrement(&PagerThreadWorkCount);
}
static NTSTATUS STDCALL static NTSTATUS STDCALL
MmPagerThreadMain(PVOID Ignored) MmPagerThreadMain(PVOID Ignored)
{ {
@ -70,10 +76,11 @@ MmPagerThreadMain(PVOID Ignored)
DbgPrint("PagerThread: Terminating\n"); DbgPrint("PagerThread: Terminating\n");
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
/* Try and make some memory available to the system. */ do
MmRebalanceMemoryConsumers(); {
/* Let the rest of the system know we finished this run. */ /* Try and make some memory available to the system. */
(VOID)InterlockedExchange(&PagerThreadWorking, 0); MmRebalanceMemoryConsumers();
} while(PagerThreadWorkCount > 0);
} }
} }
@ -82,7 +89,7 @@ NTSTATUS MmInitPagerThread(VOID)
NTSTATUS Status; NTSTATUS Status;
PagerThreadShouldTerminate = FALSE; PagerThreadShouldTerminate = FALSE;
PagerThreadWorking = 0; PagerThreadWorkCount = 0;
KeInitializeEvent(&PagerThreadEvent, KeInitializeEvent(&PagerThreadEvent,
SynchronizationEvent, SynchronizationEvent,
FALSE); FALSE);