|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH xenbus 04/11] Reduce code duplication
From: Paul Durrant <pdurrant@xxxxxxxxxx>
Introduce helper functions for disabling/enabling interrupts and waiting for
completion. The functions are then used in place of the current open-coding of
these operations.
NOTE: To avoid compiler/prefast noise, some warnings are disabled. The static
analysis can't cope with the IRQL manipulation.
Signed-off-by: Paul Durrant <pdurrant@xxxxxxxxxx>
---
src/xenbus/sync.c | 208 ++++++++++++++++++++++------------------------
1 file changed, 100 insertions(+), 108 deletions(-)
diff --git a/src/xenbus/sync.c b/src/xenbus/sync.c
index e3b55d1d257b..1b474c469e43 100644
--- a/src/xenbus/sync.c
+++ b/src/xenbus/sync.c
@@ -122,12 +122,93 @@ __SyncRelease(
ASSERT3U(Old, ==, Index);
}
-
KDEFERRED_ROUTINE SyncWorker;
#pragma intrinsic(_enable)
#pragma intrinsic(_disable)
+#pragma warning(push)
+#pragma warning(disable:28167) // Function changes IRQL and does not restore
it before exit
+#pragma warning(disable:28156) // Actual IRQL is inconsistent with required
IRQL
+
+static FORCEINLINE NTSTATUS
+__SyncProcessorDisableInterrupts(
+ VOID
+ )
+{
+ PSYNC_CONTEXT Context = SyncContext;
+ ULONG Attempts;
+ LONG Old;
+ LONG New;
+ NTSTATUS status;
+
+ (VOID) KfRaiseIrql(HIGH_LEVEL);
+ status = STATUS_SUCCESS;
+
+ InterlockedIncrement(&Context->CompletionCount);
+
+ Attempts = 0;
+ while (++Attempts <= 1000) {
+ KeMemoryBarrier();
+
+ if (Context->CompletionCount == Context->ProcessorCount)
+ break;
+
+ _mm_pause();
+ }
+
+ do {
+ Old = Context->CompletionCount;
+ New = Old - 1;
+
+ if (Old == Context->ProcessorCount)
+ break;
+ } while (InterlockedCompareExchange(&Context->CompletionCount, New, Old)
!= Old);
+
+ if (Old < Context->ProcessorCount) {
+#pragma prefast(suppress:28138) // Use constant rather than variable
+ KeLowerIrql(DISPATCH_LEVEL);
+ status = STATUS_UNSUCCESSFUL;
+ }
+
+ if (NT_SUCCESS(status))
+ _disable();
+
+ return status;
+}
+
+static FORCEINLINE VOID
+__SyncProcessorEnableInterrupts(
+ VOID
+ )
+{
+ PSYNC_CONTEXT Context = SyncContext;
+
+ _enable();
+
+#pragma prefast(suppress:28138) // Use constant rather than variable
+ KeLowerIrql(DISPATCH_LEVEL);
+
+ InterlockedIncrement(&Context->CompletionCount);
+}
+
+static FORCEINLINE VOID
+__SyncWait(
+ VOID
+ )
+{
+ PSYNC_CONTEXT Context = SyncContext;
+
+ for (;;) {
+ KeMemoryBarrier();
+
+ if (Context->CompletionCount == Context->ProcessorCount)
+ break;
+
+ _mm_pause();
+ }
+}
+
VOID
#pragma prefast(suppress:28166) // Function does not restore IRQL
SyncWorker(
@@ -174,45 +255,11 @@ SyncWorker(
}
if (Processor->DisableInterrupts) {
- ULONG Attempts;
- NTSTATUS status;
-
- (VOID) KfRaiseIrql(HIGH_LEVEL);
- status = STATUS_SUCCESS;
-
- InterlockedIncrement(&Context->CompletionCount);
-
- Attempts = 0;
- while (Context->CompletionCount < Context->ProcessorCount) {
- _mm_pause();
- KeMemoryBarrier();
-
- if (++Attempts > 1000) {
- LONG Old;
- LONG New;
-
- do {
- Old = Context->CompletionCount;
- New = Old - 1;
-
- if (Old == Context->ProcessorCount)
- break;
- } while
(InterlockedCompareExchange(&Context->CompletionCount, New, Old) != Old);
-
- if (Old < Context->ProcessorCount) {
-#pragma prefast(suppress:28138) // Use constant rather than variable
- KeLowerIrql(DISPATCH_LEVEL);
- status = STATUS_UNSUCCESSFUL;
- break;
- }
- }
- }
+ NTSTATUS status = __SyncProcessorDisableInterrupts();
if (!NT_SUCCESS(status))
continue;
- _disable();
-
InterruptsDisabled = TRUE;
} else {
InterruptsDisabled = FALSE;
@@ -220,12 +267,7 @@ SyncWorker(
if (Context->Early != NULL)
Context->Early(Context->Argument, Index);
- _enable();
-
-#pragma prefast(suppress:28138) // Use constant rather than variable
- KeLowerIrql(DISPATCH_LEVEL);
-
- InterlockedIncrement(&Context->CompletionCount);
+ __SyncProcessorEnableInterrupts();
}
}
@@ -289,12 +331,10 @@ SyncCapture(
KeInsertQueueDpc(&Processor->Dpc, NULL, NULL);
}
- InterlockedIncrement(&Context->CompletionCount);
+ KeMemoryBarrier();
- while (Context->CompletionCount < Context->ProcessorCount) {
- _mm_pause();
- KeMemoryBarrier();
- }
+ InterlockedIncrement(&Context->CompletionCount);
+ __SyncWait();
Trace("<==== (%u:%u)\n", Group, Number);
}
@@ -308,7 +348,6 @@ SyncDisableInterrupts(
{
PSYNC_CONTEXT Context = SyncContext;
LONG Index;
- ULONG Attempts;
NTSTATUS status;
Trace("====>\n");
@@ -326,47 +365,13 @@ SyncDisableInterrupts(
KeMemoryBarrier();
-again:
- (VOID) KfRaiseIrql(HIGH_LEVEL);
- status = STATUS_SUCCESS;
-
- InterlockedIncrement(&Context->CompletionCount);
-
- Attempts = 0;
- while (Context->CompletionCount < Context->ProcessorCount) {
- _mm_pause();
- KeMemoryBarrier();
-
- if (++Attempts > 1000) {
- LONG Old;
- LONG New;
-
- do {
- Old = Context->CompletionCount;
- New = Old - 1;
-
- if (Old == Context->ProcessorCount)
- break;
- } while (InterlockedCompareExchange(&Context->CompletionCount,
New, Old) != Old);
-
- if (Old < Context->ProcessorCount) {
- LogPrintf(LOG_LEVEL_WARNING,
- "SYNC: %d < %d\n",
- Old,
- Context->ProcessorCount);
+ for (;;) {
+ status = __SyncProcessorDisableInterrupts();
+ if (NT_SUCCESS(status))
+ break;
-#pragma prefast(suppress:28138) // Use constant rather than variable
- KeLowerIrql(DISPATCH_LEVEL);
- status = STATUS_UNSUCCESSFUL;
- break;
- }
- }
+ LogPrintf(LOG_LEVEL_WARNING, "SYNC: RE-TRY\n");
}
-
- if (!NT_SUCCESS(status))
- goto again;
-
- _disable();
}
__drv_requiresIRQL(HIGH_LEVEL)
@@ -376,7 +381,6 @@ SyncEnableInterrupts(
)
{
PSYNC_CONTEXT Context = SyncContext;
- KIRQL Irql;
LONG Index;
ASSERT(SyncOwner >= 0);
@@ -384,14 +388,11 @@ SyncEnableInterrupts(
if (Context->Early != NULL)
Context->Early(Context->Argument, SyncOwner);
- _enable();
-
- Irql = KeGetCurrentIrql();
- ASSERT3U(Irql, ==, HIGH_LEVEL);
-
Context->CompletionCount = 0;
KeMemoryBarrier();
+ __SyncProcessorEnableInterrupts();
+
for (Index = 0; Index < Context->ProcessorCount; Index++) {
PSYNC_PROCESSOR Processor = &Context->Processor[Index];
@@ -400,15 +401,7 @@ SyncEnableInterrupts(
KeMemoryBarrier();
- InterlockedIncrement(&Context->CompletionCount);
-
- while (Context->CompletionCount < Context->ProcessorCount) {
- _mm_pause();
- KeMemoryBarrier();
- }
-
-#pragma prefast(suppress:28138) // Use constant rather than variable
- KeLowerIrql(DISPATCH_LEVEL);
+ __SyncWait();
Trace("<====\n");
}
@@ -433,6 +426,8 @@ SyncRelease(
Context->CompletionCount = 0;
KeMemoryBarrier();
+ InterlockedIncrement(&Context->CompletionCount);
+
for (Index = 0; Index < Context->ProcessorCount; Index++) {
PSYNC_PROCESSOR Processor = &Context->Processor[Index];
@@ -441,12 +436,7 @@ SyncRelease(
KeMemoryBarrier();
- InterlockedIncrement(&Context->CompletionCount);
-
- while (Context->CompletionCount < Context->ProcessorCount) {
- _mm_pause();
- KeMemoryBarrier();
- }
+ __SyncWait();
RtlZeroMemory(Context, PAGE_SIZE);
@@ -454,3 +444,5 @@ SyncRelease(
Trace("<====\n");
}
+
+#pragma warning(pop)
--
2.17.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |