mirror of
https://github.com/reactos/reactos.git
synced 2024-09-28 13:34:53 +00:00
[NTOSKRNL] Drop the VACB lock.
This has have several benefits for ReactOS Cc: - It helps reducing potential deadlocks situations in Cc - It speeds up ReactOS by reducing locks - It gets us a bit closer to Windows VACB CORE-14349
This commit is contained in:
parent
40017a54f9
commit
953dc72dad
|
@ -251,12 +251,14 @@ CcPurgeCacheSection (
|
||||||
|
|
||||||
while (!IsListEmpty(&FreeList))
|
while (!IsListEmpty(&FreeList))
|
||||||
{
|
{
|
||||||
|
ULONG Refs;
|
||||||
|
|
||||||
Vacb = CONTAINING_RECORD(RemoveHeadList(&FreeList),
|
Vacb = CONTAINING_RECORD(RemoveHeadList(&FreeList),
|
||||||
ROS_VACB,
|
ROS_VACB,
|
||||||
CacheMapVacbListEntry);
|
CacheMapVacbListEntry);
|
||||||
InitializeListHead(&Vacb->CacheMapVacbListEntry);
|
InitializeListHead(&Vacb->CacheMapVacbListEntry);
|
||||||
CcRosVacbDecRefCount(Vacb);
|
Refs = CcRosVacbDecRefCount(Vacb);
|
||||||
CcRosInternalFreeVacb(Vacb);
|
ASSERT(Refs == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Success;
|
return Success;
|
||||||
|
|
|
@ -215,7 +215,6 @@ CcPinRead (
|
||||||
|
|
||||||
iBcb->Pinned = TRUE;
|
iBcb->Pinned = TRUE;
|
||||||
iBcb->Vacb->PinCount++;
|
iBcb->Vacb->PinCount++;
|
||||||
CcRosReleaseVacbLock(iBcb->Vacb);
|
|
||||||
|
|
||||||
if (Flags & PIN_EXCLUSIVE)
|
if (Flags & PIN_EXCLUSIVE)
|
||||||
{
|
{
|
||||||
|
@ -308,7 +307,6 @@ CcUnpinDataForThread (
|
||||||
{
|
{
|
||||||
ExReleaseResourceForThreadLite(&iBcb->Lock, ResourceThreadId);
|
ExReleaseResourceForThreadLite(&iBcb->Lock, ResourceThreadId);
|
||||||
iBcb->Pinned = FALSE;
|
iBcb->Pinned = FALSE;
|
||||||
CcRosAcquireVacbLock(iBcb->Vacb, NULL);
|
|
||||||
iBcb->Vacb->PinCount--;
|
iBcb->Vacb->PinCount--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,7 +358,6 @@ CcUnpinRepinnedBcb (
|
||||||
IoStatus->Information = 0;
|
IoStatus->Information = 0;
|
||||||
if (WriteThrough)
|
if (WriteThrough)
|
||||||
{
|
{
|
||||||
CcRosAcquireVacbLock(iBcb->Vacb, NULL);
|
|
||||||
if (iBcb->Vacb->Dirty)
|
if (iBcb->Vacb->Dirty)
|
||||||
{
|
{
|
||||||
IoStatus->Status = CcRosFlushVacb(iBcb->Vacb);
|
IoStatus->Status = CcRosFlushVacb(iBcb->Vacb);
|
||||||
|
@ -369,7 +366,6 @@ CcUnpinRepinnedBcb (
|
||||||
{
|
{
|
||||||
IoStatus->Status = STATUS_SUCCESS;
|
IoStatus->Status = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
CcRosReleaseVacbLock(iBcb->Vacb);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -380,7 +376,6 @@ CcUnpinRepinnedBcb (
|
||||||
{
|
{
|
||||||
ExReleaseResourceLite(&iBcb->Lock);
|
ExReleaseResourceLite(&iBcb->Lock);
|
||||||
iBcb->Pinned = FALSE;
|
iBcb->Pinned = FALSE;
|
||||||
CcRosAcquireVacbLock(iBcb->Vacb, NULL);
|
|
||||||
iBcb->Vacb->PinCount--;
|
iBcb->Vacb->PinCount--;
|
||||||
ASSERT(iBcb->Vacb->PinCount == 0);
|
ASSERT(iBcb->Vacb->PinCount == 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,6 +90,11 @@ ULONG CcRosVacbDecRefCount_(PROS_VACB vacb, PCSTR file, INT line)
|
||||||
file, line, vacb, Refs, vacb->Dirty, vacb->PageOut);
|
file, line, vacb, Refs, vacb->Dirty, vacb->PageOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Refs == 0)
|
||||||
|
{
|
||||||
|
CcRosInternalFreeVacb(vacb);
|
||||||
|
}
|
||||||
|
|
||||||
return Refs;
|
return Refs;
|
||||||
}
|
}
|
||||||
ULONG CcRosVacbGetRefCount_(PROS_VACB vacb, PCSTR file, INT line)
|
ULONG CcRosVacbGetRefCount_(PROS_VACB vacb, PCSTR file, INT line)
|
||||||
|
@ -107,9 +112,6 @@ ULONG CcRosVacbGetRefCount_(PROS_VACB vacb, PCSTR file, INT line)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
CcRosInternalFreeVacb(PROS_VACB Vacb);
|
|
||||||
|
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
@ -187,12 +189,10 @@ CcRosFlushDirtyPages (
|
||||||
PROS_VACB current;
|
PROS_VACB current;
|
||||||
BOOLEAN Locked;
|
BOOLEAN Locked;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
LARGE_INTEGER ZeroTimeout;
|
|
||||||
|
|
||||||
DPRINT("CcRosFlushDirtyPages(Target %lu)\n", Target);
|
DPRINT("CcRosFlushDirtyPages(Target %lu)\n", Target);
|
||||||
|
|
||||||
(*Count) = 0;
|
(*Count) = 0;
|
||||||
ZeroTimeout.QuadPart = 0;
|
|
||||||
|
|
||||||
KeEnterCriticalRegion();
|
KeEnterCriticalRegion();
|
||||||
KeAcquireGuardedMutex(&ViewLock);
|
KeAcquireGuardedMutex(&ViewLock);
|
||||||
|
@ -228,22 +228,11 @@ CcRosFlushDirtyPages (
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = CcRosAcquireVacbLock(current,
|
|
||||||
Wait ? NULL : &ZeroTimeout);
|
|
||||||
if (Status != STATUS_SUCCESS)
|
|
||||||
{
|
|
||||||
current->SharedCacheMap->Callbacks->ReleaseFromLazyWrite(
|
|
||||||
current->SharedCacheMap->LazyWriteContext);
|
|
||||||
CcRosVacbDecRefCount(current);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT(current->Dirty);
|
ASSERT(current->Dirty);
|
||||||
|
|
||||||
/* One reference is added above */
|
/* One reference is added above */
|
||||||
if (CcRosVacbGetRefCount(current) > 2)
|
if (CcRosVacbGetRefCount(current) > 2)
|
||||||
{
|
{
|
||||||
CcRosReleaseVacbLock(current);
|
|
||||||
current->SharedCacheMap->Callbacks->ReleaseFromLazyWrite(
|
current->SharedCacheMap->Callbacks->ReleaseFromLazyWrite(
|
||||||
current->SharedCacheMap->LazyWriteContext);
|
current->SharedCacheMap->LazyWriteContext);
|
||||||
CcRosVacbDecRefCount(current);
|
CcRosVacbDecRefCount(current);
|
||||||
|
@ -254,7 +243,6 @@ CcRosFlushDirtyPages (
|
||||||
|
|
||||||
Status = CcRosFlushVacb(current);
|
Status = CcRosFlushVacb(current);
|
||||||
|
|
||||||
CcRosReleaseVacbLock(current);
|
|
||||||
current->SharedCacheMap->Callbacks->ReleaseFromLazyWrite(
|
current->SharedCacheMap->Callbacks->ReleaseFromLazyWrite(
|
||||||
current->SharedCacheMap->LazyWriteContext);
|
current->SharedCacheMap->LazyWriteContext);
|
||||||
|
|
||||||
|
@ -410,13 +398,15 @@ retry:
|
||||||
|
|
||||||
while (!IsListEmpty(&FreeList))
|
while (!IsListEmpty(&FreeList))
|
||||||
{
|
{
|
||||||
|
ULONG Refs;
|
||||||
|
|
||||||
current_entry = RemoveHeadList(&FreeList);
|
current_entry = RemoveHeadList(&FreeList);
|
||||||
current = CONTAINING_RECORD(current_entry,
|
current = CONTAINING_RECORD(current_entry,
|
||||||
ROS_VACB,
|
ROS_VACB,
|
||||||
CacheMapVacbListEntry);
|
CacheMapVacbListEntry);
|
||||||
InitializeListHead(¤t->CacheMapVacbListEntry);
|
InitializeListHead(¤t->CacheMapVacbListEntry);
|
||||||
CcRosVacbDecRefCount(current);
|
Refs = CcRosVacbDecRefCount(current);
|
||||||
CcRosInternalFreeVacb(current);
|
ASSERT(Refs == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("Evicted %lu cache pages\n", (*NrFreed));
|
DPRINT("Evicted %lu cache pages\n", (*NrFreed));
|
||||||
|
@ -457,8 +447,6 @@ CcRosReleaseVacb (
|
||||||
Refs = CcRosVacbDecRefCount(Vacb);
|
Refs = CcRosVacbDecRefCount(Vacb);
|
||||||
ASSERT(Refs > 0);
|
ASSERT(Refs > 0);
|
||||||
|
|
||||||
CcRosReleaseVacbLock(Vacb);
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,7 +482,6 @@ CcRosLookupVacb (
|
||||||
CcRosVacbIncRefCount(current);
|
CcRosVacbIncRefCount(current);
|
||||||
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql);
|
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql);
|
||||||
KeReleaseGuardedMutex(&ViewLock);
|
KeReleaseGuardedMutex(&ViewLock);
|
||||||
CcRosAcquireVacbLock(current, NULL);
|
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
if (current->FileOffset.QuadPart > FileOffset)
|
if (current->FileOffset.QuadPart > FileOffset)
|
||||||
|
@ -718,6 +705,7 @@ CcRosCreateVacb (
|
||||||
PLIST_ENTRY current_entry;
|
PLIST_ENTRY current_entry;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
ULONG Refs;
|
||||||
|
|
||||||
ASSERT(SharedCacheMap);
|
ASSERT(SharedCacheMap);
|
||||||
|
|
||||||
|
@ -745,7 +733,6 @@ CcRosCreateVacb (
|
||||||
current->MappedCount = 0;
|
current->MappedCount = 0;
|
||||||
current->ReferenceCount = 0;
|
current->ReferenceCount = 0;
|
||||||
current->PinCount = 0;
|
current->PinCount = 0;
|
||||||
KeInitializeMutex(¤t->Mutex, 0);
|
|
||||||
InitializeListHead(¤t->CacheMapVacbListEntry);
|
InitializeListHead(¤t->CacheMapVacbListEntry);
|
||||||
InitializeListHead(¤t->DirtyVacbListEntry);
|
InitializeListHead(¤t->DirtyVacbListEntry);
|
||||||
InitializeListHead(¤t->VacbLruListEntry);
|
InitializeListHead(¤t->VacbLruListEntry);
|
||||||
|
@ -760,7 +747,6 @@ CcRosCreateVacb (
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
CcRosAcquireVacbLock(current, NULL);
|
|
||||||
KeAcquireGuardedMutex(&ViewLock);
|
KeAcquireGuardedMutex(&ViewLock);
|
||||||
|
|
||||||
*Vacb = current;
|
*Vacb = current;
|
||||||
|
@ -792,12 +778,12 @@ CcRosCreateVacb (
|
||||||
current);
|
current);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
CcRosVacbDecRefCount(*Vacb);
|
|
||||||
CcRosReleaseVacbLock(*Vacb);
|
|
||||||
KeReleaseGuardedMutex(&ViewLock);
|
KeReleaseGuardedMutex(&ViewLock);
|
||||||
CcRosInternalFreeVacb(*Vacb);
|
|
||||||
|
Refs = CcRosVacbDecRefCount(*Vacb);
|
||||||
|
ASSERT(Refs == 0);
|
||||||
|
|
||||||
*Vacb = current;
|
*Vacb = current;
|
||||||
CcRosAcquireVacbLock(current, NULL);
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
if (current->FileOffset.QuadPart < FileOffset)
|
if (current->FileOffset.QuadPart < FileOffset)
|
||||||
|
@ -1111,7 +1097,6 @@ CcRosDeleteFileCache (
|
||||||
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql);
|
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql);
|
||||||
|
|
||||||
current = CONTAINING_RECORD(current_entry, ROS_VACB, CacheMapVacbListEntry);
|
current = CONTAINING_RECORD(current_entry, ROS_VACB, CacheMapVacbListEntry);
|
||||||
CcRosAcquireVacbLock(current, NULL);
|
|
||||||
RemoveEntryList(¤t->VacbLruListEntry);
|
RemoveEntryList(¤t->VacbLruListEntry);
|
||||||
InitializeListHead(¤t->VacbLruListEntry);
|
InitializeListHead(¤t->VacbLruListEntry);
|
||||||
if (current->Dirty)
|
if (current->Dirty)
|
||||||
|
@ -1122,7 +1107,6 @@ CcRosDeleteFileCache (
|
||||||
DPRINT1("Freeing dirty VACB\n");
|
DPRINT1("Freeing dirty VACB\n");
|
||||||
}
|
}
|
||||||
InsertHeadList(&FreeList, ¤t->CacheMapVacbListEntry);
|
InsertHeadList(&FreeList, ¤t->CacheMapVacbListEntry);
|
||||||
CcRosReleaseVacbLock(current);
|
|
||||||
|
|
||||||
KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldIrql);
|
KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldIrql);
|
||||||
}
|
}
|
||||||
|
@ -1136,11 +1120,13 @@ CcRosDeleteFileCache (
|
||||||
|
|
||||||
while (!IsListEmpty(&FreeList))
|
while (!IsListEmpty(&FreeList))
|
||||||
{
|
{
|
||||||
|
ULONG Refs;
|
||||||
|
|
||||||
current_entry = RemoveTailList(&FreeList);
|
current_entry = RemoveTailList(&FreeList);
|
||||||
current = CONTAINING_RECORD(current_entry, ROS_VACB, CacheMapVacbListEntry);
|
current = CONTAINING_RECORD(current_entry, ROS_VACB, CacheMapVacbListEntry);
|
||||||
InitializeListHead(¤t->CacheMapVacbListEntry);
|
InitializeListHead(¤t->CacheMapVacbListEntry);
|
||||||
CcRosVacbDecRefCount(current);
|
Refs = CcRosVacbDecRefCount(current);
|
||||||
CcRosInternalFreeVacb(current);
|
ASSERT(Refs == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
|
OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
|
||||||
|
|
|
@ -217,12 +217,9 @@ typedef struct _ROS_VACB
|
||||||
LIST_ENTRY VacbLruListEntry;
|
LIST_ENTRY VacbLruListEntry;
|
||||||
/* Offset in the file which this view maps. */
|
/* Offset in the file which this view maps. */
|
||||||
LARGE_INTEGER FileOffset;
|
LARGE_INTEGER FileOffset;
|
||||||
/* Mutex */
|
|
||||||
KMUTEX Mutex;
|
|
||||||
/* Number of references. */
|
/* Number of references. */
|
||||||
volatile ULONG ReferenceCount;
|
volatile ULONG ReferenceCount;
|
||||||
/* How many times was it pinned? */
|
/* How many times was it pinned? */
|
||||||
_Guarded_by_(Mutex)
|
|
||||||
LONG PinCount;
|
LONG PinCount;
|
||||||
/* Pointer to the shared cache map for the file which this view maps data for. */
|
/* Pointer to the shared cache map for the file which this view maps data for. */
|
||||||
PROS_SHARED_CACHE_MAP SharedCacheMap;
|
PROS_SHARED_CACHE_MAP SharedCacheMap;
|
||||||
|
@ -470,28 +467,9 @@ VOID
|
||||||
CcPerformReadAhead(
|
CcPerformReadAhead(
|
||||||
IN PFILE_OBJECT FileObject);
|
IN PFILE_OBJECT FileObject);
|
||||||
|
|
||||||
FORCEINLINE
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CcRosAcquireVacbLock(
|
CcRosInternalFreeVacb(
|
||||||
_Inout_ PROS_VACB Vacb,
|
IN PROS_VACB Vacb);
|
||||||
_In_ PLARGE_INTEGER Timeout)
|
|
||||||
{
|
|
||||||
NTSTATUS Status;
|
|
||||||
Status = KeWaitForSingleObject(&Vacb->Mutex,
|
|
||||||
Executive,
|
|
||||||
KernelMode,
|
|
||||||
FALSE,
|
|
||||||
Timeout);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCEINLINE
|
|
||||||
VOID
|
|
||||||
CcRosReleaseVacbLock(
|
|
||||||
_Inout_ PROS_VACB Vacb)
|
|
||||||
{
|
|
||||||
KeReleaseMutex(&Vacb->Mutex, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
|
@ -545,6 +523,19 @@ CcRosVacbGetRefCount_(
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define CcRosVacbIncRefCount(vacb) InterlockedIncrement((PLONG)&(vacb)->ReferenceCount)
|
#define CcRosVacbIncRefCount(vacb) InterlockedIncrement((PLONG)&(vacb)->ReferenceCount)
|
||||||
#define CcRosVacbDecRefCount(vacb) InterlockedDecrement((PLONG)&(vacb)->ReferenceCount)
|
FORCEINLINE
|
||||||
|
ULONG
|
||||||
|
CcRosVacbDecRefCount(
|
||||||
|
PROS_VACB vacb)
|
||||||
|
{
|
||||||
|
ULONG Refs;
|
||||||
|
|
||||||
|
Refs = InterlockedDecrement((PLONG)&vacb->ReferenceCount);
|
||||||
|
if (Refs == 0)
|
||||||
|
{
|
||||||
|
CcRosInternalFreeVacb(vacb);
|
||||||
|
}
|
||||||
|
return Refs;
|
||||||
|
}
|
||||||
#define CcRosVacbGetRefCount(vacb) InterlockedCompareExchange((PLONG)&(vacb)->ReferenceCount, 0, 0)
|
#define CcRosVacbGetRefCount(vacb) InterlockedCompareExchange((PLONG)&(vacb)->ReferenceCount, 0, 0)
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue