[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH xenbus] Make sure the interrupt handler for each vCPU is run...
From: Paul Durrant <pdurrant@xxxxxxxxxx> ... after enabling event channel delivery. New versions of Xen have this sequence in their map_vcpu_info() function: /* * Mark everything as being pending just to make sure nothing gets * lost. The domain will get a spurious event, but it can cope. */ if ( !has_32bit_shinfo(d) ) write_atomic(&new_info->native.evtchn_pending_sel, ~0); else write_atomic(&vcpu_info(v, evtchn_pending_sel), ~0); vcpu_mark_events_pending(v); whereas older versions code this differently: /* * Mark everything as being pending just to make sure nothing gets * lost. The domain will get a spurious event, but it can cope. */ vcpu_info(v, evtchn_upcall_pending) = 1; for ( i = 0; i < BITS_PER_EVTCHN_WORD(d); i++ ) set_bit(i, &vcpu_info(v, evtchn_pending_sel)); The crucial difference is that in the older variant there is no call to vcpu_mark_events_pending() which means that, for an HVM guest at least, the upcall function that clears 'evtchn_upcall_pending' does not get run and hence no events will be received on that vCPU. This patch makes sure the upcall function for each vCPU is run at least once thereby ensuring that 'evtchn_upcall_pending' is cleared. NOTE: The patch also adds a 'Count' to each XENBUS_INTERRUPT object, incremented each time the interrupt is triggred, and emits a log line when the value transitions from zero. Signed-off-by: Paul Durrant <pdurrant@xxxxxxxxxx> --- src/xenbus/evtchn.c | 9 +++++++++ src/xenbus/fdo.c | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/src/xenbus/evtchn.c b/src/xenbus/evtchn.c index 55c16b73212a..d0702686aeea 100644 --- a/src/xenbus/evtchn.c +++ b/src/xenbus/evtchn.c @@ -1269,6 +1269,7 @@ EvtchnInterruptEnable( { ULONG Cpu; ULONG Line; + KIRQL Irql; NTSTATUS status; Trace("====>\n"); @@ -1312,6 +1313,10 @@ EvtchnInterruptEnable( ProcNumber.Number, Vector); Processor->UpcallEnabled = TRUE; + + Irql = FdoAcquireInterruptLock(Context->Fdo, Processor->Interrupt); + (VOID) EvtchnInterruptCallback(NULL, Processor); + FdoReleaseInterruptLock(Context->Fdo, Processor->Interrupt, Irql); } line: @@ -1322,6 +1327,10 @@ line: Info("CALLBACK VIA (Vector = %u)\n", Line); + Irql = FdoAcquireInterruptLock(Context->Fdo, Context->Interrupt); + (VOID) EvtchnInterruptCallback(NULL, &Context->Processor[0]); + FdoReleaseInterruptLock(Context->Fdo, Context->Interrupt, Irql); + Trace("<====\n"); } diff --git a/src/xenbus/fdo.c b/src/xenbus/fdo.c index 9944ef6d5c0e..21de8678c959 100644 --- a/src/xenbus/fdo.c +++ b/src/xenbus/fdo.c @@ -78,6 +78,7 @@ struct _XENBUS_INTERRUPT { ULONG Line; PKSERVICE_ROUTINE Callback; PVOID Argument; + ULONG Count; }; typedef struct _XENBUS_VIRQ { @@ -2212,6 +2213,12 @@ FdoInterruptCallback( if (Interrupt->Callback == NULL) return FALSE; + if (Interrupt->Count++ == 0) + LogPrintf(LOG_LEVEL_INFO, + "XENBUS: %u:%u INTERRUPT\n", + Interrupt->ProcNumber.Group, + Interrupt->ProcNumber.Number); + return Interrupt->Callback(InterruptObject, Interrupt->Argument); } -- 2.17.1
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |