[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




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.