]> xenbits.xensource.com Git - pvdrivers/win/xenbus.git/commitdiff
Separate running the 'late' SYNC_CALLBACKs from exitting the DPC
authorPaul Durrant <pdurrant@amazon.com>
Thu, 5 May 2022 18:12:40 +0000 (19:12 +0100)
committerPaul Durrant <pdurrant@amazon.com>
Fri, 6 May 2022 12:46:23 +0000 (13:46 +0100)
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@amazon.com>
src/xenbus/suspend.c
src/xenbus/sync.c
src/xenbus/sync.h

index 6a4a42ed0ab28bc2c2d78e8c8cfea4f92cdc26e9..3dca5d6fe11c9255bc2b61d1f7e68f7c19e39c46 100644 (file)
@@ -286,6 +286,7 @@ SuspendTrigger(
 
     SyncRunEarly();
     SyncEnableInterrupts();
+    SyncRunLate();
     SyncRelease();
 
     Context->Success = FALSE;
index 07cc94d2f87b2b7824df0ad74950913ffb3289f7..b6665708a58e676a857e94ed3c60de0fef539dc2 100644 (file)
@@ -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();
 
index 12ba406f662ed49b82571ba03540cc27d9ac9a73..e64d114313043759adf2a5548b55704b46dbac7d 100644 (file)
@@ -73,6 +73,13 @@ SyncEnableInterrupts(
     VOID
     );
 
+extern
+__drv_requiresIRQL(DISPATCH_LEVEL)
+VOID
+SyncRunLate(
+    VOID
+    );
+
 extern
 __drv_requiresIRQL(DISPATCH_LEVEL)
 VOID