mirror of
https://github.com/reactos/reactos.git
synced 2025-06-27 19:19:43 +00:00
[NTOSKRNL] Use interlocked operations for VACB reference counting.
CORE-14480 CORE-14285
This commit is contained in:
parent
dea9c291ab
commit
14b05e65ff
3 changed files with 60 additions and 23 deletions
|
@ -207,6 +207,8 @@ CcPurgeCacheSection (
|
||||||
ListEntry = SharedCacheMap->CacheMapVacbListHead.Flink;
|
ListEntry = SharedCacheMap->CacheMapVacbListHead.Flink;
|
||||||
while (ListEntry != &SharedCacheMap->CacheMapVacbListHead)
|
while (ListEntry != &SharedCacheMap->CacheMapVacbListHead)
|
||||||
{
|
{
|
||||||
|
ULONG Refs;
|
||||||
|
|
||||||
Vacb = CONTAINING_RECORD(ListEntry, ROS_VACB, CacheMapVacbListEntry);
|
Vacb = CONTAINING_RECORD(ListEntry, ROS_VACB, CacheMapVacbListEntry);
|
||||||
ListEntry = ListEntry->Flink;
|
ListEntry = ListEntry->Flink;
|
||||||
|
|
||||||
|
@ -225,15 +227,16 @@ CcPurgeCacheSection (
|
||||||
/* Still in use, it cannot be purged, fail
|
/* Still in use, it cannot be purged, fail
|
||||||
* Allow one ref: VACB is supposed to be always 1-referenced
|
* Allow one ref: VACB is supposed to be always 1-referenced
|
||||||
*/
|
*/
|
||||||
if ((Vacb->ReferenceCount > 1 && !Vacb->Dirty) ||
|
Refs = CcRosVacbGetRefCount(Vacb);
|
||||||
(Vacb->ReferenceCount > 2 && Vacb->Dirty))
|
if ((Refs > 1 && !Vacb->Dirty) ||
|
||||||
|
(Refs > 2 && Vacb->Dirty))
|
||||||
{
|
{
|
||||||
Success = FALSE;
|
Success = FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This VACB is in range, so unlink it and mark for free */
|
/* This VACB is in range, so unlink it and mark for free */
|
||||||
ASSERT(Vacb->ReferenceCount == 1 || Vacb->Dirty);
|
ASSERT(Refs == 1 || Vacb->Dirty);
|
||||||
RemoveEntryList(&Vacb->VacbLruListEntry);
|
RemoveEntryList(&Vacb->VacbLruListEntry);
|
||||||
if (Vacb->Dirty)
|
if (Vacb->Dirty)
|
||||||
{
|
{
|
||||||
|
|
|
@ -65,25 +65,45 @@ KSPIN_LOCK CcDeferredWriteSpinLock;
|
||||||
LIST_ENTRY CcCleanSharedCacheMapList;
|
LIST_ENTRY CcCleanSharedCacheMapList;
|
||||||
|
|
||||||
#if DBG
|
#if DBG
|
||||||
VOID CcRosVacbIncRefCount_(PROS_VACB vacb, PCSTR file, INT line)
|
ULONG CcRosVacbIncRefCount_(PROS_VACB vacb, PCSTR file, INT line)
|
||||||
{
|
{
|
||||||
++vacb->ReferenceCount;
|
ULONG Refs;
|
||||||
|
|
||||||
|
Refs = InterlockedIncrement((PLONG)&vacb->ReferenceCount);
|
||||||
if (vacb->SharedCacheMap->Trace)
|
if (vacb->SharedCacheMap->Trace)
|
||||||
{
|
{
|
||||||
DbgPrint("(%s:%i) VACB %p ++RefCount=%lu, Dirty %u, PageOut %lu\n",
|
DbgPrint("(%s:%i) VACB %p ++RefCount=%lu, Dirty %u, PageOut %lu\n",
|
||||||
file, line, vacb, vacb->ReferenceCount, vacb->Dirty, vacb->PageOut);
|
file, line, vacb, Refs, vacb->Dirty, vacb->PageOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Refs;
|
||||||
}
|
}
|
||||||
VOID CcRosVacbDecRefCount_(PROS_VACB vacb, PCSTR file, INT line)
|
ULONG CcRosVacbDecRefCount_(PROS_VACB vacb, PCSTR file, INT line)
|
||||||
{
|
{
|
||||||
ASSERT(vacb->ReferenceCount != 0);
|
ULONG Refs;
|
||||||
--vacb->ReferenceCount;
|
|
||||||
ASSERT(!(vacb->ReferenceCount == 0 && vacb->Dirty));
|
Refs = InterlockedDecrement((PLONG)&vacb->ReferenceCount);
|
||||||
|
ASSERT(!(Refs == 0 && vacb->Dirty));
|
||||||
if (vacb->SharedCacheMap->Trace)
|
if (vacb->SharedCacheMap->Trace)
|
||||||
{
|
{
|
||||||
DbgPrint("(%s:%i) VACB %p --RefCount=%lu, Dirty %u, PageOut %lu\n",
|
DbgPrint("(%s:%i) VACB %p --RefCount=%lu, Dirty %u, PageOut %lu\n",
|
||||||
file, line, vacb, vacb->ReferenceCount, vacb->Dirty, vacb->PageOut);
|
file, line, vacb, Refs, vacb->Dirty, vacb->PageOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Refs;
|
||||||
|
}
|
||||||
|
ULONG CcRosVacbGetRefCount_(PROS_VACB vacb, PCSTR file, INT line)
|
||||||
|
{
|
||||||
|
ULONG Refs;
|
||||||
|
|
||||||
|
Refs = InterlockedCompareExchange((PLONG)&vacb->ReferenceCount, 0, 0);
|
||||||
|
if (vacb->SharedCacheMap->Trace)
|
||||||
|
{
|
||||||
|
DbgPrint("(%s:%i) VACB %p ==RefCount=%lu, Dirty %u, PageOut %lu\n",
|
||||||
|
file, line, vacb, Refs, vacb->Dirty, vacb->PageOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Refs;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -221,7 +241,7 @@ CcRosFlushDirtyPages (
|
||||||
ASSERT(current->Dirty);
|
ASSERT(current->Dirty);
|
||||||
|
|
||||||
/* One reference is added above */
|
/* One reference is added above */
|
||||||
if (current->ReferenceCount > 2)
|
if (CcRosVacbGetRefCount(current) > 2)
|
||||||
{
|
{
|
||||||
CcRosReleaseVacbLock(current);
|
CcRosReleaseVacbLock(current);
|
||||||
current->SharedCacheMap->Callbacks->ReleaseFromLazyWrite(
|
current->SharedCacheMap->Callbacks->ReleaseFromLazyWrite(
|
||||||
|
@ -311,6 +331,8 @@ retry:
|
||||||
current_entry = VacbLruListHead.Flink;
|
current_entry = VacbLruListHead.Flink;
|
||||||
while (current_entry != &VacbLruListHead)
|
while (current_entry != &VacbLruListHead)
|
||||||
{
|
{
|
||||||
|
ULONG Refs;
|
||||||
|
|
||||||
current = CONTAINING_RECORD(current_entry,
|
current = CONTAINING_RECORD(current_entry,
|
||||||
ROS_VACB,
|
ROS_VACB,
|
||||||
VacbLruListEntry);
|
VacbLruListEntry);
|
||||||
|
@ -342,14 +364,14 @@ retry:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dereference the VACB */
|
/* Dereference the VACB */
|
||||||
CcRosVacbDecRefCount(current);
|
Refs = CcRosVacbDecRefCount(current);
|
||||||
|
|
||||||
/* Check if we can free this entry now */
|
/* Check if we can free this entry now */
|
||||||
if (current->ReferenceCount < 2)
|
if (Refs < 2)
|
||||||
{
|
{
|
||||||
ASSERT(!current->Dirty);
|
ASSERT(!current->Dirty);
|
||||||
ASSERT(!current->MappedCount);
|
ASSERT(!current->MappedCount);
|
||||||
ASSERT(current->ReferenceCount == 1);
|
ASSERT(Refs == 1);
|
||||||
|
|
||||||
RemoveEntryList(¤t->CacheMapVacbListEntry);
|
RemoveEntryList(¤t->CacheMapVacbListEntry);
|
||||||
RemoveEntryList(¤t->VacbLruListEntry);
|
RemoveEntryList(¤t->VacbLruListEntry);
|
||||||
|
@ -409,6 +431,7 @@ CcRosReleaseVacb (
|
||||||
BOOLEAN Dirty,
|
BOOLEAN Dirty,
|
||||||
BOOLEAN Mapped)
|
BOOLEAN Mapped)
|
||||||
{
|
{
|
||||||
|
ULONG Refs;
|
||||||
ASSERT(SharedCacheMap);
|
ASSERT(SharedCacheMap);
|
||||||
|
|
||||||
DPRINT("CcRosReleaseVacb(SharedCacheMap 0x%p, Vacb 0x%p, Valid %u)\n",
|
DPRINT("CcRosReleaseVacb(SharedCacheMap 0x%p, Vacb 0x%p, Valid %u)\n",
|
||||||
|
@ -425,13 +448,13 @@ CcRosReleaseVacb (
|
||||||
{
|
{
|
||||||
Vacb->MappedCount++;
|
Vacb->MappedCount++;
|
||||||
}
|
}
|
||||||
CcRosVacbDecRefCount(Vacb);
|
Refs = CcRosVacbDecRefCount(Vacb);
|
||||||
if (Mapped && (Vacb->MappedCount == 1))
|
if (Mapped && (Vacb->MappedCount == 1))
|
||||||
{
|
{
|
||||||
CcRosVacbIncRefCount(Vacb);
|
CcRosVacbIncRefCount(Vacb);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(Vacb->ReferenceCount > 0);
|
ASSERT(Refs > 0);
|
||||||
|
|
||||||
CcRosReleaseVacbLock(Vacb);
|
CcRosReleaseVacbLock(Vacb);
|
||||||
|
|
||||||
|
@ -835,6 +858,7 @@ CcRosGetVacb (
|
||||||
{
|
{
|
||||||
PROS_VACB current;
|
PROS_VACB current;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
ULONG Refs;
|
||||||
|
|
||||||
ASSERT(SharedCacheMap);
|
ASSERT(SharedCacheMap);
|
||||||
|
|
||||||
|
@ -856,6 +880,8 @@ CcRosGetVacb (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Refs = CcRosVacbGetRefCount(current);
|
||||||
|
|
||||||
KeAcquireGuardedMutex(&ViewLock);
|
KeAcquireGuardedMutex(&ViewLock);
|
||||||
|
|
||||||
/* Move to the tail of the LRU list */
|
/* Move to the tail of the LRU list */
|
||||||
|
@ -873,7 +899,7 @@ CcRosGetVacb (
|
||||||
*Vacb = current;
|
*Vacb = current;
|
||||||
*BaseOffset = current->FileOffset.QuadPart;
|
*BaseOffset = current->FileOffset.QuadPart;
|
||||||
|
|
||||||
ASSERT(current->ReferenceCount > 1);
|
ASSERT(Refs > 1);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -220,7 +220,7 @@ typedef struct _ROS_VACB
|
||||||
/* Mutex */
|
/* Mutex */
|
||||||
KMUTEX Mutex;
|
KMUTEX Mutex;
|
||||||
/* Number of references. */
|
/* Number of references. */
|
||||||
ULONG ReferenceCount;
|
volatile ULONG ReferenceCount;
|
||||||
/* How many times was it pinned? */
|
/* How many times was it pinned? */
|
||||||
_Guarded_by_(Mutex)
|
_Guarded_by_(Mutex)
|
||||||
LONG PinCount;
|
LONG PinCount;
|
||||||
|
@ -523,20 +523,28 @@ IsPointInRange(
|
||||||
#if DBG
|
#if DBG
|
||||||
#define CcRosVacbIncRefCount(vacb) CcRosVacbIncRefCount_(vacb,__FILE__,__LINE__)
|
#define CcRosVacbIncRefCount(vacb) CcRosVacbIncRefCount_(vacb,__FILE__,__LINE__)
|
||||||
#define CcRosVacbDecRefCount(vacb) CcRosVacbDecRefCount_(vacb,__FILE__,__LINE__)
|
#define CcRosVacbDecRefCount(vacb) CcRosVacbDecRefCount_(vacb,__FILE__,__LINE__)
|
||||||
|
#define CcRosVacbGetRefCount(vacb) CcRosVacbGetRefCount_(vacb,__FILE__,__LINE__)
|
||||||
|
|
||||||
VOID
|
ULONG
|
||||||
CcRosVacbIncRefCount_(
|
CcRosVacbIncRefCount_(
|
||||||
PROS_VACB vacb,
|
PROS_VACB vacb,
|
||||||
PCSTR file,
|
PCSTR file,
|
||||||
INT line);
|
INT line);
|
||||||
|
|
||||||
VOID
|
ULONG
|
||||||
CcRosVacbDecRefCount_(
|
CcRosVacbDecRefCount_(
|
||||||
PROS_VACB vacb,
|
PROS_VACB vacb,
|
||||||
PCSTR file,
|
PCSTR file,
|
||||||
INT line);
|
INT line);
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
CcRosVacbGetRefCount_(
|
||||||
|
PROS_VACB vacb,
|
||||||
|
PCSTR file,
|
||||||
|
INT line);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define CcRosVacbIncRefCount(vacb) (++((vacb)->ReferenceCount))
|
#define CcRosVacbIncRefCount(vacb) InterlockedIncrement((PLONG)&(vacb)->ReferenceCount)
|
||||||
#define CcRosVacbDecRefCount(vacb) (--((vacb)->ReferenceCount))
|
#define CcRosVacbDecRefCount(vacb) InterlockedDecrement((PLONG)&(vacb)->ReferenceCount)
|
||||||
|
#define CcRosVacbGetRefCount(vacb) InterlockedCompareExchange((PLONG)&(vacb)->ReferenceCount, 0, 0)
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue