[NTOSKRNL] When marking a VACB dirty on unmap/unpin, use CcRosMarkDirtyVacb().

This should help reducing race conditions with lazy writer, and thus reduce random BSODs.

CORE-14263
This commit is contained in:
Pierre Schweitzer 2018-01-27 10:57:50 +01:00
parent 1971137a5f
commit a3d78067ab
No known key found for this signature in database
GPG key ID: 7545556C3D585B0B

View file

@ -517,26 +517,25 @@ CcRosReleaseVacb (
BOOLEAN Mapped) BOOLEAN Mapped)
{ {
BOOLEAN WasDirty; BOOLEAN WasDirty;
KIRQL oldIrql;
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",
SharedCacheMap, Vacb, Valid); SharedCacheMap, Vacb, Valid);
KeAcquireGuardedMutex(&ViewLock);
KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldIrql);
Vacb->Valid = Valid; Vacb->Valid = Valid;
WasDirty = Vacb->Dirty; WasDirty = FALSE;
Vacb->Dirty = Vacb->Dirty || Dirty; if (Dirty)
if (!WasDirty && Vacb->Dirty)
{ {
InsertTailList(&DirtyVacbListHead, &Vacb->DirtyVacbListEntry); if (!Vacb->Dirty && Dirty)
CcTotalDirtyPages += VACB_MAPPING_GRANULARITY / PAGE_SIZE; {
Vacb->SharedCacheMap->DirtyPages += VACB_MAPPING_GRANULARITY / PAGE_SIZE; CcRosMarkDirtyVacb(Vacb);
}
else
{
WasDirty = TRUE;
}
} }
if (Mapped) if (Mapped)
@ -553,8 +552,6 @@ CcRosReleaseVacb (
CcRosVacbIncRefCount(Vacb); CcRosVacbIncRefCount(Vacb);
} }
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql);
KeReleaseGuardedMutex(&ViewLock);
CcRosReleaseVacbLock(Vacb); CcRosReleaseVacbLock(Vacb);
return STATUS_SUCCESS; return STATUS_SUCCESS;
@ -676,7 +673,6 @@ CcRosUnmapVacb (
{ {
PROS_VACB Vacb; PROS_VACB Vacb;
BOOLEAN WasDirty; BOOLEAN WasDirty;
KIRQL oldIrql;
ASSERT(SharedCacheMap); ASSERT(SharedCacheMap);
@ -689,21 +685,21 @@ CcRosUnmapVacb (
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
KeAcquireGuardedMutex(&ViewLock); WasDirty = FALSE;
KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldIrql); if (NowDirty)
{
WasDirty = Vacb->Dirty; if (!Vacb->Dirty && NowDirty)
Vacb->Dirty = Vacb->Dirty || NowDirty; {
CcRosMarkDirtyVacb(Vacb);
}
else
{
WasDirty = TRUE;
}
}
Vacb->MappedCount--; Vacb->MappedCount--;
if (!WasDirty && NowDirty)
{
InsertTailList(&DirtyVacbListHead, &Vacb->DirtyVacbListEntry);
CcTotalDirtyPages += VACB_MAPPING_GRANULARITY / PAGE_SIZE;
Vacb->SharedCacheMap->DirtyPages += VACB_MAPPING_GRANULARITY / PAGE_SIZE;
}
CcRosVacbDecRefCount(Vacb); CcRosVacbDecRefCount(Vacb);
if (!WasDirty && NowDirty) if (!WasDirty && NowDirty)
{ {
@ -714,8 +710,6 @@ CcRosUnmapVacb (
CcRosVacbDecRefCount(Vacb); CcRosVacbDecRefCount(Vacb);
} }
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql);
KeReleaseGuardedMutex(&ViewLock);
CcRosReleaseVacbLock(Vacb); CcRosReleaseVacbLock(Vacb);
return STATUS_SUCCESS; return STATUS_SUCCESS;