[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH 3/3] Partially revert "Simplify EVTCHN Unmask"
This partially reverts commit 3ad02ccc6c68, which removed the possibility that unmasking an event channel could fail. This semantic was actually useful in some cases though, specifically to avoid dropping out of a DPC only to have it immediately re-queued. This patch, therefore, re-instates the older semantic but makes it optional so that callers that cannot easily tolerate such a failure can force the unmask to succeed. Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx> --- include/evtchn_interface.h | 42 +++++++++++++++--- include/revision.h | 3 +- src/xenbus/console.c | 9 ++-- src/xenbus/evtchn.c | 106 ++++++++++++++++++++++++++++++++++++++++----- src/xenbus/fdo.c | 9 ++-- src/xenbus/store.c | 9 ++-- 6 files changed, 147 insertions(+), 31 deletions(-) diff --git a/include/evtchn_interface.h b/include/evtchn_interface.h index 310850b..068a697 100644 --- a/include/evtchn_interface.h +++ b/include/evtchn_interface.h @@ -128,18 +128,27 @@ typedef NTSTATUS IN UCHAR Number ); +typedef VOID +(*XENBUS_EVTCHN_UNMASK_V4)( + IN PINTERFACE Interface, + IN PXENBUS_EVTCHN_CHANNEL Channel, + IN BOOLEAN InCallback + ); + /*! \typedef XENBUS_EVTCHN_UNMASK \brief Unmask an event channel \param Interface The interface header \param Channel The channel handle \param InCallback Set to TRUE if this method is invoked in context of the channel callback + \param Force Set to TRUE if the unmask must succeed, otherwise set to FALSE and the function will return FALSE if the unmask did not complete. */ -typedef VOID +typedef BOOLEAN (*XENBUS_EVTCHN_UNMASK)( IN PINTERFACE Interface, IN PXENBUS_EVTCHN_CHANNEL Channel, - IN BOOLEAN InCallback + IN BOOLEAN InCallback, + IN BOOLEAN Force ); typedef VOID @@ -250,7 +259,7 @@ struct _XENBUS_EVTCHN_INTERFACE_V4 { XENBUS_EVTCHN_RELEASE EvtchnRelease; XENBUS_EVTCHN_OPEN EvtchnOpen; XENBUS_EVTCHN_BIND EvtchnBind; - XENBUS_EVTCHN_UNMASK EvtchnUnmask; + XENBUS_EVTCHN_UNMASK_V4 EvtchnUnmaskVersion4; XENBUS_EVTCHN_SEND_V1 EvtchnSendVersion1; XENBUS_EVTCHN_TRIGGER EvtchnTrigger; XENBUS_EVTCHN_GET_PORT EvtchnGetPort; @@ -267,7 +276,7 @@ struct _XENBUS_EVTCHN_INTERFACE_V5 { XENBUS_EVTCHN_RELEASE EvtchnRelease; XENBUS_EVTCHN_OPEN EvtchnOpen; XENBUS_EVTCHN_BIND EvtchnBind; - XENBUS_EVTCHN_UNMASK EvtchnUnmask; + XENBUS_EVTCHN_UNMASK_V4 EvtchnUnmaskVersion4; XENBUS_EVTCHN_SEND_V1 EvtchnSendVersion1; XENBUS_EVTCHN_TRIGGER EvtchnTrigger; XENBUS_EVTCHN_WAIT_V5 EvtchnWaitVersion5; @@ -285,7 +294,7 @@ struct _XENBUS_EVTCHN_INTERFACE_V6 { XENBUS_EVTCHN_RELEASE EvtchnRelease; XENBUS_EVTCHN_OPEN EvtchnOpen; XENBUS_EVTCHN_BIND EvtchnBind; - XENBUS_EVTCHN_UNMASK EvtchnUnmask; + XENBUS_EVTCHN_UNMASK_V4 EvtchnUnmaskVersion4; XENBUS_EVTCHN_SEND EvtchnSend; XENBUS_EVTCHN_TRIGGER EvtchnTrigger; XENBUS_EVTCHN_WAIT_V5 EvtchnWaitVersion5; @@ -303,6 +312,25 @@ struct _XENBUS_EVTCHN_INTERFACE_V7 { XENBUS_EVTCHN_RELEASE EvtchnRelease; XENBUS_EVTCHN_OPEN EvtchnOpen; XENBUS_EVTCHN_BIND EvtchnBind; + XENBUS_EVTCHN_UNMASK_V4 EvtchnUnmaskVersion4; + XENBUS_EVTCHN_SEND EvtchnSend; + XENBUS_EVTCHN_TRIGGER EvtchnTrigger; + XENBUS_EVTCHN_GET_COUNT EvtchnGetCount; + XENBUS_EVTCHN_WAIT EvtchnWait; + XENBUS_EVTCHN_GET_PORT EvtchnGetPort; + XENBUS_EVTCHN_CLOSE EvtchnClose; +}; + +/*! \struct _XENBUS_EVTCHN_INTERFACE_V8 + \brief EVTCHN interface version 8 + \ingroup interfaces +*/ +struct _XENBUS_EVTCHN_INTERFACE_V8 { + INTERFACE Interface; + XENBUS_EVTCHN_ACQUIRE EvtchnAcquire; + XENBUS_EVTCHN_RELEASE EvtchnRelease; + XENBUS_EVTCHN_OPEN EvtchnOpen; + XENBUS_EVTCHN_BIND EvtchnBind; XENBUS_EVTCHN_UNMASK EvtchnUnmask; XENBUS_EVTCHN_SEND EvtchnSend; XENBUS_EVTCHN_TRIGGER EvtchnTrigger; @@ -312,7 +340,7 @@ struct _XENBUS_EVTCHN_INTERFACE_V7 { XENBUS_EVTCHN_CLOSE EvtchnClose; }; -typedef struct _XENBUS_EVTCHN_INTERFACE_V7 XENBUS_EVTCHN_INTERFACE, *PXENBUS_EVTCHN_INTERFACE; +typedef struct _XENBUS_EVTCHN_INTERFACE_V8 XENBUS_EVTCHN_INTERFACE, *PXENBUS_EVTCHN_INTERFACE; /*! \def XENBUS_EVTCHN \brief Macro at assist in method invocation @@ -323,7 +351,7 @@ typedef struct _XENBUS_EVTCHN_INTERFACE_V7 XENBUS_EVTCHN_INTERFACE, *PXENBUS_EVT #endif // _WINDLL #define XENBUS_EVTCHN_INTERFACE_VERSION_MIN 4 -#define XENBUS_EVTCHN_INTERFACE_VERSION_MAX 7 +#define XENBUS_EVTCHN_INTERFACE_VERSION_MAX 8 #endif // _XENBUS_EVTCHN_INTERFACE_H diff --git a/include/revision.h b/include/revision.h index bc73be2..6aaf888 100644 --- a/include/revision.h +++ b/include/revision.h @@ -52,6 +52,7 @@ DEFINE_REVISION(0x0800000B, 1, 2, 5, 1, 2, 1, 1, 2, 1, 0, 1), \ DEFINE_REVISION(0x09000000, 1, 2, 5, 1, 2, 1, 1, 2, 1, 0, 1), \ DEFINE_REVISION(0x09000001, 1, 2, 6, 1, 2, 1, 1, 2, 1, 1, 1), \ - DEFINE_REVISION(0x09000002, 1, 2, 7, 1, 2, 1, 1, 2, 1, 1, 1) + DEFINE_REVISION(0x09000002, 1, 2, 7, 1, 2, 1, 1, 2, 1, 1, 1), \ + DEFINE_REVISION(0x09000003, 1, 2, 8, 1, 2, 1, 1, 2, 1, 1, 1) #endif // _REVISION_H diff --git a/src/xenbus/console.c b/src/xenbus/console.c index bebc6f3..1ca25f0 100644 --- a/src/xenbus/console.c +++ b/src/xenbus/console.c @@ -354,10 +354,11 @@ ConsoleEnable( FALSE); ASSERT(Context->Channel != NULL); - XENBUS_EVTCHN(Unmask, - &Context->EvtchnInterface, - Context->Channel, - FALSE); + (VOID) XENBUS_EVTCHN(Unmask, + &Context->EvtchnInterface, + Context->Channel, + FALSE, + TRUE); Context->Enabled = TRUE; diff --git a/src/xenbus/evtchn.c b/src/xenbus/evtchn.c index 2ac192d..0748e50 100644 --- a/src/xenbus/evtchn.c +++ b/src/xenbus/evtchn.c @@ -727,16 +727,19 @@ fail1: return status; } -static VOID +static BOOLEAN EvtchnUnmask( IN PINTERFACE Interface, IN PXENBUS_EVTCHN_CHANNEL Channel, - IN BOOLEAN InUpcall + IN BOOLEAN InUpcall, + IN BOOLEAN Force ) { PXENBUS_EVTCHN_CONTEXT Context = Interface->Context; KIRQL Irql = PASSIVE_LEVEL; + BOOLEAN Pending; ULONG LocalPort; + PROCESSOR_NUMBER ProcNumber; ASSERT3U(Channel->Magic, ==, XENBUS_EVTCHN_CHANNEL_MAGIC); @@ -745,27 +748,76 @@ EvtchnUnmask( ASSERT3U(KeGetCurrentIrql(), >=, DISPATCH_LEVEL); + Pending = FALSE; + if (!Channel->Active) goto done; LocalPort = Channel->LocalPort; - if (XENBUS_EVTCHN_ABI(PortUnmask, + Pending = XENBUS_EVTCHN_ABI(PortUnmask, + &Context->EvtchnAbi, + LocalPort); + + if (!Pending) + goto done; + + // + // If we are in context of the upcall, or we cannot tolerate a + // failure to unmask, then use the hypercall. + // + if (InUpcall || Force) { + XENBUS_EVTCHN_ABI(PortMask, &Context->EvtchnAbi, - LocalPort)) { - // - // The event was pending so we must re-mask and use - // a hypercall to do the unmask and raise the event - // + LocalPort); + (VOID) EventChannelUnmask(LocalPort); + + Pending = FALSE; + goto done; + } + + // + // If we are not unmasking on the same CPU to which the + // event channel is bound, then we need to use the hypercall. + // to schedule the upcall on the correct CPU. + // + (VOID) KeGetCurrentProcessorNumberEx(&ProcNumber); + + if (Channel->ProcNumber.Group != ProcNumber.Group || + Channel->ProcNumber.Number != ProcNumber.Number) { XENBUS_EVTCHN_ABI(PortMask, &Context->EvtchnAbi, LocalPort); (VOID) EventChannelUnmask(LocalPort); + + Pending = FALSE; + goto done; } + if (Channel->Mask) + XENBUS_EVTCHN_ABI(PortMask, + &Context->EvtchnAbi, + LocalPort); + + XENBUS_EVTCHN_ABI(PortAck, + &Context->EvtchnAbi, + LocalPort); + done: if (!InUpcall) KeReleaseSpinLock(&Channel->Lock, Irql); + + return Pending; +} + +static VOID +EvtchnUnmaskVersion4( + IN PINTERFACE Interface, + IN PXENBUS_EVTCHN_CHANNEL Channel, + IN BOOLEAN InUpcall + ) +{ + EvtchnUnmask(Interface, Channel, InUpcall, TRUE); } static VOID @@ -1635,7 +1687,7 @@ static struct _XENBUS_EVTCHN_INTERFACE_V4 EvtchnInterfaceVersion4 = { EvtchnRelease, EvtchnOpen, EvtchnBind, - EvtchnUnmask, + EvtchnUnmaskVersion4, EvtchnSendVersion1, EvtchnTrigger, EvtchnGetPort, @@ -1648,7 +1700,7 @@ static struct _XENBUS_EVTCHN_INTERFACE_V5 EvtchnInterfaceVersion5 = { EvtchnRelease, EvtchnOpen, EvtchnBind, - EvtchnUnmask, + EvtchnUnmaskVersion4, EvtchnSendVersion1, EvtchnTrigger, EvtchnWaitVersion5, @@ -1662,7 +1714,7 @@ static struct _XENBUS_EVTCHN_INTERFACE_V6 EvtchnInterfaceVersion6 = { EvtchnRelease, EvtchnOpen, EvtchnBind, - EvtchnUnmask, + EvtchnUnmaskVersion4, EvtchnSend, EvtchnTrigger, EvtchnWaitVersion5, @@ -1676,6 +1728,21 @@ static struct _XENBUS_EVTCHN_INTERFACE_V7 EvtchnInterfaceVersion7 = { EvtchnRelease, EvtchnOpen, EvtchnBind, + EvtchnUnmaskVersion4, + EvtchnSend, + EvtchnTrigger, + EvtchnGetCount, + EvtchnWait, + EvtchnGetPort, + EvtchnClose, +}; + +static struct _XENBUS_EVTCHN_INTERFACE_V8 EvtchnInterfaceVersion8 = { + { sizeof (struct _XENBUS_EVTCHN_INTERFACE_V8), 8, NULL, NULL, NULL }, + EvtchnAcquire, + EvtchnRelease, + EvtchnOpen, + EvtchnBind, EvtchnUnmask, EvtchnSend, EvtchnTrigger, @@ -1861,6 +1928,23 @@ EvtchnGetInterface( status = STATUS_SUCCESS; break; } + case 8: { + struct _XENBUS_EVTCHN_INTERFACE_V8 *EvtchnInterface; + + EvtchnInterface = (struct _XENBUS_EVTCHN_INTERFACE_V8 *)Interface; + + status = STATUS_BUFFER_OVERFLOW; + if (Size < sizeof (struct _XENBUS_EVTCHN_INTERFACE_V8)) + break; + + *EvtchnInterface = EvtchnInterfaceVersion8; + + ASSERT3U(Interface->Version, ==, Version); + Interface->Context = Context; + + status = STATUS_SUCCESS; + break; + } default: status = STATUS_NOT_SUPPORTED; break; diff --git a/src/xenbus/fdo.c b/src/xenbus/fdo.c index c5b5da1..7b9da12 100644 --- a/src/xenbus/fdo.c +++ b/src/xenbus/fdo.c @@ -2675,10 +2675,11 @@ __FdoD3ToD0( if (Fdo->Channel == NULL) goto fail1; - XENBUS_EVTCHN(Unmask, - &Fdo->EvtchnInterface, - Fdo->Channel, - FALSE); + (VOID) XENBUS_EVTCHN(Unmask, + &Fdo->EvtchnInterface, + Fdo->Channel, + FALSE, + TRUE); status = LogAddDisposition(DriverGetConsoleLogLevel(), FdoOutputBuffer, diff --git a/src/xenbus/store.c b/src/xenbus/store.c index 101dc40..0dee054 100644 --- a/src/xenbus/store.c +++ b/src/xenbus/store.c @@ -2152,10 +2152,11 @@ StoreEnable( FALSE); ASSERT(Context->Channel != NULL); - XENBUS_EVTCHN(Unmask, - &Context->EvtchnInterface, - Context->Channel, - FALSE); + (VOID) XENBUS_EVTCHN(Unmask, + &Context->EvtchnInterface, + Context->Channel, + FALSE, + TRUE); Context->Enabled = TRUE; -- 2.5.3 _______________________________________________ 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 |