X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=ntoskrnl%2Fconfig%2Fcmlazy.c;h=348739e8c5dfb4c04b94cd823bd6ece7b0de3d1c;hp=bfe56542a234ef968e485810a6c1f79f2be07611;hb=8069b8c90ddf941e9877bb4c68645443e4388b8a;hpb=b726d7355f0aa394852fa8c56e59cfc9bbc4293c diff --git a/ntoskrnl/config/cmlazy.c b/ntoskrnl/config/cmlazy.c index bfe56542a23..348739e8c5d 100644 --- a/ntoskrnl/config/cmlazy.c +++ b/ntoskrnl/config/cmlazy.c @@ -23,7 +23,7 @@ BOOLEAN CmpLazyFlushPending; BOOLEAN CmpForceForceFlush; BOOLEAN CmpHoldLazyFlush = TRUE; ULONG CmpLazyFlushIntervalInSeconds = 5; -ULONG CmpLazyFlushHiveCount = 7; +static ULONG CmpLazyFlushHiveCount = 7; ULONG CmpLazyFlushCount = 1; LONG CmpFlushStarveWriters; @@ -31,33 +31,30 @@ LONG CmpFlushStarveWriters; BOOLEAN NTAPI -CmpDoFlushNextHive(IN BOOLEAN ForceFlush, - OUT PBOOLEAN Error, - OUT PULONG DirtyCount) +CmpDoFlushNextHive(_In_ BOOLEAN ForceFlush, + _Out_ PBOOLEAN Error, + _Out_ PULONG DirtyCount) { NTSTATUS Status; PLIST_ENTRY NextEntry; PCMHIVE CmHive; - BOOLEAN Result; + BOOLEAN Result; ULONG HiveCount = CmpLazyFlushHiveCount; /* Set Defaults */ *Error = FALSE; *DirtyCount = 0; - + /* Don't do anything if we're not supposed to */ if (CmpNoWrite) return TRUE; /* Make sure we have to flush at least one hive */ if (!HiveCount) HiveCount = 1; - /* Don't force flush */ - CmpForceForceFlush = FALSE; - /* Acquire the list lock and loop */ ExAcquirePushLockShared(&CmpHiveListHeadLock); NextEntry = CmpHiveListHead.Flink; - while (NextEntry != &CmpHiveListHead) + while ((NextEntry != &CmpHiveListHead) && HiveCount) { /* Get the hive and check if we should flush it */ CmHive = CONTAINING_RECORD(NextEntry, CMHIVE, HiveList); @@ -66,26 +63,32 @@ CmpDoFlushNextHive(IN BOOLEAN ForceFlush, { /* Great sucess! */ Result = TRUE; - - /* Ignore clean or volatile hves */ - if (!(CmHive->Hive.DirtyCount) || + + /* One less to flush */ + HiveCount--; + + /* Ignore clean or volatile hives */ + if ((!CmHive->Hive.DirtyCount && !ForceFlush) || (CmHive->Hive.HiveFlags & HIVE_VOLATILE)) { /* Don't do anything but do update the count */ CmHive->FlushCount = CmpLazyFlushCount; + DPRINT("Hive %wZ is clean.\n", &CmHive->FileFullPath); } else { /* Do the sync */ - DPRINT1("Flushing: %wZ\n", CmHive->FileFullPath); - DPRINT1("Handle: %lx\n", CmHive->FileHandles[HFILE_TYPE_PRIMARY]); + DPRINT1("Flushing: %wZ\n", &CmHive->FileFullPath); + DPRINT1("Handle: %p\n", CmHive->FileHandles[HFILE_TYPE_PRIMARY]); Status = HvSyncHive(&CmHive->Hive); if(!NT_SUCCESS(Status)) { /* Let them know we failed */ *Error = TRUE; Result = FALSE; + break; } + CmHive->FlushCount = CmpLazyFlushCount; } } else if ((CmHive->Hive.DirtyCount) && @@ -95,12 +98,13 @@ CmpDoFlushNextHive(IN BOOLEAN ForceFlush, /* Use another lazy flusher for this hive */ ASSERT(CmHive->FlushCount == CmpLazyFlushCount); *DirtyCount += CmHive->Hive.DirtyCount; + DPRINT("CmHive %wZ already uptodate.\n", &CmHive->FileFullPath); } /* Try the next one */ NextEntry = NextEntry->Flink; } - + /* Check if we've flushed everything */ if (NextEntry == &CmpHiveListHead) { @@ -112,12 +116,13 @@ CmpDoFlushNextHive(IN BOOLEAN ForceFlush, /* We need to be called again */ Result = TRUE; } - + /* Unlock the list and return the result */ ExReleasePushLock(&CmpHiveListHeadLock); return Result; } +_Function_class_(KDEFERRED_ROUTINE) VOID NTAPI CmpEnableLazyFlushDpcRoutine(IN PKDPC Dpc, @@ -129,6 +134,7 @@ CmpEnableLazyFlushDpcRoutine(IN PKDPC Dpc, CmpHoldLazyFlush = FALSE; } +_Function_class_(KDEFERRED_ROUTINE) VOID NTAPI CmpLazyFlushDpcRoutine(IN PKDPC Dpc, @@ -137,6 +143,7 @@ CmpLazyFlushDpcRoutine(IN PKDPC Dpc, IN PVOID SystemArgument2) { /* Check if we should queue the lazy flush worker */ + DPRINT("Flush pending: %s, Holding lazy flush: %s.\n", CmpLazyFlushPending ? "yes" : "no", CmpHoldLazyFlush ? "yes" : "no"); if ((!CmpLazyFlushPending) && (!CmpHoldLazyFlush)) { CmpLazyFlushPending = TRUE; @@ -150,7 +157,7 @@ CmpLazyFlush(VOID) { LARGE_INTEGER DueTime; PAGED_CODE(); - + /* Check if we should set the lazy flush timer */ if ((!CmpNoWrite) && (!CmpHoldLazyFlush)) { @@ -161,6 +168,7 @@ CmpLazyFlush(VOID) } } +_Function_class_(WORKER_THREAD_ROUTINE) VOID NTAPI CmpLazyFlushWorker(IN PVOID Parameter) @@ -170,22 +178,29 @@ CmpLazyFlushWorker(IN PVOID Parameter) PAGED_CODE(); /* Don't do anything if lazy flushing isn't enabled yet */ - if (CmpHoldLazyFlush) return; - + if (CmpHoldLazyFlush) + { + DPRINT1("Lazy flush held. Bye bye.\n"); + CmpLazyFlushPending = FALSE; + return; + } + /* Check if we are forcing a flush */ ForceFlush = CmpForceForceFlush; if (ForceFlush) { + DPRINT("Forcing flush.\n"); /* Lock the registry exclusively */ CmpLockRegistryExclusive(); } else { - /* Do a normal lock */ - CmpLockRegistry(); + DPRINT("Not forcing flush.\n"); + /* Starve writers before locking */ InterlockedIncrement(&CmpFlushStarveWriters); + CmpLockRegistry(); } - + /* Flush the next hive */ MoreWork = CmpDoFlushNextHive(ForceFlush, &Result, &DirtyCount); if (!MoreWork) @@ -195,29 +210,36 @@ CmpLazyFlushWorker(IN PVOID Parameter) } /* Check if we have starved writers */ - if (!ForceFlush) InterlockedDecrement(&CmpFlushStarveWriters); + if (!ForceFlush) + InterlockedDecrement(&CmpFlushStarveWriters); /* Not pending anymore, release the registry lock */ CmpLazyFlushPending = FALSE; CmpUnlockRegistry(); - - /* Check if we need to flush another hive */ - if ((MoreWork) || (DirtyCount)) CmpLazyFlush(); + + DPRINT("Lazy flush done. More work to be done: %s. Entries still dirty: %u.\n", + MoreWork ? "Yes" : "No", DirtyCount); + + if (MoreWork) + { + /* Relaunch the flush timer, so the remaining hives get flushed */ + CmpLazyFlush(); + } } VOID NTAPI CmpCmdInit(IN BOOLEAN SetupBoot) { - LARGE_INTEGER DueTime; + LARGE_INTEGER DueTime; PAGED_CODE(); - + /* Setup the lazy DPC */ KeInitializeDpc(&CmpLazyFlushDpc, CmpLazyFlushDpcRoutine, NULL); - + /* Setup the lazy timer */ KeInitializeTimer(&CmpLazyFlushTimer); - + /* Setup the lazy worker */ ExInitializeWorkItem(&CmpLazyWorkItem, CmpLazyFlushWorker, NULL); @@ -226,7 +248,7 @@ CmpCmdInit(IN BOOLEAN SetupBoot) CmpEnableLazyFlushDpcRoutine, NULL); KeInitializeTimer(&CmpEnableLazyFlushTimer); - + /* Enable lazy flushing after 10 minutes */ DueTime.QuadPart = Int32x32To64(600, -10 * 1000 * 1000); KeSetTimer(&CmpEnableLazyFlushTimer, DueTime, &CmpEnableLazyFlushDpc); @@ -234,10 +256,10 @@ CmpCmdInit(IN BOOLEAN SetupBoot) /* Setup flush variables */ CmpNoWrite = CmpMiniNTBoot; CmpWasSetupBoot = SetupBoot; - + /* Testing: Force Lazy Flushing */ CmpHoldLazyFlush = FALSE; - + /* Setup the hive list */ CmpInitializeHiveList(SetupBoot); }