diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index 244f2a2035f..89af0926d32 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -86,9 +86,11 @@ typedef struct } Data; } MEMORY_AREA, *PMEMORY_AREA; +#define WSET_ADDRESSES_IN_PAGE (1020) + typedef struct _MWORKING_SET { - PVOID Address[1020]; + PVOID Address[WSET_ADDRESSES_IN_PAGE]; struct _MWORKING_SET* Next; } MWORKING_SET, *PMWORKING_SET; @@ -261,6 +263,7 @@ typedef struct ULONG NrUserPages; ULONG NrFreePages; ULONG NrDirtyPages; + ULONG NrLockedPages; ULONG PagingRequestsInLastMinute; ULONG PagingRequestsInLastFiveMinutes; ULONG PagingRequestsInLastFifteenMinutes; @@ -283,6 +286,8 @@ VOID MmSetSavedSwapEntryPage(PVOID PhysicalAddress, SWAPENTRY SavedSwapEntry); SWAPENTRY MmGetSavedSwapEntryPage(PVOID PhysicalAddress); VOID MmSetCleanPage(struct _EPROCESS* Process, PVOID Address); +VOID MmLockPage(PVOID PhysicalPage); +VOID MmUnlockPage(PVOID PhysicalPage); #define MM_PHYSICAL_PAGE_MPW_PENDING (0x8) diff --git a/reactos/ntoskrnl/io/cleanup.c b/reactos/ntoskrnl/io/cleanup.c index c74c3e6de53..a02e01f9d37 100644 --- a/reactos/ntoskrnl/io/cleanup.c +++ b/reactos/ntoskrnl/io/cleanup.c @@ -115,10 +115,11 @@ VOID IoReadWriteCompletion(PDEVICE_OBJECT DeviceObject, } ExFreePool(Irp->AssociatedIrp.SystemBuffer); } - if (DeviceObject->Flags & DO_DIRECT_IO && !(Irp->Flags & IRP_PAGING_IO)) + if (DeviceObject->Flags & DO_DIRECT_IO) { + /* FIXME: Is the MDL destroyed on a paging i/o, check all cases. */ DPRINT("Tearing down MDL\n"); - if (Irp->MdlAddress->MappedSystemVa!=NULL) + if (Irp->MdlAddress->MappedSystemVa != NULL) { MmUnmapLockedPages(Irp->MdlAddress->MappedSystemVa, Irp->MdlAddress); diff --git a/reactos/ntoskrnl/ke/main.c b/reactos/ntoskrnl/ke/main.c index ec320462157..976ab82f4e7 100644 --- a/reactos/ntoskrnl/ke/main.c +++ b/reactos/ntoskrnl/ke/main.c @@ -1,4 +1,4 @@ -/* $Id: main.c,v 1.52 2000/07/04 11:11:03 dwelch Exp $ +/* $Id: main.c,v 1.53 2000/07/08 16:53:32 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -83,8 +83,16 @@ void _main (PLOADER_PARAMETER_BLOCK LoaderBlock) */ HalInitSystem (0, &KeLoaderBlock); + /* + * Display version number and copyright/warranty message + */ HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR" (Build "KERNEL_VERSION_BUILD_STR")\n"); - + HalDisplayString("Copyright 2000 (So who owns the copyright?).\n"); + HalDisplayString("ReactOS is free software, covered by the GNU General Public License, and you\n"); + HalDisplayString("are welcome to change it and/or distribute copies of it under certain\n"); + HalDisplayString("conditions.\n"); + HalDisplayString("There is absolutely no warranty for ReactOS.\n"); + last_kernel_address = KERNEL_BASE; for (i=0; i <= KeLoaderBlock.nr_files; i++) { diff --git a/reactos/ntoskrnl/mm/freelist.c b/reactos/ntoskrnl/mm/freelist.c index c637de5e46b..1e3492df760 100644 --- a/reactos/ntoskrnl/mm/freelist.c +++ b/reactos/ntoskrnl/mm/freelist.c @@ -33,6 +33,7 @@ typedef struct _PHYSICAL_PAGE ULONG ReferenceCount; KEVENT Event; SWAPENTRY SavedSwapEntry; + ULONG LockCount; } PHYSICAL_PAGE, *PPHYSICAL_PAGE; /* GLOBALS ****************************************************************/ @@ -315,6 +316,40 @@ VOID MmDereferencePage(PVOID PhysicalAddress) KeReleaseSpinLock(&PageListLock, oldIrql); } +VOID MmLockPage(PVOID PhysicalAddress) +{ + ULONG Start = (ULONG)PhysicalAddress / PAGESIZE; + KIRQL oldIrql; + + DPRINT("MmReferencePage(PhysicalAddress %x)\n", PhysicalAddress); + + if (((ULONG)PhysicalAddress) == 0) + { + KeBugCheck(0); + } + + KeAcquireSpinLock(&PageListLock, &oldIrql); + MmPageArray[Start].LockCount++; + KeReleaseSpinLock(&PageListLock, oldIrql); +} + +VOID MmUnlockPage(PVOID PhysicalAddress) +{ + ULONG Start = (ULONG)PhysicalAddress / PAGESIZE; + KIRQL oldIrql; + + DPRINT("MmReferencePage(PhysicalAddress %x)\n", PhysicalAddress); + + if (((ULONG)PhysicalAddress) == 0) + { + KeBugCheck(0); + } + + KeAcquireSpinLock(&PageListLock, &oldIrql); + MmPageArray[Start].LockCount--; + KeReleaseSpinLock(&PageListLock, oldIrql); +} + PVOID MmAllocPage(SWAPENTRY SavedSwapEntry) { diff --git a/reactos/ntoskrnl/mm/mdl.c b/reactos/ntoskrnl/mm/mdl.c index ad8bd16777d..496ba861e61 100644 --- a/reactos/ntoskrnl/mm/mdl.c +++ b/reactos/ntoskrnl/mm/mdl.c @@ -1,4 +1,4 @@ -/* $Id: mdl.c,v 1.23 2000/07/07 10:30:56 dwelch Exp $ +/* $Id: mdl.c,v 1.24 2000/07/08 16:53:33 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -24,14 +24,14 @@ PVOID MmGetMdlPageAddress(PMDL Mdl, PVOID Offset) { - PULONG mdl_pages; + PULONG MdlPages; - mdl_pages = (PULONG)(Mdl + 1); + MdlPages = (PULONG)(Mdl + 1); - return((PVOID)mdl_pages[((ULONG)Offset) / PAGESIZE]); + return((PVOID)MdlPages[((ULONG)Offset) / PAGESIZE]); } -VOID STDCALL MmUnlockPages(PMDL MemoryDescriptorList) +VOID STDCALL MmUnlockPages(PMDL Mdl) /* * FUNCTION: Unlocks the physical pages described by a given MDL * ARGUMENTS: @@ -41,7 +41,36 @@ VOID STDCALL MmUnlockPages(PMDL MemoryDescriptorList) * MDL is updated */ { - /* It is harmless to leave this one as a stub */ + ULONG i; + PULONG MdlPages; + + /* + * FIXME: I don't know whether this right, but it looks sensible + */ + if ((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) || + (Mdl->MdlFlags & MDL_IO_PAGE_READ)) + { + return; + } + + /* + * FIXME: Seems sensible + */ + if (!(Mdl->MdlFlags & MDL_PAGES_LOCKED)) + { + return; + } + + MmLockAddressSpace(&Mdl->Process->AddressSpace); + + MdlPages = (PULONG)(Mdl + 1); + for (i=0; i<(PAGE_ROUND_UP(Mdl->ByteCount+Mdl->ByteOffset)/PAGESIZE); i++) + { + MmUnlockPage((PVOID)MdlPages[i]); + MmDereferencePage((PVOID)MdlPages[i]); + } + MmUnlockAddressSpace(&Mdl->Process->AddressSpace); + Mdl->MdlFlags = Mdl->MdlFlags & (~MDL_PAGES_LOCKED); } PVOID STDCALL MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode) @@ -52,41 +81,46 @@ PVOID STDCALL MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode) * AccessMode = Specifies the access mode in which to map the MDL * RETURNS: The base virtual address that maps the locked pages for the * range described by the MDL + * FIXME: What does AccessMode do? */ { - PVOID base = NULL; - unsigned int i; - ULONG* mdl_pages=NULL; + PVOID Base; + ULONG i; + PULONG MdlPages; MEMORY_AREA* Result; + NTSTATUS Status; DPRINT("MmMapLockedPages(Mdl %x, AccessMode %x)\n", Mdl, AccessMode); - DPRINT("Mdl->ByteCount %x\n",Mdl->ByteCount); - DPRINT("PAGE_ROUND_UP(Mdl->ByteCount)/PAGESIZE) %x\n", - PAGE_ROUND_UP(Mdl->ByteCount)/PAGESIZE); + MmLockAddressSpace(MmGetKernelAddressSpace()); - MmCreateMemoryArea(NULL, - MmGetKernelAddressSpace(), - MEMORY_AREA_MDL_MAPPING, - &base, - Mdl->ByteCount + Mdl->ByteOffset, - 0, - &Result); - CHECKPOINT; - mdl_pages = (ULONG *)(Mdl + 1); + Base = NULL; + Status = MmCreateMemoryArea(NULL, + MmGetKernelAddressSpace(), + MEMORY_AREA_MDL_MAPPING, + &Base, + Mdl->ByteCount + Mdl->ByteOffset, + 0, + &Result); + if (!NT_SUCCESS(Status)) + { + MmUnlockAddressSpace(MmGetKernelAddressSpace()); + KeBugCheck(0); + return(STATUS_SUCCESS); + } + + MdlPages = (PULONG)(Mdl + 1); for (i=0; i<(PAGE_ROUND_UP(Mdl->ByteCount+Mdl->ByteOffset)/PAGESIZE); i++) { - DPRINT("Writing %x with physical address %x\n", - base+(i*PAGESIZE),mdl_pages[i]); MmSetPage(NULL, - (PVOID)((DWORD)base+(i*PAGESIZE)), + (PVOID)((ULONG)Base+(i*PAGESIZE)), PAGE_READWRITE, - mdl_pages[i]); + MdlPages[i]); } - DPRINT("base %x\n",base); + MmUnlockAddressSpace(MmGetKernelAddressSpace()); Mdl->MdlFlags = Mdl->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA; - Mdl->MappedSystemVa = base + Mdl->ByteOffset; - return(base + Mdl->ByteOffset); + Mdl->MappedSystemVa = Base + Mdl->ByteOffset; + return(Base + Mdl->ByteOffset); } @@ -99,34 +133,36 @@ VOID STDCALL MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl) */ { DPRINT("MmUnmapLockedPages(BaseAddress %x, Mdl %x)\n", Mdl, BaseAddress); - (void)MmFreeMemoryArea(MmGetKernelAddressSpace(), + MmLockAddressSpace(MmGetKernelAddressSpace()); + (VOID)MmFreeMemoryArea(MmGetKernelAddressSpace(), BaseAddress - Mdl->ByteOffset, Mdl->ByteCount, FALSE); Mdl->MdlFlags = Mdl->MdlFlags & ~MDL_MAPPED_TO_SYSTEM_VA; Mdl->MappedSystemVa = NULL; - DPRINT("MmUnmapLockedPages() finished\n"); + MmUnlockAddressSpace(MmGetKernelAddressSpace()); } VOID MmBuildMdlFromPages(PMDL Mdl, PULONG Pages) { ULONG i; - PULONG mdl_pages; + PULONG MdlPages; - mdl_pages = (PULONG)(Mdl + 1); + Mdl->MdlFlags = Mdl->MdlFlags | + (MDL_PAGES_LOCKED | MDL_IO_PAGE_READ); + + MdlPages = (PULONG)(Mdl + 1); for (i=0;i<(PAGE_ROUND_UP(Mdl->ByteOffset+Mdl->ByteCount)/PAGESIZE);i++) { - mdl_pages[i] = Pages[i]; - DPRINT("mdl_pages[i] %x\n",mdl_pages[i]); + MdlPages[i] = Pages[i]; } } - -VOID STDCALL MmProbeAndLockPages (PMDL Mdl, - KPROCESSOR_MODE AccessMode, - LOCK_OPERATION Operation) +VOID STDCALL MmProbeAndLockPages (PMDL Mdl, + KPROCESSOR_MODE AccessMode, + LOCK_OPERATION Operation) /* * FUNCTION: Probes the specified pages, makes them resident and locks them * ARGUMENTS: @@ -135,14 +171,20 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl, * Operation = Operation to probe for */ { - ULONG* mdl_pages=NULL; - int i; - MEMORY_AREA* marea; - PVOID Address; + PULONG MdlPages; + ULONG i; + PMEMORY_AREA MArea; PMADDRESS_SPACE AddressSpace; - DPRINT("MmProbeAndLockPages(Mdl %x)\n",Mdl); - DPRINT("StartVa %x\n",Mdl->StartVa); + DPRINT("MmProbeAndLockPages(Mdl %x)\n", Mdl); + + /* + * FIXME: Check behaviour against NT + */ + if (Mdl->MdlFlags & MDL_PAGES_LOCKED) + { + return; + } if (Mdl->StartVa > (PVOID)KERNEL_BASE) { @@ -153,38 +195,36 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl, AddressSpace = &Mdl->Process->AddressSpace; } MmLockAddressSpace(AddressSpace); - marea = MmOpenMemoryAreaByAddress(AddressSpace, + MArea = MmOpenMemoryAreaByAddress(AddressSpace, Mdl->StartVa); - DPRINT("marea %x\n",marea); /* * Check the area is valid */ - if (marea==NULL ) + if (MArea == NULL) { DbgPrint("(%s:%d) Area is invalid\n",__FILE__,__LINE__); MmUnlockAddressSpace(AddressSpace); + /* FIXME: ExRaiseStatus doesn't do anything sensible at the moment */ ExRaiseStatus(STATUS_INVALID_PARAMETER); } - /* - * Lock the memory area - * (We can't allow it to be freed while an I/O operation to it is - * ongoing) - */ - /* * Lock the pages */ - mdl_pages = (ULONG *)(Mdl + 1); + MdlPages = (ULONG *)(Mdl + 1); for (i=0;i<(PAGE_ROUND_UP(Mdl->ByteOffset+Mdl->ByteCount)/PAGESIZE);i++) { + PVOID Address; + Address = Mdl->StartVa + (i*PAGESIZE); - mdl_pages[i] = (MmGetPhysicalAddress(Address)).u.LowPart; - DPRINT("mdl_pages[i] %x\n",mdl_pages[i]); + MdlPages[i] = (MmGetPhysicalAddress(Address)).u.LowPart; + MmReferencePage((PVOID)MdlPages[i]); + MmLockPage((PVOID)MdlPages[i]); } MmUnlockAddressSpace(AddressSpace); + Mdl->MdlFlags = Mdl->MdlFlags | MDL_PAGES_LOCKED; } @@ -198,9 +238,10 @@ ULONG STDCALL MmSizeOfMdl (PVOID Base, * Length = number of bytes to map */ { - unsigned int len=ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base,Length); + ULONG len; + + len = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base,Length); - DPRINT("MmSizeOfMdl() %x\n",sizeof(MDL)+(len*sizeof(ULONG))); return(sizeof(MDL)+(len*sizeof(ULONG))); } @@ -244,7 +285,7 @@ PMDL STDCALL MmCreateMdl (PMDL MemoryDescriptorList, Size = MmSizeOfMdl(Base,Length); MemoryDescriptorList = (PMDL)ExAllocatePool(NonPagedPool,Size); - if (MemoryDescriptorList==NULL) + if (MemoryDescriptorList == NULL) { return(NULL); } @@ -256,13 +297,13 @@ PMDL STDCALL MmCreateMdl (PMDL MemoryDescriptorList, } -VOID -STDCALL -MmMapMemoryDumpMdl ( - PVOID Unknown0 - ) +VOID STDCALL MmMapMemoryDumpMdl (PVOID Unknown0) +/* + * FIXME: Has something to do with crash dumps. Do we want to implement + * this? + */ { - UNIMPLEMENTED; + UNIMPLEMENTED; } /* EOF */ diff --git a/reactos/ntoskrnl/mm/wset.c b/reactos/ntoskrnl/mm/wset.c index 7fb25a52485..68b3b065138 100644 --- a/reactos/ntoskrnl/mm/wset.c +++ b/reactos/ntoskrnl/mm/wset.c @@ -1,4 +1,4 @@ -/* $Id: wset.c,v 1.3 2000/07/07 10:30:57 dwelch Exp $ +/* $Id: wset.c,v 1.4 2000/07/08 16:53:33 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -124,7 +124,7 @@ ULONG MmTrimWorkingSet(PEPROCESS Process, } else { - j = (j + 1) % 1020; + j = (j + 1) % WSET_ADDRESSES_IN_PAGE; i++; } @@ -163,11 +163,11 @@ VOID MmRemovePageFromWorkingSet(PEPROCESS Process, } else { - AddressSpace->WorkingSetLruLast = 1020; + AddressSpace->WorkingSetLruLast = WSET_ADDRESSES_IN_PAGE; } return; } - j = (j + 1) % 1020; + j = (j + 1) % WSET_ADDRESSES_IN_PAGE; } KeBugCheck(0); } @@ -180,7 +180,7 @@ BOOLEAN MmAddPageToWorkingSet(PEPROCESS Process, AddressSpace = &Process->AddressSpace; - if (((AddressSpace->WorkingSetLruLast + 1) % 1020) == + if (((AddressSpace->WorkingSetLruLast + 1) % WSET_ADDRESSES_IN_PAGE) == AddressSpace->WorkingSetLruFirst) { return(FALSE); @@ -191,7 +191,7 @@ BOOLEAN MmAddPageToWorkingSet(PEPROCESS Process, WSet->Address[AddressSpace->WorkingSetLruLast] = Address; AddressSpace->WorkingSetLruLast = - (AddressSpace->WorkingSetLruLast + 1) % 1024; + (AddressSpace->WorkingSetLruLast + 1) % WSET_ADDRESSES_IN_PAGE; AddressSpace->WorkingSetSize++; return(TRUE);