[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




 


Rackspace

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