Keep DPC queue size correct

Share section pages with cache if possible
If doing a read direct from disk (not via the cache) don't copy the data
MDL fixes

svn path=/trunk/; revision=1773
This commit is contained in:
David Welch 2001-04-03 17:25:50 +00:00
parent 0858e6f0fb
commit b63d768a18
9 changed files with 220 additions and 98 deletions

View file

@ -1,5 +1,5 @@
/* $Id: rw.c,v 1.21 2001/03/02 15:59:16 cnettel Exp $
/* $Id: rw.c,v 1.22 2001/04/03 17:25:50 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -174,7 +174,10 @@ VfatReadBigCluster(PDEVICE_EXTENSION DeviceExt,
/*
* Copy the data from the cache to the caller
*/
memcpy(Destination, BaseAddress + InternalOffset, InternalLength);
if (InternalOffset != 0 || !NoCache)
{
memcpy(Destination, BaseAddress + InternalOffset, InternalLength);
}
if (!NoCache)
{
CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, TRUE);
@ -292,7 +295,10 @@ VfatReadSmallCluster(PDEVICE_EXTENSION DeviceExt,
/*
* Copy the data from the cache to the caller
*/
memcpy(Destination, BaseAddress + InternalOffset, InternalLength);
if (InternalOffset != 0 || !NoCache)
{
memcpy(Destination, BaseAddress + InternalOffset, InternalLength);
}
if (!NoCache)
{
CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, TRUE);

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: view.c,v 1.22 2001/03/25 02:34:27 dwelch Exp $
/* $Id: view.c,v 1.23 2001/04/03 17:25:48 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -64,7 +64,7 @@
/* GLOBALS *******************************************************************/
#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
#define ROUND_DOWN(N, S) (ROUND_UP(N, S) - S)
#define ROUND_DOWN(N, S) (((N) % (S)) ? ROUND_UP(N, S) - S : N)
#define TAG_CSEG TAG('C', 'S', 'E', 'G')
#define TAG_BCB TAG('B', 'C', 'B', ' ')
@ -104,42 +104,30 @@ CcReleaseCacheSegment(PBCB Bcb,
return(STATUS_SUCCESS);
}
NTSTATUS STDCALL
CcRequestCacheSegment(PBCB Bcb,
ULONG FileOffset,
PVOID* BaseAddress,
PBOOLEAN UptoDate,
PCACHE_SEGMENT* CacheSeg)
/*
* FUNCTION: Request a page mapping for a BCB
*/
NTSTATUS
CcGetCacheSegment(PBCB Bcb,
ULONG FileOffset,
PULONG BaseOffset,
PVOID* BaseAddress,
PBOOLEAN UptoDate,
PCACHE_SEGMENT* CacheSeg)
{
KIRQL oldirql;
PLIST_ENTRY current_entry;
PCACHE_SEGMENT current;
ULONG i;
if ((FileOffset % Bcb->CacheSegmentSize) != 0)
{
KeBugCheck(0);
}
DPRINT("CcRequestCachePage(Bcb %x, FileOffset %x, BaseAddress %x, "
"UptoDate %x, CacheSeg %x)\n", Bcb, FileOffset, BaseAddress,
UptoDate, CacheSeg);
KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
current_entry = Bcb->CacheSegmentListHead.Flink;
while (current_entry != &Bcb->CacheSegmentListHead)
{
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, ListEntry);
if (current->FileOffset == FileOffset)
if (current->FileOffset <= FileOffset &&
(current->FileOffset + Bcb->CacheSegmentSize) > FileOffset)
{
DPRINT("Found existing segment at %x\n", current);
current->ReferenceCount++;
KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
DPRINT("Waiting for segment\n");
KeWaitForSingleObject(&current->Lock,
Executive,
KernelMode,
@ -148,7 +136,7 @@ CcRequestCacheSegment(PBCB Bcb,
*UptoDate = current->Valid;
*BaseAddress = current->BaseAddress;
*CacheSeg = current;
DPRINT("Returning %x (UptoDate %d)\n", current, current->Valid);
*BaseOffset = current->FileOffset;
return(STATUS_SUCCESS);
}
current_entry = current_entry->Flink;
@ -170,7 +158,7 @@ CcRequestCacheSegment(PBCB Bcb,
(PMEMORY_AREA*)&current->MemoryArea,
FALSE);
current->Valid = FALSE;
current->FileOffset = FileOffset;
current->FileOffset = ROUND_DOWN(FileOffset, Bcb->CacheSegmentSize);
current->Bcb = Bcb;
KeInitializeEvent(&current->Lock, SynchronizationEvent, FALSE);
current->ReferenceCount = 1;
@ -178,6 +166,7 @@ CcRequestCacheSegment(PBCB Bcb,
*UptoDate = current->Valid;
*BaseAddress = current->BaseAddress;
*CacheSeg = current;
*BaseOffset = current->FileOffset;
for (i = 0; i < (Bcb->CacheSegmentSize / PAGESIZE); i++)
{
MmCreateVirtualMapping(NULL,
@ -187,11 +176,35 @@ CcRequestCacheSegment(PBCB Bcb,
}
DPRINT("Returning %x (BaseAddress %x)\n", current, *BaseAddress);
return(STATUS_SUCCESS);
}
NTSTATUS STDCALL
CcRequestCacheSegment(PBCB Bcb,
ULONG FileOffset,
PVOID* BaseAddress,
PBOOLEAN UptoDate,
PCACHE_SEGMENT* CacheSeg)
/*
* FUNCTION: Request a page mapping for a BCB
*/
{
ULONG BaseOffset;
if ((FileOffset % Bcb->CacheSegmentSize) != 0)
{
KeBugCheck(0);
}
return(CcGetCacheSegment(Bcb,
FileOffset,
&BaseOffset,
BaseAddress,
UptoDate,
CacheSeg));
}
STATIC VOID
CcFreeCachePage(PVOID Context, PVOID Address, ULONG PhysAddr)
{

View file

@ -1,7 +1,15 @@
#ifndef __INCLUDE_INTERNAL_CC_H
#define __INCLUDE_INTERNAL_CCS_H
/* $Id: cc.h,v 1.2 2000/12/28 03:38:07 dwelch Exp $ */
#define __INCLUDE_INTERNAL_CC_H
/* $Id: cc.h,v 1.3 2001/04/03 17:25:48 dwelch Exp $ */
#include <ddk/ntifs.h>
VOID STDCALL
CcMdlReadCompleteDev (IN PMDL MdlChain,
IN PDEVICE_OBJECT DeviceObject);
NTSTATUS
CcGetCacheSegment(PBCB Bcb,
ULONG FileOffset,
PULONG BaseOffset,
PVOID* BaseAddress,
PBOOLEAN UptoDate,
PCACHE_SEGMENT* CacheSeg);
#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: io.h,v 1.8 2001/01/13 18:38:08 dwelch Exp $
/* $Id: io.h,v 1.9 2001/04/03 17:25:49 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -86,11 +86,12 @@ VOID IoInitShutdownNotification(VOID);
VOID IoShutdownRegisteredDevices(VOID);
VOID IoShutdownRegisteredFileSystems(VOID);
NTSTATUS STDCALL IoPageRead (PFILE_OBJECT FileObject,
PMDL Mdl,
PLARGE_INTEGER Offset,
PIO_STATUS_BLOCK StatusBlock,
ULONG PagingIo);
NTSTATUS STDCALL
IoPageRead (PFILE_OBJECT FileObject,
PMDL Mdl,
PLARGE_INTEGER Offset,
PIO_STATUS_BLOCK StatusBlock,
BOOLEAN PagingIo);
NTSTATUS STDCALL IoPageWrite (PFILE_OBJECT FileObject,
PMDL Mdl,
PLARGE_INTEGER Offset,

View file

@ -1,4 +1,4 @@
/* $Id: buildirp.c,v 1.24 2001/03/07 16:48:41 dwelch Exp $
/* $Id: buildirp.c,v 1.25 2001/04/03 17:25:49 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -481,13 +481,14 @@ IoBuildSynchronousFsdRequest(ULONG MajorFunction,
}
PIRP IoBuildSynchronousFsdRequestWithMdl(ULONG MajorFunction,
PDEVICE_OBJECT DeviceObject,
PMDL Mdl,
PLARGE_INTEGER StartingOffset,
PKEVENT Event,
PIO_STATUS_BLOCK IoStatusBlock,
ULONG PagingIo)
PIRP
IoBuildSynchronousFsdRequestWithMdl(ULONG MajorFunction,
PDEVICE_OBJECT DeviceObject,
PMDL Mdl,
PLARGE_INTEGER StartingOffset,
PKEVENT Event,
PIO_STATUS_BLOCK IoStatusBlock,
BOOLEAN PagingIo)
/*
* FUNCTION: Allocates and builds an IRP to be sent synchronously to lower
* level driver(s)

View file

@ -1,4 +1,4 @@
/* $Id: page.c,v 1.11 2001/01/13 18:38:09 dwelch Exp $
/* $Id: page.c,v 1.12 2001/04/03 17:25:49 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -68,11 +68,12 @@ NTSTATUS STDCALL IoPageWrite(PFILE_OBJECT FileObject,
}
NTSTATUS STDCALL IoPageRead(PFILE_OBJECT FileObject,
PMDL Mdl,
PLARGE_INTEGER Offset,
PIO_STATUS_BLOCK StatusBlock,
ULONG PagingIo)
NTSTATUS STDCALL
IoPageRead(PFILE_OBJECT FileObject,
PMDL Mdl,
PLARGE_INTEGER Offset,
PIO_STATUS_BLOCK StatusBlock,
BOOLEAN PagingIo)
{
PIRP Irp;
KEVENT Event;

View file

@ -18,7 +18,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: dpc.c,v 1.20 2001/04/02 04:07:49 phreak Exp $
/* $Id: dpc.c,v 1.21 2001/04/03 17:25:49 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -96,7 +96,10 @@ KiDispatchInterrupt(VOID)
KeRaiseIrql(HIGH_LEVEL, &oldlvl);
KeAcquireSpinLockAtDpcLevel(&DpcQueueLock);
current_entry = RemoveHeadList(&DpcQueueHead);
DpcQueueSize--;
if (current_entry != &DpcQueueHead)
{
DpcQueueSize--;
}
KeReleaseSpinLockFromDpcLevel(&DpcQueueLock);
current = CONTAINING_RECORD(current_entry,KDPC,DpcListEntry);
current->Lock=FALSE;
@ -110,7 +113,10 @@ KiDispatchInterrupt(VOID)
KeRaiseIrql(HIGH_LEVEL, &oldlvl);
KeAcquireSpinLockAtDpcLevel(&DpcQueueLock);
current_entry = RemoveHeadList(&DpcQueueHead);
DpcQueueSize--;
if (current_entry != &DpcQueueHead)
{
DpcQueueSize--;
}
KeReleaseSpinLockFromDpcLevel(&DpcQueueLock);
current = CONTAINING_RECORD(current_entry,KDPC,DpcListEntry);
current->Lock=FALSE;

View file

@ -1,4 +1,4 @@
/* $Id: mdl.c,v 1.33 2001/03/25 02:34:28 dwelch Exp $
/* $Id: mdl.c,v 1.34 2001/04/03 17:25:49 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -35,7 +35,8 @@ MmGetMdlPageAddress(PMDL Mdl, PVOID Offset)
return((PVOID)MdlPages[((ULONG)Offset) / PAGESIZE]);
}
VOID STDCALL MmUnlockPages(PMDL Mdl)
VOID STDCALL
MmUnlockPages(PMDL Mdl)
/*
* FUNCTION: Unlocks the physical pages described by a given MDL
* ARGUMENTS:
@ -92,6 +93,11 @@ PVOID STDCALL MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode)
NTSTATUS Status;
DPRINT("MmMapLockedPages(Mdl %x, AccessMode %x)\n", Mdl, AccessMode);
if (Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL)
{
return(Mdl->MappedSystemVa);
}
MmLockAddressSpace(MmGetKernelAddressSpace());
@ -131,7 +137,8 @@ PVOID STDCALL MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode)
}
VOID STDCALL MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl)
VOID STDCALL
MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl)
/*
* FUNCTION: Releases a mapping set up by a preceding call to MmMapLockedPages
* ARGUMENTS:
@ -140,6 +147,16 @@ VOID STDCALL MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl)
*/
{
DPRINT("MmUnmapLockedPages(BaseAddress %x, Mdl %x)\n", Mdl, BaseAddress);
/*
* In this case, the MDL has the same system address as the base address
* so there is no need to free it
*/
if (Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL)
{
return;
}
MmLockAddressSpace(MmGetKernelAddressSpace());
(VOID)MmFreeMemoryArea(MmGetKernelAddressSpace(),
BaseAddress - Mdl->ByteOffset,
@ -152,7 +169,8 @@ VOID STDCALL MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl)
}
VOID MmBuildMdlFromPages(PMDL Mdl, PULONG Pages)
VOID
MmBuildMdlFromPages(PMDL Mdl, PULONG Pages)
{
ULONG i;
PULONG MdlPages;
@ -286,7 +304,8 @@ ULONG STDCALL MmSizeOfMdl (PVOID Base,
}
VOID STDCALL MmBuildMdlForNonPagedPool (PMDL Mdl)
VOID STDCALL
MmBuildMdlForNonPagedPool (PMDL Mdl)
/*
* FUNCTION: Fills in the corresponding physical page array of a given
* MDL for a buffer in nonpaged system space
@ -296,8 +315,9 @@ VOID STDCALL MmBuildMdlForNonPagedPool (PMDL Mdl)
*/
{
int va;
Mdl->MdlFlags = Mdl->MdlFlags | MDL_SOURCE_IS_NONPAGED_POOL;
for (va=0; va<Mdl->Size; va++)
Mdl->MdlFlags = Mdl->MdlFlags |
(MDL_SOURCE_IS_NONPAGED_POOL | MDL_PAGES_LOCKED);
for (va=0; va < ((Mdl->Size - sizeof(MDL)) / sizeof(ULONG)); va++)
{
((PULONG)(Mdl + 1))[va] =
(MmGetPhysicalAddress(Mdl->StartVa + (va * PAGESIZE))).u.LowPart;
@ -306,9 +326,10 @@ VOID STDCALL MmBuildMdlForNonPagedPool (PMDL Mdl)
}
PMDL STDCALL MmCreateMdl (PMDL MemoryDescriptorList,
PVOID Base,
ULONG Length)
PMDL STDCALL
MmCreateMdl (PMDL MemoryDescriptorList,
PVOID Base,
ULONG Length)
/*
* FUNCTION: Allocates and initalizes an MDL
* ARGUMENTS:
@ -337,8 +358,8 @@ PMDL STDCALL MmCreateMdl (PMDL MemoryDescriptorList,
return(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?

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.54 2001/03/30 15:14:53 dwelch Exp $
/* $Id: section.c,v 1.55 2001/04/03 17:25:49 dwelch Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/section.c
@ -35,6 +35,7 @@
#include <internal/io.h>
#include <internal/ps.h>
#include <internal/pool.h>
#include <internal/cc.h>
#include <ddk/ntifs.h>
#define NDEBUG
@ -248,6 +249,98 @@ MmUnsharePageEntrySectionSegment(PMM_SECTION_SEGMENT Segment,
MmSetPageEntrySectionSegment(Segment, Offset, Entry);
}
NTSTATUS
MiReadPage(PMEMORY_AREA MemoryArea,
PLARGE_INTEGER Offset,
PVOID* Page)
{
IO_STATUS_BLOCK IoStatus;
PFILE_OBJECT FileObject;
PMDL Mdl;
NTSTATUS Status;
PREACTOS_COMMON_FCB_HEADER Fcb;
FileObject = MemoryArea->Data.SectionData.Section->FileObject;
Fcb = (PREACTOS_COMMON_FCB_HEADER)FileObject->FsContext;
if (FileObject->Flags & FO_DIRECT_CACHE_PAGING_READ &&
(Offset->QuadPart % PAGESIZE) == 0)
{
ULONG BaseOffset;
PVOID BaseAddress;
BOOLEAN UptoDate;
PCACHE_SEGMENT CacheSeg;
LARGE_INTEGER SegOffset;
PHYSICAL_ADDRESS Addr;
Status = CcGetCacheSegment(Fcb->Bcb,
(ULONG)Offset->QuadPart,
&BaseOffset,
&BaseAddress,
&UptoDate,
&CacheSeg);
if (!NT_SUCCESS(Status))
{
return(Status);
}
if (!UptoDate)
{
Mdl = MmCreateMdl(NULL, BaseAddress, Fcb->Bcb->CacheSegmentSize);
MmBuildMdlForNonPagedPool(Mdl);
SegOffset.QuadPart = BaseOffset;
Status = IoPageRead(FileObject,
Mdl,
&SegOffset,
&IoStatus,
TRUE);
if (!NT_SUCCESS(Status))
{
CcReleaseCacheSegment(Fcb->Bcb, CacheSeg, FALSE);
return(Status);
}
}
Addr = MmGetPhysicalAddress(BaseAddress +
Offset->QuadPart - BaseOffset);
(*Page) = (PVOID)(ULONG)Addr.QuadPart;
MmReferencePage((*Page));
CcReleaseCacheSegment(Fcb->Bcb, CacheSeg, TRUE);
return(STATUS_SUCCESS);
}
else
{
/*
* Allocate a page, this is rather complicated by the possibility
* we might have to move other things out of memory
*/
(*Page) = MmAllocPage(0);
while ((*Page) == NULL)
{
MmWaitForFreePages();
(*Page) = MmAllocPage(0);
}
/*
* Create an mdl to hold the page we are going to read data into.
*/
Mdl = MmCreateMdl(NULL, NULL, PAGESIZE);
MmBuildMdlFromPages(Mdl, (PULONG)Page);
/*
* Call the FSD to read the page
*/
Status = IoPageRead(FileObject,
Mdl,
Offset,
&IoStatus,
FALSE);
return(Status);
}
}
NTSTATUS
MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
@ -256,8 +349,6 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
BOOLEAN Locked)
{
LARGE_INTEGER Offset;
IO_STATUS_BLOCK IoStatus;
PMDL Mdl;
PVOID Page;
NTSTATUS Status;
ULONG PAddress;
@ -461,41 +552,15 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
* If the entry is zero (and it can't change because we have
* locked the segment) then we need to load the page.
*/
/*
* Allocate a page, this is rather complicated by the possibility
* we might have to move other things out of memory
*/
Page = MmAllocPage(0);
while (Page == NULL)
{
MmUnlockSectionSegment(Segment);
MmUnlockSection(Section);
MmUnlockAddressSpace(AddressSpace);
MmWaitForFreePages();
MmLockAddressSpace(AddressSpace);
MmLockSection(Section);
MmLockSectionSegment(Segment);
Page = MmAllocPage(0);
}
/*
* Create an mdl to hold the page we are going to read data into.
*/
Mdl = MmCreateMdl(NULL, NULL, PAGESIZE);
MmBuildMdlFromPages(Mdl, (PULONG)&Page);
/*
* Release all our locks and read in the page from disk
*/
MmUnlockSectionSegment(Segment);
MmUnlockSection(Section);
MmUnlockAddressSpace(AddressSpace);
Status = IoPageRead(MemoryArea->Data.SectionData.Section->FileObject,
Mdl,
&Offset,
&IoStatus,
FALSE);
Status = MiReadPage(MemoryArea, &Offset, &Page);
if (!NT_SUCCESS(Status) && Status != STATUS_END_OF_FILE)
{
/*