[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |