- 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);
VOID
MmSetLRULastPage(PHYSICAL_ADDRESS PhysicalAddress);
VOID
MmRawDeleteVirtualMapping(PVOID Address);
VOID
MiStopPagerThread(VOID);
#endif

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.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
* FILE: ntoskrnl/mm/balance.c
@ -181,10 +181,6 @@ MmRebalanceMemoryConsumers(VOID)
Target = Target - NrFreedPages;
}
}
if (Target > 0)
{
KeBugCheck(0);
}
}
NTSTATUS
@ -264,6 +260,7 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait,
MmTransferOwnershipPage(Page, Consumer);
*AllocatedPage = Page;
InterlockedDecrement((LONG *)&MiPagesRequired);
MiStopPagerThread();
return(STATUS_SUCCESS);
}

View file

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

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: 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
* 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
MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage,
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
* PROJECT: ReactOS kernel
@ -386,7 +386,7 @@ VOID MmInit1(ULONG FirstKrnlPhysAddr,
i<(KERNEL_BASE + 2 * PAGE_TABLE_SIZE);
i=i+PAGE_SIZE)
{
MmDeleteVirtualMapping(NULL, (PVOID)(i), FALSE, NULL, NULL);
MmRawDeleteVirtualMapping((PVOID)(i));
}
DPRINT("Almost done MmInit()\n");
#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
* PROJECT: ReactOS kernel
@ -25,7 +25,7 @@ static HANDLE PagerThreadHandle;
static CLIENT_ID PagerThreadId;
static KEVENT PagerThreadEvent;
static BOOLEAN PagerThreadShouldTerminate;
static ULONG PagerThreadWorking;
static ULONG PagerThreadWorkCount;
/* FUNCTIONS *****************************************************************/
@ -40,13 +40,19 @@ MiStartPagerThread(VOID)
{
ULONG WasWorking;
WasWorking = InterlockedExchange(&PagerThreadWorking, 1);
if (WasWorking == 0)
WasWorking = InterlockedIncrement(&PagerThreadWorkCount);
if (WasWorking == 1)
{
KeSetEvent(&PagerThreadEvent, IO_NO_INCREMENT, FALSE);
}
}
VOID
MiStopPagerThread(VOID)
{
(VOID)InterlockedDecrement(&PagerThreadWorkCount);
}
static NTSTATUS STDCALL
MmPagerThreadMain(PVOID Ignored)
{
@ -70,10 +76,11 @@ MmPagerThreadMain(PVOID Ignored)
DbgPrint("PagerThread: Terminating\n");
return(STATUS_SUCCESS);
}
/* Try and make some memory available to the system. */
MmRebalanceMemoryConsumers();
/* Let the rest of the system know we finished this run. */
(VOID)InterlockedExchange(&PagerThreadWorking, 0);
do
{
/* Try and make some memory available to the system. */
MmRebalanceMemoryConsumers();
} while(PagerThreadWorkCount > 0);
}
}
@ -82,7 +89,7 @@ NTSTATUS MmInitPagerThread(VOID)
NTSTATUS Status;
PagerThreadShouldTerminate = FALSE;
PagerThreadWorking = 0;
PagerThreadWorkCount = 0;
KeInitializeEvent(&PagerThreadEvent,
SynchronizationEvent,
FALSE);