[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 |