|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH xenbus 09/11] Separate running the 'late' SYNC_CALLBACKs from exitting the DPC
From: Paul Durrant <pdurrant@xxxxxxxxxx>
This patch introduces a new dedicated request to ensure that *all* callbacks
have been completed before *any* CPU exits the DPC, thereby allowing threads
to be scheduled or other DPCs to run.
Signed-off-by: Paul Durrant <pdurrant@xxxxxxxxxx>
---
src/xenbus/suspend.c | 1 +
src/xenbus/sync.c | 46 ++++++++++++++++++++++++++++++++++++--------
src/xenbus/sync.h | 7 +++++++
3 files changed, 46 insertions(+), 8 deletions(-)
diff --git a/src/xenbus/suspend.c b/src/xenbus/suspend.c
index 6a4a42ed0ab2..3dca5d6fe11c 100644
--- a/src/xenbus/suspend.c
+++ b/src/xenbus/suspend.c
@@ -286,6 +286,7 @@ SuspendTrigger(
SyncRunEarly();
SyncEnableInterrupts();
+ SyncRunLate();
SyncRelease();
Context->Success = FALSE;
diff --git a/src/xenbus/sync.c b/src/xenbus/sync.c
index 07cc94d2f87b..b6665708a58e 100644
--- a/src/xenbus/sync.c
+++ b/src/xenbus/sync.c
@@ -84,6 +84,7 @@ typedef enum _SYNC_REQUEST {
SYNC_REQUEST_DISABLE_INTERRUPTS,
SYNC_REQUEST_RUN_EARLY,
SYNC_REQUEST_ENABLE_INTERRUPTS,
+ SYNC_REQUEST_RUN_LATE,
SYNC_REQUEST_EXIT,
} SYNC_REQUEST;
@@ -208,6 +209,19 @@ __SyncProcessorEnableInterrupts(
InterlockedIncrement(&Context->CompletionCount);
}
+static FORCEINLINE VOID
+__SyncProcessorRunLate(
+ IN ULONG Index
+ )
+{
+ PSYNC_CONTEXT Context = SyncContext;
+
+ if (Context->Late != NULL)
+ Context->Late(Context->Argument, Index);
+
+ InterlockedIncrement(&Context->CompletionCount);
+}
+
static FORCEINLINE VOID
__SyncWait(
VOID
@@ -255,12 +269,8 @@ SyncWorker(
for (;;) {
KeMemoryBarrier();
- if (Context->Request == SYNC_REQUEST_EXIT) {
- if (Context->Late != NULL)
- Context->Late(Context->Argument, Index);
-
+ if (Context->Request == SYNC_REQUEST_EXIT)
break;
- }
if (Context->Request == Request) {
_mm_pause();
@@ -276,6 +286,8 @@ SyncWorker(
__SyncProcessorRunEarly(Index);
} else if (Context->Request == SYNC_REQUEST_ENABLE_INTERRUPTS) {
__SyncProcessorEnableInterrupts();
+ } else if (Context->Request == SYNC_REQUEST_RUN_LATE) {
+ __SyncProcessorRunLate(Index);
}
Request = Context->Request;
@@ -419,6 +431,27 @@ SyncEnableInterrupts(
Trace("<====\n");
}
+__drv_requiresIRQL(DISPATCH_LEVEL)
+VOID
+SyncRunLate(
+ )
+{
+ PSYNC_CONTEXT Context = SyncContext;
+
+ ASSERT(SyncOwner >= 0);
+
+ Context->CompletionCount = 0;
+ KeMemoryBarrier();
+
+ __SyncProcessorRunLate(SyncOwner);
+
+ Context->Request = SYNC_REQUEST_RUN_LATE;
+ KeMemoryBarrier();
+
+ __SyncWait();
+}
+
+
__drv_requiresIRQL(DISPATCH_LEVEL)
VOID
#pragma prefast(suppress:28167) // Function changes IRQL
@@ -432,9 +465,6 @@ SyncRelease(
ASSERT(SyncOwner >= 0);
- if (Context->Late != NULL)
- Context->Late(Context->Argument, SyncOwner);
-
Context->CompletionCount = 0;
KeMemoryBarrier();
diff --git a/src/xenbus/sync.h b/src/xenbus/sync.h
index 12ba406f662e..e64d11431304 100644
--- a/src/xenbus/sync.h
+++ b/src/xenbus/sync.h
@@ -73,6 +73,13 @@ SyncEnableInterrupts(
VOID
);
+extern
+__drv_requiresIRQL(DISPATCH_LEVEL)
+VOID
+SyncRunLate(
+ VOID
+ );
+
extern
__drv_requiresIRQL(DISPATCH_LEVEL)
VOID
--
2.17.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |