Fixed some swapping bugs and deadlocks

svn path=/trunk/; revision=2468
This commit is contained in:
David Welch 2002-01-01 00:21:57 +00:00
parent 3ea11463b3
commit e5a34ef337
16 changed files with 206 additions and 102 deletions

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: view.c,v 1.33 2001/12/31 19:06:47 dwelch Exp $ /* $Id: view.c,v 1.34 2002/01/01 00:21:55 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -88,6 +88,7 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
PCACHE_SEGMENT current; PCACHE_SEGMENT current;
ULONG PagesPerSegment; ULONG PagesPerSegment;
ULONG PagesFreed; ULONG PagesFreed;
BOOLEAN Locked;
DPRINT("CcRosTrimCache(Target %d)\n", Target); DPRINT("CcRosTrimCache(Target %d)\n", Target);
@ -99,7 +100,11 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
{ {
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, CacheSegmentLRUListEntry); current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, CacheSegmentLRUListEntry);
current_entry = current_entry->Flink; current_entry = current_entry->Flink;
ExAcquireFastMutex(&current->Lock); Locked = ExTryToAcquireFastMutex(&current->Lock);
if (!Locked)
{
continue;
}
if (current->MappedCount > 0 || current->Dirty || current->ReferenceCount > 0) if (current->MappedCount > 0 || current->Dirty || current->ReferenceCount > 0)
{ {
ExReleaseFastMutex(&current->Lock); ExReleaseFastMutex(&current->Lock);
@ -318,8 +323,8 @@ CcRosGetCacheSegment(PBCB Bcb,
Status = MmCreateVirtualMapping(NULL, Status = MmCreateVirtualMapping(NULL,
current->BaseAddress + (i * PAGESIZE), current->BaseAddress + (i * PAGESIZE),
PAGE_READWRITE, PAGE_READWRITE,
(ULONG)Page); (ULONG)Page,
TRUE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
KeBugCheck(0); KeBugCheck(0);

View file

@ -57,8 +57,14 @@ extern inline PULONG get_page_directory(void)
NTSTATUS MmCreateVirtualMapping(struct _EPROCESS* Process, NTSTATUS MmCreateVirtualMapping(struct _EPROCESS* Process,
PVOID Address, PVOID Address,
ULONG flProtect, ULONG flProtect,
ULONG PhysicalAddress); ULONG PhysicalAddress,
BOOLEAN MayWait);
NTSTATUS
MmCreateVirtualMappingUnsafe(struct _EPROCESS* Process,
PVOID Address,
ULONG flProtect,
ULONG PhysicalAddress,
BOOLEAN MayWait);
VOID MmSetPageProtect(struct _EPROCESS* Process, VOID MmSetPageProtect(struct _EPROCESS* Process,
PVOID Address, PVOID Address,

View file

@ -127,7 +127,8 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
Status = MmCreateVirtualMapping(NULL, Status = MmCreateVirtualMapping(NULL,
KernelStack + (i * PAGESIZE), KernelStack + (i * PAGESIZE),
PAGE_EXECUTE_READWRITE, PAGE_EXECUTE_READWRITE,
(ULONG)Page); (ULONG)Page,
TRUE);
} }
Thread->InitialStack = KernelStack + MM_STACK_SIZE; Thread->InitialStack = KernelStack + MM_STACK_SIZE;
Thread->StackBase = KernelStack + MM_STACK_SIZE; Thread->StackBase = KernelStack + MM_STACK_SIZE;

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.3 2001/12/31 01:53:45 dwelch Exp $ /* $Id: balance.c,v 1.4 2002/01/01 00:21:55 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top directory * COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -31,6 +31,7 @@
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#include <internal/mm.h> #include <internal/mm.h>
#include <ntos/minmax.h>
#define NDEBUG #define NDEBUG
#include <internal/debug.h> #include <internal/debug.h>
@ -59,6 +60,10 @@ static ULONG MiNrAvailablePages;
static ULONG MiNrTotalPages; static ULONG MiNrTotalPages;
static LIST_ENTRY AllocationListHead; static LIST_ENTRY AllocationListHead;
static KSPIN_LOCK AllocationListLock; static KSPIN_LOCK AllocationListLock;
static ULONG NrWorkingThreads = 0;
static HANDLE WorkerThreadId;
static ULONG MiPagesRequired = 0;
static ULONG MiMinimumPagesPerRun = 1;
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
@ -94,8 +99,15 @@ MmReleasePageMemoryConsumer(ULONG Consumer, PVOID Page)
PLIST_ENTRY Entry; PLIST_ENTRY Entry;
KIRQL oldIrql; KIRQL oldIrql;
if (Page == NULL)
{
DPRINT1("Tried to release page zero.\n");
KeBugCheck(0);
}
InterlockedDecrement(&MiMemoryConsumers[Consumer].PagesUsed); InterlockedDecrement(&MiMemoryConsumers[Consumer].PagesUsed);
InterlockedIncrement(&MiNrAvailablePages); InterlockedIncrement(&MiNrAvailablePages);
InterlockedDecrement(&MiPagesRequired);
KeAcquireSpinLock(&AllocationListLock, &oldIrql); KeAcquireSpinLock(&AllocationListLock, &oldIrql);
if (IsListEmpty(&AllocationListHead)) if (IsListEmpty(&AllocationListHead))
{ {
@ -138,11 +150,8 @@ MiRebalanceMemoryConsumers(VOID)
ULONG NrFreedPages; ULONG NrFreedPages;
NTSTATUS Status; NTSTATUS Status;
Target = MiMinimumAvailablePages - MiNrAvailablePages; Target = (MiMinimumAvailablePages - MiNrAvailablePages) + MiPagesRequired;
if (Target < 0) Target = min(Target, MiMinimumPagesPerRun);
{
Target = 1;
}
for (i = 0; i < MC_MAXIMUM && Target > 0; i++) for (i = 0; i < MC_MAXIMUM && Target > 0; i++)
{ {
@ -168,12 +177,14 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, PVOID* AllocatedPag
ULONG OldUsed; ULONG OldUsed;
ULONG OldAvailable; ULONG OldAvailable;
PVOID Page; PVOID Page;
KIRQL oldIrql;
/* /*
* Make sure we don't exceed our individual target. * Make sure we don't exceed our individual target.
*/ */
OldUsed = InterlockedIncrement(&MiMemoryConsumers[Consumer].PagesUsed); OldUsed = InterlockedIncrement(&MiMemoryConsumers[Consumer].PagesUsed);
if (OldUsed >= (MiMemoryConsumers[Consumer].PagesTarget - 1)) if (OldUsed >= (MiMemoryConsumers[Consumer].PagesTarget - 1) &&
WorkerThreadId != PsGetCurrentThreadId())
{ {
if (!CanWait) if (!CanWait)
{ {
@ -188,26 +199,9 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, PVOID* AllocatedPag
*/ */
OldAvailable = InterlockedDecrement(&MiNrAvailablePages); OldAvailable = InterlockedDecrement(&MiNrAvailablePages);
if (OldAvailable < MiMinimumAvailablePages) if (OldAvailable < MiMinimumAvailablePages)
{
if (!CanWait)
{
InterlockedIncrement(&MiNrAvailablePages);
InterlockedDecrement(&MiMemoryConsumers[Consumer].PagesUsed);
return(STATUS_NO_MEMORY);
}
MiRebalanceMemoryConsumers();
}
/*
* Actually allocate the page.
*/
Page = MmAllocPage(Consumer, 0);
if (Page == NULL)
{ {
MM_ALLOCATION_REQUEST Request; MM_ALLOCATION_REQUEST Request;
KIRQL oldIrql;
/* Still not trimmed enough. */
if (!CanWait) if (!CanWait)
{ {
InterlockedIncrement(&MiNrAvailablePages); InterlockedIncrement(&MiNrAvailablePages);
@ -218,15 +212,59 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, PVOID* AllocatedPag
/* Insert an allocation request. */ /* Insert an allocation request. */
Request.Page = NULL; Request.Page = NULL;
KeInitializeEvent(&Request.Event, NotificationEvent, FALSE); KeInitializeEvent(&Request.Event, NotificationEvent, FALSE);
KeAcquireSpinLock(&AllocationListLock, &oldIrql); InterlockedIncrement(&MiPagesRequired);
InsertTailList(&AllocationListHead, &Request.ListEntry);
KeReleaseSpinLock(&AllocationListLock, oldIrql); KeAcquireSpinLock(&AllocationListLock, &oldIrql);
MiRebalanceMemoryConsumers(); if (NrWorkingThreads == 0)
{
InsertTailList(&AllocationListHead, &Request.ListEntry);
NrWorkingThreads++;
KeReleaseSpinLock(&AllocationListLock, oldIrql);
WorkerThreadId = PsGetCurrentThreadId();
MiRebalanceMemoryConsumers();
KeAcquireSpinLock(&AllocationListLock, &oldIrql);
NrWorkingThreads--;
WorkerThreadId = 0;
KeReleaseSpinLock(&AllocationListLock, oldIrql);
}
else
{
if (WorkerThreadId == PsGetCurrentThreadId())
{
Page = MmAllocPage(Consumer, 0);
KeReleaseSpinLock(&AllocationListLock, oldIrql);
if (Page == NULL)
{
KeBugCheck(0);
}
*AllocatedPage = Page;
return(STATUS_SUCCESS);
}
InsertTailList(&AllocationListHead, &Request.ListEntry);
KeReleaseSpinLock(&AllocationListLock, oldIrql);
KeWaitForSingleObject(&Request.Event,
0,
KernelMode,
FALSE,
NULL);
}
Page = Request.Page; Page = Request.Page;
if (Page == NULL) if (Page == NULL)
{ {
KeBugCheck(0); KeBugCheck(0);
} }
*AllocatedPage = Page;
return(STATUS_SUCCESS);
}
/*
* Actually allocate the page.
*/
Page = MmAllocPage(Consumer, 0);
if (Page == NULL)
{
KeBugCheck(0);
} }
*AllocatedPage = Page; *AllocatedPage = Page;

View file

@ -1,4 +1,4 @@
/* $Id: cont.c,v 1.16 2001/12/31 19:06:47 dwelch Exp $ /* $Id: cont.c,v 1.17 2002/01/01 00:21:55 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -74,7 +74,8 @@ MmAllocateContiguousAlignedMemory(IN ULONG NumberOfBytes,
MmCreateVirtualMapping(NULL, MmCreateVirtualMapping(NULL,
BaseAddress + (i * 4096), BaseAddress + (i * 4096),
PAGE_EXECUTE_READWRITE | PAGE_SYSTEM, PAGE_EXECUTE_READWRITE | PAGE_SYSTEM,
(ULONG)(PBase + (i * 4096))); (ULONG)(PBase + (i * 4096)),
TRUE);
} }
return(BaseAddress); return(BaseAddress);
} }

View file

@ -47,12 +47,6 @@ static LIST_ENTRY FreeZeroedPageListHead;
static LIST_ENTRY FreeUnzeroedPageListHead; static LIST_ENTRY FreeUnzeroedPageListHead;
static LIST_ENTRY BiosPageListHead; static LIST_ENTRY BiosPageListHead;
NTSTATUS
MmCreateVirtualMappingUnsafe(struct _EPROCESS* Process,
PVOID Address,
ULONG flProtect,
ULONG PhysicalAddress);
/* FUNCTIONS *************************************************************/ /* FUNCTIONS *************************************************************/
PVOID PVOID
@ -320,7 +314,8 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
(i * PAGESIZE)), (i * PAGESIZE)),
PAGE_READWRITE, PAGE_READWRITE,
(ULONG)(LastPhysKernelAddress (ULONG)(LastPhysKernelAddress
- (i * PAGESIZE))); - (i * PAGESIZE)),
FALSE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DbgPrint("Unable to create virtual mapping\n"); DbgPrint("Unable to create virtual mapping\n");

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.31 2001/12/31 19:06:48 dwelch Exp $ /* $Id: page.c,v 1.32 2002/01/01 00:21:57 dwelch Exp $
* *
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/i386/page.c * FILE: ntoskrnl/mm/i386/page.c
@ -217,7 +217,7 @@ VOID MmFreePageTable(PEPROCESS Process, PVOID Address)
} }
} }
NTSTATUS MmGetPageEntry2(PVOID PAddress, PULONG* Pte) NTSTATUS MmGetPageEntry2(PVOID PAddress, PULONG* Pte, BOOLEAN MayWait)
/* /*
* FUNCTION: Get a pointer to the page table entry for a virtual address * FUNCTION: Get a pointer to the page table entry for a virtual address
*/ */
@ -240,7 +240,7 @@ NTSTATUS MmGetPageEntry2(PVOID PAddress, PULONG* Pte)
else else
{ {
NTSTATUS Status; NTSTATUS Status;
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, (PVOID*)&npage); Status = MmRequestPageMemoryConsumer(MC_NPPOOL, MayWait, (PVOID*)&npage);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return(Status); return(Status);
@ -803,7 +803,7 @@ MmCreateVirtualMappingForKernel(PVOID Address,
KeAttachProcess(Process); KeAttachProcess(Process);
} }
Status = MmGetPageEntry2(Address, &Pte); Status = MmGetPageEntry2(Address, &Pte, FALSE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
if (Process != NULL && Process != CurrentProcess) if (Process != NULL && Process != CurrentProcess)
@ -878,7 +878,7 @@ MmCreatePageFileMapping(PEPROCESS Process,
KeAttachProcess(Process); KeAttachProcess(Process);
} }
Status = MmGetPageEntry2(Address, &Pte); Status = MmGetPageEntry2(Address, &Pte, FALSE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
if (Process != NULL && Process != CurrentProcess) if (Process != NULL && Process != CurrentProcess)
@ -914,7 +914,8 @@ NTSTATUS
MmCreateVirtualMappingUnsafe(PEPROCESS Process, MmCreateVirtualMappingUnsafe(PEPROCESS Process,
PVOID Address, PVOID Address,
ULONG flProtect, ULONG flProtect,
ULONG PhysicalAddress) ULONG PhysicalAddress,
BOOLEAN MayWait)
{ {
PEPROCESS CurrentProcess; PEPROCESS CurrentProcess;
ULONG Attributes; ULONG Attributes;
@ -949,7 +950,7 @@ MmCreateVirtualMappingUnsafe(PEPROCESS Process,
KeAttachProcess(Process); KeAttachProcess(Process);
} }
Status = MmGetPageEntry2(Address, &Pte); Status = MmGetPageEntry2(Address, &Pte, MayWait);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
if (Process != NULL && Process != CurrentProcess) if (Process != NULL && Process != CurrentProcess)
@ -990,7 +991,8 @@ NTSTATUS
MmCreateVirtualMapping(PEPROCESS Process, MmCreateVirtualMapping(PEPROCESS Process,
PVOID Address, PVOID Address,
ULONG flProtect, ULONG flProtect,
ULONG PhysicalAddress) ULONG PhysicalAddress,
BOOLEAN MayWait)
{ {
if (!MmIsUsablePage((PVOID)PhysicalAddress)) if (!MmIsUsablePage((PVOID)PhysicalAddress))
{ {
@ -1001,7 +1003,8 @@ MmCreateVirtualMapping(PEPROCESS Process,
return(MmCreateVirtualMappingUnsafe(Process, return(MmCreateVirtualMappingUnsafe(Process,
Address, Address,
flProtect, flProtect,
PhysicalAddress)); PhysicalAddress,
MayWait));
} }
ULONG ULONG

View file

@ -1,4 +1,4 @@
/* $Id: kmap.c,v 1.13 2001/12/31 01:53:45 dwelch Exp $ /* $Id: kmap.c,v 1.14 2002/01/01 00:21:56 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -111,7 +111,8 @@ ExAllocatePageWithPhysPage(ULONG PhysPage)
Status = MmCreateVirtualMapping(NULL, Status = MmCreateVirtualMapping(NULL,
(PVOID)addr, (PVOID)addr,
PAGE_READWRITE | PAGE_SYSTEM, PAGE_READWRITE | PAGE_SYSTEM,
PhysPage); PhysPage,
FALSE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DbgPrint("Unable to create virtual mapping\n"); DbgPrint("Unable to create virtual mapping\n");
@ -138,7 +139,9 @@ MiFreeNonPagedPoolRegion(PVOID Addr, ULONG Count, BOOLEAN Free)
ULONG i; ULONG i;
ULONG Base = (Addr - NonPagedPoolBase) / PAGESIZE; ULONG Base = (Addr - NonPagedPoolBase) / PAGESIZE;
ULONG Offset; ULONG Offset;
KIRQL oldlvl;
KeAcquireSpinLock(&AllocMapLock, &oldlvl);
for (i = 0; i < Count; i++) for (i = 0; i < Count; i++)
{ {
Offset = Base + i; Offset = Base + i;
@ -149,6 +152,7 @@ MiFreeNonPagedPoolRegion(PVOID Addr, ULONG Count, BOOLEAN Free)
NULL, NULL,
NULL); NULL);
} }
KeReleaseSpinLock(&AllocMapLock, oldlvl);
} }
PVOID PVOID
@ -160,7 +164,9 @@ MiAllocNonPagedPoolRegion(ULONG nr_pages)
unsigned int start = 0; unsigned int start = 0;
unsigned int length = 0; unsigned int length = 0;
unsigned int i,j; unsigned int i,j;
KIRQL oldlvl;
KeAcquireSpinLock(&AllocMapLock, &oldlvl);
for (i=1; i<ALLOC_MAP_SIZE;i++) for (i=1; i<ALLOC_MAP_SIZE;i++)
{ {
if (!(AllocMap[i/32] & (1 << (i % 32)))) if (!(AllocMap[i/32] & (1 << (i % 32))))
@ -181,6 +187,7 @@ MiAllocNonPagedPoolRegion(ULONG nr_pages)
AllocMap[j / 32] |= (1 << (j % 32)); AllocMap[j / 32] |= (1 << (j % 32));
} }
DPRINT("returning %x\n",((start*PAGESIZE)+NonPagedPoolBase)); DPRINT("returning %x\n",((start*PAGESIZE)+NonPagedPoolBase));
KeReleaseSpinLock(&AllocMapLock, oldlvl);
return(((start*PAGESIZE)+NonPagedPoolBase)); return(((start*PAGESIZE)+NonPagedPoolBase));
} }
} }

View file

@ -313,7 +313,7 @@ MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace,
} }
for (i=0; i<(PAGE_ROUND_UP(MemoryArea->Length)/PAGESIZE); i++) for (i=0; i<(PAGE_ROUND_UP(MemoryArea->Length)/PAGESIZE); i++)
{ {
ULONG PhysAddr; ULONG PhysAddr = 0;
BOOL Dirty; BOOL Dirty;
SWAPENTRY SwapEntry = 0; SWAPENTRY SwapEntry = 0;

View file

@ -1,4 +1,4 @@
/* $Id: mdl.c,v 1.34 2001/04/03 17:25:49 dwelch Exp $ /* $Id: mdl.c,v 1.35 2002/01/01 00:21:56 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -116,6 +116,7 @@ PVOID STDCALL MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode)
KeBugCheck(0); KeBugCheck(0);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
MmUnlockAddressSpace(MmGetKernelAddressSpace());
MdlPages = (PULONG)(Mdl + 1); MdlPages = (PULONG)(Mdl + 1);
for (i=0; i<(PAGE_ROUND_UP(Mdl->ByteCount+Mdl->ByteOffset)/PAGESIZE); i++) for (i=0; i<(PAGE_ROUND_UP(Mdl->ByteCount+Mdl->ByteOffset)/PAGESIZE); i++)
@ -123,14 +124,14 @@ PVOID STDCALL MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode)
Status = MmCreateVirtualMapping(NULL, Status = MmCreateVirtualMapping(NULL,
(PVOID)((ULONG)Base+(i*PAGESIZE)), (PVOID)((ULONG)Base+(i*PAGESIZE)),
PAGE_READWRITE, PAGE_READWRITE,
MdlPages[i]); MdlPages[i],
TRUE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DbgPrint("Unable to create virtual mapping\n"); DbgPrint("Unable to create virtual mapping\n");
KeBugCheck(0); KeBugCheck(0);
} }
} }
MmUnlockAddressSpace(MmGetKernelAddressSpace());
Mdl->MdlFlags = Mdl->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA; Mdl->MdlFlags = Mdl->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
Mdl->MappedSystemVa = Base + Mdl->ByteOffset; Mdl->MappedSystemVa = Base + Mdl->ByteOffset;
return(Base + Mdl->ByteOffset); return(Base + Mdl->ByteOffset);

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: mm.c,v 1.52 2001/12/31 01:53:45 dwelch Exp $ /* $Id: mm.c,v 1.53 2002/01/01 00:21:56 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top directory * COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -257,7 +257,19 @@ NTSTATUS MmCommitPagedPoolAddress(PVOID Address)
MmCreateVirtualMapping(NULL, MmCreateVirtualMapping(NULL,
(PVOID)PAGE_ROUND_DOWN(Address), (PVOID)PAGE_ROUND_DOWN(Address),
PAGE_READWRITE, PAGE_READWRITE,
(ULONG)AllocatedPage); (ULONG)AllocatedPage,
FALSE);
if (!NT_SUCCESS(Status))
{
MmUnlockAddressSpace(MmGetKernelAddressSpace());
Status =
MmCreateVirtualMapping(NULL,
(PVOID)PAGE_ROUND_DOWN(Address),
PAGE_READWRITE,
(ULONG)AllocatedPage,
FALSE);
MmLockAddressSpace(MmGetKernelAddressSpace());
}
return(Status); return(Status);
} }
@ -353,9 +365,21 @@ NTSTATUS MmNotPresentFault(KPROCESSOR_MODE Mode,
case MEMORY_AREA_SHARED_DATA: case MEMORY_AREA_SHARED_DATA:
Status = Status =
MmCreateVirtualMapping(PsGetCurrentProcess(), MmCreateVirtualMapping(PsGetCurrentProcess(),
(PVOID)PAGE_ROUND_DOWN(Address), (PVOID)PAGE_ROUND_DOWN(Address),
PAGE_READONLY, PAGE_READONLY,
(ULONG)MmSharedDataPagePhysicalAddress); (ULONG)MmSharedDataPagePhysicalAddress,
FALSE);
if (!NT_SUCCESS(Status))
{
MmUnlockAddressSpace(&PsGetCurrentProcess()->AddressSpace);
Status =
MmCreateVirtualMapping(PsGetCurrentProcess(),
(PVOID)PAGE_ROUND_DOWN(Address),
PAGE_READONLY,
(ULONG)MmSharedDataPagePhysicalAddress,
TRUE);
MmLockAddressSpace(&PsGetCurrentProcess()->AddressSpace);
}
break; break;
default: default:

View file

@ -1,4 +1,4 @@
/* $Id: mminit.c,v 1.29 2001/12/31 01:53:45 dwelch Exp $ /* $Id: mminit.c,v 1.30 2002/01/01 00:21:56 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top directory * COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -184,7 +184,8 @@ VOID MmInitVirtualMemory(ULONG LastKernelAddress,
Status = MmCreateVirtualMapping(NULL, Status = MmCreateVirtualMapping(NULL,
(PVOID)KERNEL_SHARED_DATA_BASE, (PVOID)KERNEL_SHARED_DATA_BASE,
PAGE_READWRITE, PAGE_READWRITE,
(ULONG)MmSharedDataPagePhysicalAddress); (ULONG)MmSharedDataPagePhysicalAddress,
TRUE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DbgPrint("Unable to create virtual mapping\n"); DbgPrint("Unable to create virtual mapping\n");

View file

@ -1,4 +1,4 @@
/* $Id: ncache.c,v 1.14 2001/12/31 19:06:47 dwelch Exp $ /* $Id: ncache.c,v 1.15 2002/01/01 00:21:56 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -79,7 +79,8 @@ MmAllocateNonCachedMemory(IN ULONG NumberOfBytes)
MmCreateVirtualMapping (NULL, MmCreateVirtualMapping (NULL,
Result + (i * PAGESIZE), Result + (i * PAGESIZE),
Attributes, Attributes,
(ULONG)NPage); (ULONG)NPage,
TRUE);
} }
return ((PVOID)Result); return ((PVOID)Result);
} }

View file

@ -1,4 +1,4 @@
/* $Id: npool.c,v 1.53 2001/12/31 19:06:47 dwelch Exp $ /* $Id: npool.c,v 1.54 2002/01/01 00:21:56 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -692,27 +692,33 @@ static BLOCK_HDR* grow_kernel_pool(unsigned int size, ULONG Tag, PVOID Caller)
{ {
unsigned int total_size = size + sizeof(BLOCK_HDR); unsigned int total_size = size + sizeof(BLOCK_HDR);
unsigned int nr_pages = PAGE_ROUND_UP(total_size) / PAGESIZE; unsigned int nr_pages = PAGE_ROUND_UP(total_size) / PAGESIZE;
unsigned int start = (ULONG)MiAllocNonPagedPoolRegion(nr_pages); unsigned int start;
BLOCK_HDR* used_blk=NULL; BLOCK_HDR* used_blk=NULL;
BLOCK_HDR* free_blk=NULL; BLOCK_HDR* free_blk=NULL;
int i; int i;
NTSTATUS Status; NTSTATUS Status;
KIRQL oldIrql;
start = (ULONG)MiAllocNonPagedPoolRegion(nr_pages);
DPRINT("growing heap for block size %d, ",size); DPRINT("growing heap for block size %d, ",size);
DPRINT("start %x\n",start); DPRINT("start %x\n",start);
for (i=0;i<nr_pages;i++) for (i=0;i<nr_pages;i++)
{ {
PVOID Page; PVOID Page;
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Page); /* FIXME: Check whether we can really wait here. */
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
KeBugCheck(0);
return(NULL); return(NULL);
} }
Status = MmCreateVirtualMapping(NULL, Status = MmCreateVirtualMapping(NULL,
(PVOID)(start + (i*PAGESIZE)), (PVOID)(start + (i*PAGESIZE)),
PAGE_READWRITE, PAGE_READWRITE,
(ULONG)Page); (ULONG)Page,
FALSE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DbgPrint("Unable to create virtual mapping\n"); DbgPrint("Unable to create virtual mapping\n");
@ -720,7 +726,7 @@ static BLOCK_HDR* grow_kernel_pool(unsigned int size, ULONG Tag, PVOID Caller)
} }
} }
KeAcquireSpinLock(&MmNpoolLock, &oldIrql);
if ((PAGESIZE-(total_size%PAGESIZE))>(2*sizeof(BLOCK_HDR))) if ((PAGESIZE-(total_size%PAGESIZE))>(2*sizeof(BLOCK_HDR)))
{ {
used_blk = (struct _BLOCK_HDR *)start; used_blk = (struct _BLOCK_HDR *)start;
@ -756,6 +762,7 @@ static BLOCK_HDR* grow_kernel_pool(unsigned int size, ULONG Tag, PVOID Caller)
#endif /* TAG_STATISTICS_TRACKING */ #endif /* TAG_STATISTICS_TRACKING */
VALIDATE_POOL; VALIDATE_POOL;
KeReleaseSpinLock(&MmNpoolLock, oldIrql);
return(used_blk); return(used_blk);
} }
@ -987,10 +994,9 @@ ExAllocateNonPagedPoolWithTag(ULONG Type, ULONG Size, ULONG Tag, PVOID Caller)
/* /*
* Otherwise create a new block * Otherwise create a new block
*/ */
block=block_to_address(grow_kernel_pool(Size, Tag, Caller));
VALIDATE_POOL;
memset(block, 0, Size);
KeReleaseSpinLock(&MmNpoolLock, oldIrql); KeReleaseSpinLock(&MmNpoolLock, oldIrql);
block=block_to_address(grow_kernel_pool(Size, Tag, Caller));
memset(block, 0, Size);
return(block); return(block);
#endif /* WHOLE_PAGE_ALLOCATIONS */ #endif /* WHOLE_PAGE_ALLOCATIONS */
} }

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.71 2001/12/31 19:06:48 dwelch Exp $ /* $Id: section.c,v 1.72 2002/01/01 00:21:56 dwelch Exp $
* *
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/section.c * FILE: ntoskrnl/mm/section.c
@ -528,7 +528,8 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
Status = MmCreateVirtualMapping(PsGetCurrentProcess(), Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
Address, Address,
Attributes, Attributes,
(ULONG)Page); (ULONG)Page,
FALSE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DbgPrint("Unable to create virtual mapping\n"); DbgPrint("Unable to create virtual mapping\n");
@ -574,7 +575,8 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
Status = MmCreateVirtualMapping(PsGetCurrentProcess(), Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
Address, Address,
MemoryArea->Attributes, MemoryArea->Attributes,
(ULONG)Page); (ULONG)Page,
FALSE);
while (Status == STATUS_NO_MEMORY) while (Status == STATUS_NO_MEMORY)
{ {
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
@ -583,7 +585,8 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
Status = MmCreateVirtualMapping(PsGetCurrentProcess(), Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
Address, Address,
MemoryArea->Attributes, MemoryArea->Attributes,
(ULONG)Page); (ULONG)Page,
FALSE);
} }
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -621,7 +624,8 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
Status = MmCreateVirtualMapping(PsGetCurrentProcess(), Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
Address, Address,
MemoryArea->Attributes, MemoryArea->Attributes,
Offset.QuadPart); Offset.QuadPart,
FALSE);
/* Don't add an rmap entry since the page mapped could be for anything. */ /* Don't add an rmap entry since the page mapped could be for anything. */
if (Locked) if (Locked)
{ {
@ -659,7 +663,8 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
Status = MmCreateVirtualMapping(PsGetCurrentProcess(), Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
Address, Address,
MemoryArea->Attributes, MemoryArea->Attributes,
(ULONG)Page); (ULONG)Page,
FALSE);
MmInsertRmap(Page, PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Address)); MmInsertRmap(Page, PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Address));
if (Locked) if (Locked)
{ {
@ -762,7 +767,8 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
Status = MmCreateVirtualMapping(PsGetCurrentProcess(), Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
Address, Address,
Attributes, Attributes,
(ULONG)Page); (ULONG)Page,
FALSE);
MmInsertRmap(Page, PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Address)); MmInsertRmap(Page, PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Address));
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -838,7 +844,8 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
Status = MmCreateVirtualMapping(PsGetCurrentProcess(), Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
Address, Address,
Attributes, Attributes,
(ULONG)Page); (ULONG)Page,
FALSE);
MmInsertRmap(Page, PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Address)); MmInsertRmap(Page, PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Address));
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -871,7 +878,8 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
Status = MmCreateVirtualMapping(PsGetCurrentProcess(), Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
Address, Address,
Attributes, Attributes,
(ULONG)Page); (ULONG)Page,
FALSE);
MmInsertRmap(Page, PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Address)); MmInsertRmap(Page, PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Address));
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -1019,7 +1027,8 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
Status = MmCreateVirtualMapping(PsGetCurrentProcess(), Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
Address, Address,
MemoryArea->Attributes, MemoryArea->Attributes,
(ULONG)NewPage); (ULONG)NewPage,
FALSE);
MmInsertRmap(NewPage, PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Address)); MmInsertRmap(NewPage, PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Address));
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -1243,7 +1252,8 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
Status = MmCreateVirtualMapping(MemoryArea->Process, Status = MmCreateVirtualMapping(MemoryArea->Process,
Address, Address,
MemoryArea->Attributes, MemoryArea->Attributes,
(ULONG)PhysicalAddress); (ULONG)PhysicalAddress,
FALSE);
MmInsertRmap(PhysicalAddress, MmInsertRmap(PhysicalAddress,
MemoryArea->Process, MemoryArea->Process,
Address); Address);
@ -1258,7 +1268,8 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
Status = MmCreateVirtualMapping(MemoryArea->Process, Status = MmCreateVirtualMapping(MemoryArea->Process,
Address, Address,
MemoryArea->Attributes, MemoryArea->Attributes,
(ULONG)PhysicalAddress); (ULONG)PhysicalAddress,
FALSE);
MmSetPageEntrySectionSegment(Segment, Offset.QuadPart, (ULONG)PhysicalAddress); MmSetPageEntrySectionSegment(Segment, Offset.QuadPart, (ULONG)PhysicalAddress);
MmSharePageEntrySectionSegment(Segment, Offset.QuadPart); MmSharePageEntrySectionSegment(Segment, Offset.QuadPart);
} }
@ -1287,7 +1298,8 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
Status = MmCreateVirtualMapping(MemoryArea->Process, Status = MmCreateVirtualMapping(MemoryArea->Process,
Address, Address,
MemoryArea->Attributes, MemoryArea->Attributes,
(ULONG)PhysicalAddress); (ULONG)PhysicalAddress,
FALSE);
MmInsertRmap(PhysicalAddress, MmInsertRmap(PhysicalAddress,
MemoryArea->Process, MemoryArea->Process,
Address); Address);
@ -1297,7 +1309,8 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
Status = MmCreateVirtualMapping(MemoryArea->Process, Status = MmCreateVirtualMapping(MemoryArea->Process,
Address, Address,
MemoryArea->Attributes, MemoryArea->Attributes,
(ULONG)PhysicalAddress); (ULONG)PhysicalAddress,
FALSE);
MmSetPageEntrySectionSegment(Segment, Offset.QuadPart, (ULONG)PhysicalAddress); MmSetPageEntrySectionSegment(Segment, Offset.QuadPart, (ULONG)PhysicalAddress);
MmSharePageEntrySectionSegment(Segment, Offset.QuadPart); MmSharePageEntrySectionSegment(Segment, Offset.QuadPart);
} }
@ -1310,7 +1323,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
/* /*
* Otherwise we have succeeded. * Otherwise we have succeeded.
*/ */
DPRINT1("MM: Wrote section page to swap!\n"); DPRINT("MM: Wrote section page 0x%.8X to swap!\n", PhysicalAddress);
MmReleasePageMemoryConsumer(MC_USER, PhysicalAddress); MmReleasePageMemoryConsumer(MC_USER, PhysicalAddress);
if (Private) if (Private)
@ -2649,7 +2662,8 @@ MmAllocateSection (IN ULONG Length)
Status = MmCreateVirtualMapping (NULL, Status = MmCreateVirtualMapping (NULL,
(Result + (i * PAGESIZE)), (Result + (i * PAGESIZE)),
PAGE_READWRITE, PAGE_READWRITE,
(ULONG)Page); (ULONG)Page,
TRUE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DbgPrint("Unable to create virtual mapping\n"); DbgPrint("Unable to create virtual mapping\n");

View file

@ -1,4 +1,4 @@
/* $Id: virtual.c,v 1.52 2001/12/31 19:06:48 dwelch Exp $ /* $Id: virtual.c,v 1.53 2002/01/01 00:21:56 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top directory * COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -183,7 +183,7 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
/* /*
* Otherwise we have succeeded, free the page * Otherwise we have succeeded, free the page
*/ */
DPRINT1("MM: Swapped out virtual memory swap!\n"); DPRINT("MM: Swapped out virtual memory page 0x%.8X!\n", PhysicalAddress);
MmDeleteVirtualMapping(MemoryArea->Process, Address, FALSE, NULL, NULL); MmDeleteVirtualMapping(MemoryArea->Process, Address, FALSE, NULL, NULL);
MmCreatePageFileMapping(MemoryArea->Process, Address, SwapEntry); MmCreatePageFileMapping(MemoryArea->Process, Address, SwapEntry);
MmDeleteAllRmaps(PhysicalAddress, NULL, NULL); MmDeleteAllRmaps(PhysicalAddress, NULL, NULL);
@ -340,16 +340,17 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
Status = MmCreateVirtualMapping(PsGetCurrentProcess(), Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
Address, Address,
MemoryArea->Attributes, MemoryArea->Attributes,
(ULONG)Page); (ULONG)Page,
FALSE);
while (Status == STATUS_NO_MEMORY) while (Status == STATUS_NO_MEMORY)
{ {
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
KeBugCheck(0); Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
MmLockAddressSpace(AddressSpace);
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
Address, Address,
MemoryArea->Attributes, MemoryArea->Attributes,
(ULONG)Page); (ULONG)Page,
TRUE);
MmLockAddressSpace(AddressSpace);
} }
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {