- The address space lock is a pushlock -- pushlocks can fail if callers are acquiring them without first disabling APCs, so they should always be acquired within a critical region. Fix the address space lock to do this.

- Don't keep track of the page table reference count table in the address space structure, nobody was using this.
- Instead of using either a global kernel pushlock for the kernel address space, and a per-process lock for process address space, always use a per-process lock (the kernel address space uses the idle process' lock).
- Instead of acquiring/releasing the lock by dereferencing the process which owns the address space, hold a pointer to the lock directly. This removes an extra dereference, and also allows the kernel lock to work (because kernel address space doesn't have an associated process).
- Inline the lock acquisition/release functions and the get-address-space functions.
- Measured a 20% performance boost during boot-up, and 150% during installation.
- Patch by Alex.

svn path=/trunk/; revision=33092
This commit is contained in:
Aleksey Bragin 2008-04-21 21:42:00 +00:00
parent 901badd513
commit 4f1c23c238
2 changed files with 73 additions and 102 deletions

View file

@ -254,9 +254,9 @@ typedef struct _MADDRESS_SPACE
{
PMEMORY_AREA MemoryAreaRoot;
PVOID LowestAddress;
struct _EPROCESS* Process;
PEPROCESS Process;
PUSHORT PageTableRefCountTable;
ULONG PageTableRefCountTableSize;
PEX_PUSH_LOCK Lock;
} MADDRESS_SPACE, *PMADDRESS_SPACE;
typedef struct
@ -392,26 +392,10 @@ typedef VOID
/* aspace.c ******************************************************************/
VOID
NTAPI
MmLockAddressSpace(PMADDRESS_SPACE AddressSpace);
VOID
NTAPI
MmUnlockAddressSpace(PMADDRESS_SPACE AddressSpace);
VOID
NTAPI
MmInitializeKernelAddressSpace(VOID);
PMADDRESS_SPACE
NTAPI
MmGetCurrentAddressSpace(VOID);
PMADDRESS_SPACE
NTAPI
MmGetKernelAddressSpace(VOID);
NTSTATUS
NTAPI
MmInitializeAddressSpace(
@ -1584,4 +1568,37 @@ MiSyncThreadProcessViews(IN PVOID Process,
MmUpdatePageDir((PEPROCESS)Process, Address, Size);
}
extern MADDRESS_SPACE MmKernelAddressSpace;
FORCEINLINE
VOID
MmLockAddressSpace(PMADDRESS_SPACE AddressSpace)
{
KeEnterCriticalRegion();
ExAcquirePushLockExclusive(AddressSpace->Lock);
}
FORCEINLINE
VOID
MmUnlockAddressSpace(PMADDRESS_SPACE AddressSpace)
{
ExReleasePushLock(AddressSpace->Lock);
KeLeaveCriticalRegion();
}
FORCEINLINE
PMADDRESS_SPACE
MmGetCurrentAddressSpace(VOID)
{
return (PMADDRESS_SPACE)&((PEPROCESS)KeGetCurrentThread()->ApcState.Process)->VadRoot;
}
FORCEINLINE
PMADDRESS_SPACE
MmGetKernelAddressSpace(VOID)
{
return &MmKernelAddressSpace;
}
#endif

View file

@ -19,59 +19,19 @@
/* GLOBALS ******************************************************************/
static MADDRESS_SPACE KernelAddressSpace;
EX_PUSH_LOCK KernelAddressSpaceLock;
MADDRESS_SPACE MmKernelAddressSpace;
ULONGLONG Cycles;
ULONG TimeDelta;
/* FUNCTIONS *****************************************************************/
VOID
NTAPI
MmLockAddressSpace(PMADDRESS_SPACE AddressSpace)
{
if (AddressSpace->Process)
{
ExAcquirePushLockExclusive((PEX_PUSH_LOCK)&AddressSpace->Process->AddressCreationLock);
}
else
{
ExAcquirePushLockExclusive(&KernelAddressSpaceLock);
}
}
VOID
NTAPI
MmUnlockAddressSpace(PMADDRESS_SPACE AddressSpace)
{
if (AddressSpace->Process)
{
ExReleasePushLock((PEX_PUSH_LOCK)&AddressSpace->Process->AddressCreationLock);
}
else
{
ExReleasePushLock(&KernelAddressSpaceLock);
}
}
VOID
INIT_FUNCTION
NTAPI
MmInitializeKernelAddressSpace(VOID)
{
MmInitializeAddressSpace(NULL, &KernelAddressSpace);
}
PMADDRESS_SPACE
NTAPI
MmGetCurrentAddressSpace(VOID)
{
return((PMADDRESS_SPACE)&(PsGetCurrentProcess())->VadRoot);
}
PMADDRESS_SPACE
NTAPI
MmGetKernelAddressSpace(VOID)
{
return(&KernelAddressSpace);
MmInitializeAddressSpace(NULL, &MmKernelAddressSpace);
}
NTSTATUS
@ -79,51 +39,45 @@ NTAPI
MmInitializeAddressSpace(PEPROCESS Process,
PMADDRESS_SPACE AddressSpace)
{
AddressSpace->MemoryAreaRoot = NULL;
if (Process)
{
ExInitializePushLock((PULONG_PTR)&Process->AddressCreationLock);
}
else
{
ExInitializePushLock((PULONG_PTR)&KernelAddressSpaceLock);
}
if (Process != NULL)
{
AddressSpace->LowestAddress = MM_LOWEST_USER_ADDRESS;
}
else
{
AddressSpace->LowestAddress = MmSystemRangeStart;
}
AddressSpace->Process = Process;
if (Process != NULL)
{
ULONG Count;
Count = MiGetUserPageDirectoryCount();
AddressSpace->PageTableRefCountTable =
ExAllocatePoolWithTag(NonPagedPool, Count * sizeof(USHORT),
TAG_PTRC);
RtlZeroMemory(AddressSpace->PageTableRefCountTable, Count * sizeof(USHORT));
AddressSpace->PageTableRefCountTableSize = Count;
}
else
{
AddressSpace->PageTableRefCountTable = NULL;
AddressSpace->PageTableRefCountTableSize = 0;
}
return(STATUS_SUCCESS);
ULONG Count;
AddressSpace->MemoryAreaRoot = NULL;
if (Process != NULL)
{
AddressSpace->LowestAddress = MM_LOWEST_USER_ADDRESS;
AddressSpace->Process = Process;
AddressSpace->Lock = (PEX_PUSH_LOCK)&Process->AddressCreationLock;
ExInitializePushLock((PULONG_PTR)AddressSpace->Lock);
Count = MiGetUserPageDirectoryCount();
AddressSpace->PageTableRefCountTable = ExAllocatePoolWithTag(NonPagedPool,
Count * sizeof(USHORT),
TAG_PTRC);
RtlZeroMemory(AddressSpace->PageTableRefCountTable, Count * sizeof(USHORT));
}
else
{
AddressSpace->LowestAddress = MmSystemRangeStart;
AddressSpace->Process = NULL;
AddressSpace->PageTableRefCountTable = NULL;
AddressSpace->Lock = (PEX_PUSH_LOCK)&PsGetCurrentProcess()->AddressCreationLock;
ExInitializePushLock((PULONG_PTR)AddressSpace->Lock);
}
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
MmDestroyAddressSpace(PMADDRESS_SPACE AddressSpace)
{
if (AddressSpace->PageTableRefCountTable != NULL)
{
ExFreePool(AddressSpace->PageTableRefCountTable);
}
return(STATUS_SUCCESS);
if (AddressSpace->PageTableRefCountTable)
{
ExFreePool(AddressSpace->PageTableRefCountTable);
}
return STATUS_SUCCESS;
}
/* EOF */