mirror of
https://github.com/reactos/reactos.git
synced 2025-05-29 14:08:22 +00:00
- Fix several problems with the System PTE implementation, including the lack of locks.
- I also didn't fully like the idea of sticking "-1" into a 5-bit wide bitfield -- instead just stuff it as 0xFFFFF with a typecast. - This seems to be NT's MM_EMPTY_LIST that shows up in a couple of ASSERTs on the checked build. - This fixes several random crashes seen on my test boxes when mapping MDLs and using NP expansion VA. - Dedicated to Brüno. svn path=/trunk/; revision=41934
This commit is contained in:
parent
1279c44e6c
commit
0067e2c1a5
1 changed files with 36 additions and 8 deletions
|
@ -33,6 +33,7 @@ MiReserveAlignedSystemPtes(IN ULONG NumberOfPtes,
|
||||||
IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType,
|
IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType,
|
||||||
IN ULONG Alignment)
|
IN ULONG Alignment)
|
||||||
{
|
{
|
||||||
|
KIRQL OldIrql;
|
||||||
PMMPTE PointerPte, NextPte, PreviousPte;
|
PMMPTE PointerPte, NextPte, PreviousPte;
|
||||||
ULONG_PTR ClusterSize;
|
ULONG_PTR ClusterSize;
|
||||||
|
|
||||||
|
@ -41,11 +42,23 @@ MiReserveAlignedSystemPtes(IN ULONG NumberOfPtes,
|
||||||
//
|
//
|
||||||
ASSERT(Alignment <= PAGE_SIZE);
|
ASSERT(Alignment <= PAGE_SIZE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Lock the system PTE space
|
||||||
|
//
|
||||||
|
OldIrql = KeAcquireQueuedSpinLock(LockQueueSystemSpaceLock);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Get the first free cluster and make sure we have PTEs available
|
// Get the first free cluster and make sure we have PTEs available
|
||||||
//
|
//
|
||||||
PointerPte = &MmFirstFreeSystemPte[SystemPtePoolType];
|
PointerPte = &MmFirstFreeSystemPte[SystemPtePoolType];
|
||||||
if (PointerPte->u.List.NextEntry == -1) return NULL;
|
if (PointerPte->u.List.NextEntry == ((ULONG)0xFFFFF))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Fail
|
||||||
|
//
|
||||||
|
KeReleaseQueuedSpinLock(LockQueueSystemSpaceLock, OldIrql);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Now move to the first free system PTE cluster
|
// Now move to the first free system PTE cluster
|
||||||
|
@ -96,6 +109,7 @@ MiReserveAlignedSystemPtes(IN ULONG NumberOfPtes,
|
||||||
// Decrement the free count and move to the next starting PTE
|
// Decrement the free count and move to the next starting PTE
|
||||||
//
|
//
|
||||||
MmTotalFreeSystemPtes[SystemPtePoolType] -= NumberOfPtes;
|
MmTotalFreeSystemPtes[SystemPtePoolType] -= NumberOfPtes;
|
||||||
|
KeReleaseQueuedSpinLock(LockQueueSystemSpaceLock, OldIrql);
|
||||||
PointerPte += (ClusterSize - NumberOfPtes);
|
PointerPte += (ClusterSize - NumberOfPtes);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -126,7 +140,14 @@ MiReserveAlignedSystemPtes(IN ULONG NumberOfPtes,
|
||||||
//
|
//
|
||||||
// We couldn't find what you wanted -- is this the last cluster?
|
// We couldn't find what you wanted -- is this the last cluster?
|
||||||
//
|
//
|
||||||
if (PointerPte->u.List.NextEntry == -1) return NULL;
|
if (PointerPte->u.List.NextEntry == ((ULONG)0xFFFFF))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Fail
|
||||||
|
//
|
||||||
|
KeReleaseQueuedSpinLock(LockQueueSystemSpaceLock, OldIrql);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Go to the next cluster
|
// Go to the next cluster
|
||||||
|
@ -164,20 +185,27 @@ MiReleaseSystemPtes(IN PMMPTE StartingPte,
|
||||||
IN ULONG NumberOfPtes,
|
IN ULONG NumberOfPtes,
|
||||||
IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
|
IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
|
||||||
{
|
{
|
||||||
|
KIRQL OldIrql;
|
||||||
ULONG_PTR ClusterSize, CurrentSize;
|
ULONG_PTR ClusterSize, CurrentSize;
|
||||||
PMMPTE CurrentPte, NextPte, PointerPte;
|
PMMPTE CurrentPte, NextPte, PointerPte;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check to make sure the PTE address is within bounds.
|
// Check to make sure the PTE address is within bounds
|
||||||
//
|
//
|
||||||
ASSERT(NumberOfPtes != 0);
|
ASSERT(NumberOfPtes != 0);
|
||||||
ASSERT(StartingPte >= MmSystemPtesStart[SystemPtePoolType]);
|
ASSERT(StartingPte >= MmSystemPtesStart[SystemPtePoolType]);
|
||||||
ASSERT(StartingPte <= MmSystemPtesEnd[SystemPtePoolType]);
|
ASSERT(StartingPte <= MmSystemPtesEnd[SystemPtePoolType]);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Zero PTEs.
|
// Zero PTEs
|
||||||
//
|
//
|
||||||
RtlZeroMemory(StartingPte, NumberOfPtes * sizeof (MMPTE));
|
RtlZeroMemory(StartingPte, NumberOfPtes * sizeof(MMPTE));
|
||||||
|
CurrentSize = (ULONG_PTR)(StartingPte - MmSystemPteBase);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Acquire the system PTE lock
|
||||||
|
//
|
||||||
|
OldIrql = KeAcquireQueuedSpinLock(LockQueueSystemSpaceLock);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Increase availability
|
// Increase availability
|
||||||
|
@ -187,7 +215,6 @@ MiReleaseSystemPtes(IN PMMPTE StartingPte,
|
||||||
//
|
//
|
||||||
// Get the free cluster and start going through them
|
// Get the free cluster and start going through them
|
||||||
//
|
//
|
||||||
CurrentSize = (ULONG_PTR)(StartingPte - MmSystemPteBase);
|
|
||||||
CurrentPte = &MmFirstFreeSystemPte[SystemPtePoolType];
|
CurrentPte = &MmFirstFreeSystemPte[SystemPtePoolType];
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
|
@ -201,7 +228,7 @@ MiReleaseSystemPtes(IN PMMPTE StartingPte,
|
||||||
// Sanity check
|
// Sanity check
|
||||||
//
|
//
|
||||||
ASSERT(((StartingPte + NumberOfPtes) <= PointerPte) ||
|
ASSERT(((StartingPte + NumberOfPtes) <= PointerPte) ||
|
||||||
(CurrentPte->u.List.NextEntry == -1));
|
(CurrentPte->u.List.NextEntry == ((ULONG)0xFFFFF)));
|
||||||
|
|
||||||
//
|
//
|
||||||
// Get the next cluster in case it's the one
|
// Get the next cluster in case it's the one
|
||||||
|
@ -312,6 +339,7 @@ MiReleaseSystemPtes(IN PMMPTE StartingPte,
|
||||||
//
|
//
|
||||||
// We released the PTEs into their cluster (and optimized the list)
|
// We released the PTEs into their cluster (and optimized the list)
|
||||||
//
|
//
|
||||||
|
KeReleaseQueuedSpinLock(LockQueueSystemSpaceLock, OldIrql);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,7 +378,7 @@ MiInitializeSystemPtes(IN PMMPTE StartingPte,
|
||||||
//
|
//
|
||||||
// Make the first entry free and link it
|
// Make the first entry free and link it
|
||||||
//
|
//
|
||||||
StartingPte->u.List.NextEntry = -1;
|
StartingPte->u.List.NextEntry = ((ULONG)0xFFFFF);
|
||||||
MmFirstFreeSystemPte[PoolType].u.Long = 0;
|
MmFirstFreeSystemPte[PoolType].u.Long = 0;
|
||||||
MmFirstFreeSystemPte[PoolType].u.List.NextEntry = StartingPte -
|
MmFirstFreeSystemPte[PoolType].u.List.NextEntry = StartingPte -
|
||||||
MmSystemPteBase;
|
MmSystemPteBase;
|
||||||
|
|
Loading…
Reference in a new issue