|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH xenbus 08/11] Separate running the 'early' SYNC_CALLBACKs from the interrupt enable request
From: Paul Durrant <pdurrant@xxxxxxxxxx>
This patch introduces a new dedicated request to ensure that *all* callbacks
have been completed before *any* CPU re-enables interrupts.
Signed-off-by: Paul Durrant <pdurrant@xxxxxxxxxx>
---
src/xenbus/suspend.c | 1 +
src/xenbus/sync.c | 42 ++++++++++++++++++++++++++++++++++++------
src/xenbus/sync.h | 7 +++++++
3 files changed, 44 insertions(+), 6 deletions(-)
diff --git a/src/xenbus/suspend.c b/src/xenbus/suspend.c
index 471c0c4c1972..6a4a42ed0ab2 100644
--- a/src/xenbus/suspend.c
+++ b/src/xenbus/suspend.c
@@ -284,6 +284,7 @@ SuspendTrigger(
Context->Success = NT_SUCCESS(status) ? TRUE : FALSE;
+ SyncRunEarly();
SyncEnableInterrupts();
SyncRelease();
diff --git a/src/xenbus/sync.c b/src/xenbus/sync.c
index 767a3c4a767e..07cc94d2f87b 100644
--- a/src/xenbus/sync.c
+++ b/src/xenbus/sync.c
@@ -82,6 +82,7 @@ static UCHAR __Section[PAGE_SIZE];
typedef enum _SYNC_REQUEST {
SYNC_REQUEST_NONE,
SYNC_REQUEST_DISABLE_INTERRUPTS,
+ SYNC_REQUEST_RUN_EARLY,
SYNC_REQUEST_ENABLE_INTERRUPTS,
SYNC_REQUEST_EXIT,
} SYNC_REQUEST;
@@ -179,6 +180,19 @@ __SyncProcessorDisableInterrupts(
return status;
}
+static FORCEINLINE VOID
+__SyncProcessorRunEarly(
+ IN ULONG Index
+ )
+{
+ PSYNC_CONTEXT Context = SyncContext;
+
+ if (Context->Early != NULL)
+ Context->Early(Context->Argument, Index);
+
+ InterlockedIncrement(&Context->CompletionCount);
+}
+
static FORCEINLINE VOID
__SyncProcessorEnableInterrupts(
VOID
@@ -258,10 +272,9 @@ SyncWorker(
if (!NT_SUCCESS(status))
continue;
+ } else if (Context->Request == SYNC_REQUEST_RUN_EARLY) {
+ __SyncProcessorRunEarly(Index);
} else if (Context->Request == SYNC_REQUEST_ENABLE_INTERRUPTS) {
- if (Context->Early != NULL)
- Context->Early(Context->Argument, Index);
-
__SyncProcessorEnableInterrupts();
}
@@ -363,6 +376,26 @@ SyncDisableInterrupts(
}
}
+__drv_requiresIRQL(HIGH_LEVEL)
+VOID
+SyncRunEarly(
+ )
+{
+ PSYNC_CONTEXT Context = SyncContext;
+
+ ASSERT(SyncOwner >= 0);
+
+ Context->CompletionCount = 0;
+ KeMemoryBarrier();
+
+ __SyncProcessorRunEarly(SyncOwner);
+
+ Context->Request = SYNC_REQUEST_RUN_EARLY;
+ KeMemoryBarrier();
+
+ __SyncWait();
+}
+
__drv_requiresIRQL(HIGH_LEVEL)
__drv_setsIRQL(DISPATCH_LEVEL)
VOID
@@ -373,9 +406,6 @@ SyncEnableInterrupts(
ASSERT(SyncOwner >= 0);
- if (Context->Early != NULL)
- Context->Early(Context->Argument, SyncOwner);
-
Context->CompletionCount = 0;
KeMemoryBarrier();
diff --git a/src/xenbus/sync.h b/src/xenbus/sync.h
index c4b172107513..12ba406f662e 100644
--- a/src/xenbus/sync.h
+++ b/src/xenbus/sync.h
@@ -58,6 +58,13 @@ SyncDisableInterrupts(
VOID
);
+extern
+__drv_requiresIRQL(HIGH_LEVEL)
+VOID
+SyncRunEarly(
+ VOID
+ );
+
extern
__drv_requiresIRQL(HIGH_LEVEL)
__drv_setsIRQL(DISPATCH_LEVEL)
--
2.17.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |