[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [win-pv-devel] [PATCH] Add DPC timeout check
> -----Original Message----- > From: win-pv-devel [mailto:win-pv-devel-bounces@xxxxxxxxxxxxxxxxxxxx] On > Behalf Of owen.smith@xxxxxxxxxx > Sent: 16 August 2017 16:34 > To: win-pv-devel@xxxxxxxxxxxxxxxxxxxx > Cc: Owen Smith <owen.smith@xxxxxxxxxx> > Subject: [win-pv-devel] [PATCH] Add DPC timeout check > > From: Owen Smith <owen.smith@xxxxxxxxxx> > > Check the DPC has not exceeded 1/2 its alloted time every > * 1/4 ring of responses processed > * all outstanding prepared requests submitted > * 1 queued SRB prepared > > Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx> Acked-by: Paul Durrant <paul.durrant@xxxxxxxxxx> > --- > src/xenvbd/blockring.c | 12 ++++++--- > src/xenvbd/blockring.h | 2 +- > src/xenvbd/frontend.c | 10 +++++--- > src/xenvbd/frontend.h | 2 +- > src/xenvbd/notifier.c | 66 > ++++++++++++++++++++++++++++++++++++++++++++++---- > src/xenvbd/target.c | 13 ++++++++-- > src/xenvbd/target.h | 2 +- > 7 files changed, 91 insertions(+), 16 deletions(-) > > diff --git a/src/xenvbd/blockring.c b/src/xenvbd/blockring.c > index e00b64a..24e47c0 100644 > --- a/src/xenvbd/blockring.c > +++ b/src/xenvbd/blockring.c > @@ -506,12 +506,13 @@ BlockRingDebugCallback( > BlockRing->Submitted = BlockRing->Received = 0; > } > > -VOID > +BOOLEAN > BlockRingPoll( > IN PXENVBD_BLOCKRING BlockRing > ) > { > PXENVBD_TARGET Target = FrontendGetTarget(BlockRing->Frontend); > + BOOLEAN Retry = FALSE; > > ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL); > KeAcquireSpinLockAtDpcLevel(&BlockRing->Lock); > @@ -532,10 +533,10 @@ BlockRingPoll( > > KeMemoryBarrier(); > > - if (rsp_cons == rsp_prod) > + if (rsp_cons == rsp_prod || Retry) > break; > > - while (rsp_cons != rsp_prod) { > + while (rsp_cons != rsp_prod && !Retry) { > blkif_response_t* Response; > ULONG Tag; > > @@ -548,6 +549,9 @@ BlockRingPoll( > } > > RtlZeroMemory(Response, sizeof(union blkif_sring_entry)); > + > + if (rsp_cons - BlockRing->FrontRing.rsp_cons > > RING_SIZE(&BlockRing->FrontRing) / 4) > + Retry = TRUE; > } > > KeMemoryBarrier(); > @@ -558,6 +562,8 @@ BlockRingPoll( > > done: > KeReleaseSpinLockFromDpcLevel(&BlockRing->Lock); > + > + return Retry; > } > > BOOLEAN > diff --git a/src/xenvbd/blockring.h b/src/xenvbd/blockring.h > index 1117d73..98fe278 100644 > --- a/src/xenvbd/blockring.h > +++ b/src/xenvbd/blockring.h > @@ -83,7 +83,7 @@ BlockRingDebugCallback( > IN PXENBUS_DEBUG_INTERFACE Debug > ); > > -extern VOID > +extern BOOLEAN > BlockRingPoll( > IN PXENVBD_BLOCKRING BlockRing > ); > diff --git a/src/xenvbd/frontend.c b/src/xenvbd/frontend.c > index c909ea8..2ec082d 100644 > --- a/src/xenvbd/frontend.c > +++ b/src/xenvbd/frontend.c > @@ -326,13 +326,17 @@ out: > > > //========================================================= > ==================== > __drv_requiresIRQL(DISPATCH_LEVEL) > -VOID > +BOOLEAN > FrontendNotifyResponses( > __in PXENVBD_FRONTEND Frontend > ) > { > - BlockRingPoll(Frontend->BlockRing); > - TargetSubmitRequests(Frontend->Target); > + BOOLEAN Retry = FALSE; > + > + Retry |= BlockRingPoll(Frontend->BlockRing); > + Retry |= TargetSubmitRequests(Frontend->Target); > + > + return Retry; > } > > > //========================================================= > ==================== > diff --git a/src/xenvbd/frontend.h b/src/xenvbd/frontend.h > index 8a6cc04..4490aeb 100644 > --- a/src/xenvbd/frontend.h > +++ b/src/xenvbd/frontend.h > @@ -149,7 +149,7 @@ FrontendWriteUsage( > > // Ring > __drv_requiresIRQL(DISPATCH_LEVEL) > -extern VOID > +extern BOOLEAN > FrontendNotifyResponses( > __in PXENVBD_FRONTEND Frontend > ); > diff --git a/src/xenvbd/notifier.c b/src/xenvbd/notifier.c > index a87c3bd..22bfe00 100644 > --- a/src/xenvbd/notifier.c > +++ b/src/xenvbd/notifier.c > @@ -50,6 +50,8 @@ struct _XENVBD_NOTIFIER { > ULONG NumInts; > ULONG NumDpcs; > KDPC Dpc; > + KDPC TimerDpc; > + KTIMER Timer; > }; > > #define NOTIFIER_POOL_TAG 'yfNX' > @@ -95,6 +97,37 @@ NotifierInterrupt( > return TRUE; > } > > +static FORCEINLINE BOOLEAN > +__NotifierDpcTimeout( > + IN PXENVBD_NOTIFIER Notifier > + ) > +{ > + KDPC_WATCHDOG_INFORMATION Watchdog; > + NTSTATUS status; > + > + UNREFERENCED_PARAMETER(Notifier); > + > + RtlZeroMemory(&Watchdog, sizeof (Watchdog)); > + > + status = KeQueryDpcWatchdogInformation(&Watchdog); > + ASSERT(NT_SUCCESS(status)); > + > + if (Watchdog.DpcTimeLimit == 0 || > + Watchdog.DpcWatchdogLimit == 0) > + return FALSE; > + > + if (Watchdog.DpcTimeCount > (Watchdog.DpcTimeLimit / 2) && > + Watchdog.DpcWatchdogCount > (Watchdog.DpcWatchdogLimit / 2)) > + return FALSE; > + > + return TRUE; > +} > + > +#define TIME_US(_us) ((_us) * 10) > +#define TIME_MS(_ms) (TIME_US((_ms) * 1000)) > +#define TIME_S(_s) (TIME_MS((_s) * 1000)) > +#define TIME_RELATIVE(_t) (-(_t)) > + > KDEFERRED_ROUTINE NotifierDpc; > > VOID > @@ -116,12 +149,25 @@ NotifierDpc( > if (!Notifier->Connected) > return; > > - FrontendNotifyResponses(Notifier->Frontend); > + for (;;) { > + if (!FrontendNotifyResponses(Notifier->Frontend)) { > + XENBUS_EVTCHN(Unmask, > + &Notifier->EvtchnInterface, > + Notifier->Channel, > + FALSE); > + break; > + } > + if (__NotifierDpcTimeout(Notifier)) { > + LARGE_INTEGER Delay; > > - XENBUS_EVTCHN(Unmask, > - &Notifier->EvtchnInterface, > - Notifier->Channel, > - FALSE); > + Delay.QuadPart = TIME_RELATIVE(TIME_US(100)); > + > + KeSetTimer(&Notifier->Timer, > + Delay, > + &Notifier->TimerDpc); > + break; > + } > + } > } > > NTSTATUS > @@ -136,6 +182,8 @@ NotifierCreate( > > (*Notifier)->Frontend = Frontend; > KeInitializeDpc(&(*Notifier)->Dpc, NotifierDpc, *Notifier); > + KeInitializeDpc(&(*Notifier)->TimerDpc, NotifierDpc, *Notifier); > + KeInitializeTimer(&(*Notifier)->Timer); > > return STATUS_SUCCESS; > > @@ -150,6 +198,8 @@ NotifierDestroy( > { > Notifier->Frontend = NULL; > RtlZeroMemory(&Notifier->Dpc, sizeof(KDPC)); > + RtlZeroMemory(&Notifier->TimerDpc, sizeof(KDPC)); > + RtlZeroMemory(&Notifier->Timer, sizeof(KTIMER)); > > ASSERT(IsZeroMemory(Notifier, sizeof(XENVBD_NOTIFIER))); > > @@ -252,6 +302,12 @@ NotifierDisable( > ASSERT(Notifier->Enabled == TRUE); > > Notifier->Enabled = FALSE; > + > + // > + // No new timers can be scheduled once Enabled goes to FALSE. > + // Cancel any existing ones. > + // > + (VOID) KeCancelTimer(&Notifier->Timer); > } > > VOID > diff --git a/src/xenvbd/target.c b/src/xenvbd/target.c > index ffffa3e..697f309 100644 > --- a/src/xenvbd/target.c > +++ b/src/xenvbd/target.c > @@ -1254,11 +1254,13 @@ BlkifOperationName( > } > } > > -VOID > +BOOLEAN > TargetSubmitRequests( > IN PXENVBD_TARGET Target > ) > { > + BOOLEAN Retry = FALSE; > + > for (;;) { > // submit all prepared requests (0 or more requests) > // return TRUE if submitted 0 or more requests from prepared queue > @@ -1271,10 +1273,17 @@ TargetSubmitRequests( > // return FALSE if prepare failed or fresh queue empty > if (!TargetPrepareFresh(Target)) > break; > + > + // back off, check DPC timeout and try again > + Retry = TRUE; > + break; > } > > // if no requests/SRBs outstanding, complete any shutdown SRBs > - TargetCompleteShutdown(Target); > + if (!Retry) > + TargetCompleteShutdown(Target); > + > + return Retry; > } > > VOID > diff --git a/src/xenvbd/target.h b/src/xenvbd/target.h > index 1e2b3ed..b790eb4 100644 > --- a/src/xenvbd/target.h > +++ b/src/xenvbd/target.h > @@ -93,7 +93,7 @@ TargetSetDeviceObject( > IN PDEVICE_OBJECT DeviceObject > ); > > -extern VOID > +extern BOOLEAN > TargetSubmitRequests( > IN PXENVBD_TARGET Target > ); > -- > 2.8.3 > > > _______________________________________________ > win-pv-devel mailing list > win-pv-devel@xxxxxxxxxxxxxxxxxxxx > https://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel _______________________________________________ win-pv-devel mailing list win-pv-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |