|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH] Use a threaded DPC for ring processing
From: Owen Smith <owen.smith@xxxxxxxxxx>
The current DPC back-off mechanism uses a timer to reschedule long
running DPCs. Timers seem to always have a minimum tick period, so
rescheduled DPCs always have an additional level of latency.
Using a threaded DPC (which executes at PASSIVE_LEVEL) will allow
other drivers to interrupt the vbd DPC, and maintain system
responsiveness. Once the vbd's DPC can be pre-empted by another
DPC, a DPC back-off mechanism is no longer required.
Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx>
---
src/xenvbd/ring.c | 79 +++++++++++--------------------------------------------
1 file changed, 16 insertions(+), 63 deletions(-)
diff --git a/src/xenvbd/ring.c b/src/xenvbd/ring.c
index 0b0df72..f612fc7 100644
--- a/src/xenvbd/ring.c
+++ b/src/xenvbd/ring.c
@@ -76,8 +76,6 @@ struct _XENVBD_RING {
PVOID Grants[XENVBD_MAX_RING_PAGES];
PXENBUS_EVTCHN_CHANNEL Channel;
KDPC Dpc;
- KDPC TimerDpc;
- KTIMER Timer;
PXENBUS_CACHE RequestCache;
PXENBUS_CACHE SegmentCache;
@@ -1254,6 +1252,9 @@ RingNotifyResponses(
{
BOOLEAN Retry = FALSE;
+ if (!Ring->Enabled)
+ return FALSE;
+
Retry |= RingPoll(Ring);
Retry |= RingSubmitRequests(Ring);
@@ -1284,37 +1285,6 @@ RingInterrupt(
return TRUE;
}
-static FORCEINLINE BOOLEAN
-__RingDpcTimeout(
- IN PXENVBD_RING Ring
- )
-{
- KDPC_WATCHDOG_INFORMATION Watchdog;
- NTSTATUS status;
-
- UNREFERENCED_PARAMETER(Ring);
-
- 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 RingDpc;
VOID
@@ -1333,28 +1303,22 @@ RingDpc(
ASSERT(Ring != NULL);
- if (!Ring->Connected)
- return;
-
for (;;) {
- if (!RingNotifyResponses(Ring)) {
- XENBUS_EVTCHN(Unmask,
- &Ring->EvtchnInterface,
- Ring->Channel,
- FALSE);
- break;
- }
- if (__RingDpcTimeout(Ring)) {
- LARGE_INTEGER Delay;
+ KIRQL Irql;
+ BOOLEAN Retry;
- Delay.QuadPart = TIME_RELATIVE(TIME_US(100));
+ KeRaiseIrql(DISPATCH_LEVEL, &Irql);
+ Retry = RingNotifyResponses(Ring);
+ KeLowerIrql(Irql);
- KeSetTimer(&Ring->Timer,
- Delay,
- &Ring->TimerDpc);
+ if (!Retry)
break;
- }
}
+
+ XENBUS_EVTCHN(Unmask,
+ &Ring->EvtchnInterface,
+ Ring->Channel,
+ FALSE);
}
static DECLSPEC_NOINLINE VOID
@@ -1590,9 +1554,8 @@ RingCreate(
(*Ring)->Frontend = Frontend;
KeInitializeSpinLock(&(*Ring)->Lock);
- KeInitializeDpc(&(*Ring)->Dpc, RingDpc, *Ring);
- KeInitializeDpc(&(*Ring)->TimerDpc, RingDpc, *Ring);
- KeInitializeTimer(&(*Ring)->Timer);
+ KeInitializeThreadedDpc(&(*Ring)->Dpc, RingDpc, *Ring);
+ KeSetImportanceDpc(&(*Ring)->Dpc, MediumHighImportance);
QueueInit(&(*Ring)->FreshSrbs);
QueueInit(&(*Ring)->PreparedReqs);
@@ -1703,8 +1666,6 @@ fail2:
RtlZeroMemory(&(*Ring)->SubmittedReqs, sizeof(XENVBD_QUEUE));
RtlZeroMemory(&(*Ring)->ShutdownSrbs, sizeof(XENVBD_QUEUE));
- RtlZeroMemory(&(*Ring)->Timer, sizeof(KTIMER));
- RtlZeroMemory(&(*Ring)->TimerDpc, sizeof(KDPC));
RtlZeroMemory(&(*Ring)->Dpc, sizeof(KDPC));
RtlZeroMemory(&(*Ring)->Lock, sizeof(KSPIN_LOCK));
(*Ring)->Frontend = NULL;
@@ -1748,8 +1709,6 @@ RingDestroy(
RtlZeroMemory(&Ring->SubmittedReqs, sizeof(XENVBD_QUEUE));
RtlZeroMemory(&Ring->ShutdownSrbs, sizeof(XENVBD_QUEUE));
- RtlZeroMemory(&Ring->Timer, sizeof(KTIMER));
- RtlZeroMemory(&Ring->TimerDpc, sizeof(KDPC));
RtlZeroMemory(&Ring->Dpc, sizeof(KDPC));
RtlZeroMemory(&Ring->Lock, sizeof(KSPIN_LOCK));
Ring->Frontend = NULL;
@@ -2091,12 +2050,6 @@ RingDisable(
AdapterCompleteSrb(Adapter, SrbExt);
}
}
-
- //
- // No new timers can be scheduled once Enabled goes to FALSE.
- // Cancel any existing ones.
- //
- (VOID) KeCancelTimer(&Ring->Timer);
}
VOID
--
2.8.3
_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/win-pv-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |