[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH 04/10] Separate checking upcall_pending in shared info from EvtchnPoll
The current EvtchnPoll routine in in the shared info code is tied to the two level event channel ABI, wheras checking upcall_pending is ABI independent. Hence the check should be separated into its own method. This patch therefore introduces version 2 of the SHARED_INFO interface, which has a new EvtchnUpcallPending method. Version 1 is still supported by having its EvtchnPoll variant call EvtchnUpcallPending method internally. Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx> --- include/shared_info_interface.h | 43 +++++++++- include/xen.h | 8 ++ src/xen/system.c | 20 ++++- src/xenbus/evtchn.c | 16 +++- src/xenbus/shared_info.c | 174 +++++++++++++++++++++++++++++----------- 5 files changed, 207 insertions(+), 54 deletions(-) diff --git a/include/shared_info_interface.h b/include/shared_info_interface.h index 2e402a8..0d36ac8 100644 --- a/include/shared_info_interface.h +++ b/include/shared_info_interface.h @@ -63,11 +63,34 @@ typedef VOID IN PINTERFACE Interface ); +/*! \typedef XENBUS_SHARED_INFO_UPCALL_PENDING + \brief Private method for EVTCHN inerface +*/ +typedef BOOLEAN +(*XENBUS_SHARED_INFO_UPCALL_PENDING)( + IN PINTERFACE Interface, + IN ULONG Cpu + ); + +typedef BOOLEAN +(*XENBUS_SHARED_INFO_EVENT)( + IN PVOID Argument, + IN ULONG Port + ); + /*! \typedef XENBUS_SHARED_INFO_EVTCHN_POLL \brief Private method for EVTCHN inerface */ typedef BOOLEAN (*XENBUS_SHARED_INFO_EVTCHN_POLL)( + IN PINTERFACE Interface, + IN ULONG Cpu, + IN XENBUS_SHARED_INFO_EVENT Event, + IN PVOID Argument + ); + +typedef BOOLEAN +(*XENBUS_SHARED_INFO_EVTCHN_POLL_V1)( IN PINTERFACE Interface, IN BOOLEAN (*Function)(PVOID, ULONG), IN PVOID Argument @@ -123,6 +146,22 @@ struct _XENBUS_SHARED_INFO_INTERFACE_V1 { INTERFACE Interface; XENBUS_SHARED_INFO_ACQUIRE SharedInfoAcquire; XENBUS_SHARED_INFO_RELEASE SharedInfoRelease; + XENBUS_SHARED_INFO_EVTCHN_POLL_V1 SharedInfoEvtchnPollVersion1; + XENBUS_SHARED_INFO_EVTCHN_ACK SharedInfoEvtchnAck; + XENBUS_SHARED_INFO_EVTCHN_MASK SharedInfoEvtchnMask; + XENBUS_SHARED_INFO_EVTCHN_UNMASK SharedInfoEvtchnUnmask; + XENBUS_SHARED_INFO_GET_TIME SharedInfoGetTime; +}; + +/*! \struct _XENBUS_SHARED_INFO_INTERFACE_V2 + \brief SHARED_INFO interface version 2 + \ingroup interfaces +*/ +struct _XENBUS_SHARED_INFO_INTERFACE_V2 { + INTERFACE Interface; + XENBUS_SHARED_INFO_ACQUIRE SharedInfoAcquire; + XENBUS_SHARED_INFO_RELEASE SharedInfoRelease; + XENBUS_SHARED_INFO_UPCALL_PENDING SharedInfoUpcallPending; XENBUS_SHARED_INFO_EVTCHN_POLL SharedInfoEvtchnPoll; XENBUS_SHARED_INFO_EVTCHN_ACK SharedInfoEvtchnAck; XENBUS_SHARED_INFO_EVTCHN_MASK SharedInfoEvtchnMask; @@ -130,7 +169,7 @@ struct _XENBUS_SHARED_INFO_INTERFACE_V1 { XENBUS_SHARED_INFO_GET_TIME SharedInfoGetTime; }; -typedef struct _XENBUS_SHARED_INFO_INTERFACE_V1 XENBUS_SHARED_INFO_INTERFACE, *PXENBUS_SHARED_INFO_INTERFACE; +typedef struct _XENBUS_SHARED_INFO_INTERFACE_V2 XENBUS_SHARED_INFO_INTERFACE, *PXENBUS_SHARED_INFO_INTERFACE; /*! \def XENBUS_SHARED_INFO \brief Macro at assist in method invocation @@ -141,6 +180,6 @@ typedef struct _XENBUS_SHARED_INFO_INTERFACE_V1 XENBUS_SHARED_INFO_INTERFACE, *P #endif // _WINDLL #define XENBUS_SHARED_INFO_INTERFACE_VERSION_MIN 1 -#define XENBUS_SHARED_INFO_INTERFACE_VERSION_MAX 1 +#define XENBUS_SHARED_INFO_INTERFACE_VERSION_MAX 2 #endif // _XENBUS_SHARED_INFO_H diff --git a/include/xen.h b/include/xen.h index 4a202fc..674676c 100644 --- a/include/xen.h +++ b/include/xen.h @@ -257,4 +257,12 @@ LogPrintf( ... ); +// SYSTEM + +XEN_API +ULONG +SystemVirtualCpuIndex( + IN ULONG Index + ); + #endif // _XEN_H diff --git a/src/xen/system.c b/src/xen/system.c index a9d88c1..1ac8123 100644 --- a/src/xen/system.c +++ b/src/xen/system.c @@ -29,6 +29,8 @@ * SUCH DAMAGE. */ +#define XEN_API __declspec(dllexport) + #include <ntddk.h> #include <ntstrsafe.h> #include <stdlib.h> @@ -447,7 +449,7 @@ SystemPowerStateCallback( } } -extern NTSTATUS +NTSTATUS SystemInitialize( VOID ) @@ -503,7 +505,21 @@ fail1: return status; } -extern VOID +XEN_API +ULONG +SystemVirtualCpuIndex( + IN ULONG Index + ) +{ + PSYSTEM_CONTEXT Context = &SystemContext; + PSYSTEM_CPU Cpu = &Context->Cpu[Index]; + + ASSERT3U(Index, <, MAXIMUM_PROCESSORS); + + return Cpu->ApicID / 2; +} + +VOID SystemTeardown( VOID ) diff --git a/src/xenbus/evtchn.c b/src/xenbus/evtchn.c index 9ba2e84..35ad44a 100644 --- a/src/xenbus/evtchn.c +++ b/src/xenbus/evtchn.c @@ -665,10 +665,20 @@ EvtchnInterrupt( IN PXENBUS_EVTCHN_CONTEXT Context ) { - return XENBUS_SHARED_INFO(EvtchnPoll, + BOOLEAN DoneSomething; + + DoneSomething = FALSE; + + while (XENBUS_SHARED_INFO(UpcallPending, &Context->SharedInfoInterface, - EvtchnPollCallback, - Context); + 0)) + DoneSomething |= XENBUS_SHARED_INFO(EvtchnPoll, + &Context->SharedInfoInterface, + 0, + EvtchnPollCallback, + Context); + + return DoneSomething; } static VOID diff --git a/src/xenbus/shared_info.c b/src/xenbus/shared_info.c index 41c99cf..0afc218 100644 --- a/src/xenbus/shared_info.c +++ b/src/xenbus/shared_info.c @@ -44,6 +44,7 @@ struct _XENBUS_SHARED_INFO_CONTEXT { LONG References; PHYSICAL_ADDRESS Address; shared_info_t *Shared; + ULONG Port; XENBUS_SUSPEND_INTERFACE SuspendInterface; PXENBUS_SUSPEND_CALLBACK SuspendCallbackEarly; XENBUS_DEBUG_INTERFACE DebugInterface; @@ -128,7 +129,7 @@ SharedInfoTestBit( } static VOID -SharedInfoMaskAll( +SharedInfoEvtchnMaskAll( IN PXENBUS_SHARED_INFO_CONTEXT Context ) { @@ -149,70 +150,105 @@ SharedInfoMaskAll( } static BOOLEAN -SharedInfoEvtchnPoll( +SharedInfoUpcallPending( IN PINTERFACE Interface, - IN BOOLEAN (*Function)(PVOID, ULONG), - IN PVOID Argument OPTIONAL + IN ULONG Cpu ) { PXENBUS_SHARED_INFO_CONTEXT Context = Interface->Context; - shared_info_t *Shared; - static ULONG Port; - BOOLEAN DoneSomething; + shared_info_t *Shared = Context->Shared; + int vcpu_id = SystemVirtualCpuIndex(Cpu); + UCHAR Pending; - Shared = Context->Shared; + KeMemoryBarrier(); - DoneSomething = FALSE; + Pending = _InterlockedExchange8((CHAR *)&Shared->vcpu_info[vcpu_id].evtchn_upcall_pending, 0); - for (;;) { - UCHAR Pending; - ULONG_PTR SelectorMask; + return (Pending != 0) ? TRUE : FALSE; +} - KeMemoryBarrier(); +static BOOLEAN +SharedInfoEvtchnPoll( + IN PINTERFACE Interface, + IN ULONG Cpu, + IN XENBUS_SHARED_INFO_EVENT Event, + IN PVOID Argument OPTIONAL + ) +{ + PXENBUS_SHARED_INFO_CONTEXT Context = Interface->Context; + shared_info_t *Shared = Context->Shared; + int vcpu_id = SystemVirtualCpuIndex(Cpu); + ULONG Port; + ULONG_PTR SelectorMask; + BOOLEAN DoneSomething; - Pending = _InterlockedExchange8((CHAR *)&Shared->vcpu_info[0].evtchn_upcall_pending, 0); - if (Pending == 0) - break; + DoneSomething = FALSE; - SelectorMask = (ULONG_PTR)InterlockedExchangePointer((PVOID *)&Shared->vcpu_info[0].evtchn_pending_sel, (PVOID)0); + KeMemoryBarrier(); - KeMemoryBarrier(); + SelectorMask = (ULONG_PTR)InterlockedExchangePointer((PVOID *)&Shared->vcpu_info[vcpu_id].evtchn_pending_sel, (PVOID)0); + + KeMemoryBarrier(); - while (SelectorMask != 0) { - ULONG SelectorBit; - ULONG PortBit; + Port = Context->Port; - SelectorBit = Port / XENBUS_SHARED_INFO_EVTCHN_PER_SELECTOR; - PortBit = Port % XENBUS_SHARED_INFO_EVTCHN_PER_SELECTOR; + while (SelectorMask != 0) { + ULONG SelectorBit; + ULONG PortBit; - if (SharedInfoTestBit(&SelectorMask, SelectorBit)) { - ULONG_PTR PortMask; - PortMask = Shared->evtchn_pending[SelectorBit]; - PortMask &= ~Shared->evtchn_mask[SelectorBit]; + SelectorBit = Port / XENBUS_SHARED_INFO_EVTCHN_PER_SELECTOR; + PortBit = Port % XENBUS_SHARED_INFO_EVTCHN_PER_SELECTOR; + + if (SharedInfoTestBit(&SelectorMask, SelectorBit)) { + ULONG_PTR PortMask; - while (PortMask != 0 && PortBit < XENBUS_SHARED_INFO_EVTCHN_PER_SELECTOR) { - if (SharedInfoTestBit(&PortMask, PortBit)) { - DoneSomething |= Function(Argument, (SelectorBit * XENBUS_SHARED_INFO_EVTCHN_PER_SELECTOR) + PortBit); + PortMask = Shared->evtchn_pending[SelectorBit]; + PortMask &= ~Shared->evtchn_mask[SelectorBit]; - (VOID) SharedInfoClearBitUnlocked(&PortMask, PortBit); - } + while (PortMask != 0 && PortBit < XENBUS_SHARED_INFO_EVTCHN_PER_SELECTOR) { + if (SharedInfoTestBit(&PortMask, PortBit)) { + DoneSomething |= Event(Argument, (SelectorBit * XENBUS_SHARED_INFO_EVTCHN_PER_SELECTOR) + PortBit); - PortBit++; + PortMask &= ~((ULONG_PTR)1 << PortBit); } - // Are we done with this selector? - if (PortMask == 0) - (VOID) SharedInfoClearBitUnlocked(&SelectorMask, SelectorBit); + PortBit++; } - Port = (SelectorBit + 1) * XENBUS_SHARED_INFO_EVTCHN_PER_SELECTOR; - - if (Port >= XENBUS_SHARED_INFO_EVTCHN_SELECTOR_COUNT * XENBUS_SHARED_INFO_EVTCHN_PER_SELECTOR) - Port = 0; + // Are we done with this selector? + if (PortMask == 0) + SelectorMask &= ~((ULONG_PTR)1 << SelectorBit); } + + Port = (SelectorBit + 1) * XENBUS_SHARED_INFO_EVTCHN_PER_SELECTOR; + + if (Port >= XENBUS_SHARED_INFO_EVTCHN_SELECTOR_COUNT * XENBUS_SHARED_INFO_EVTCHN_PER_SELECTOR) + Port = 0; } + Context->Port = Port; + + return DoneSomething; +} + +static BOOLEAN +SharedInfoEvtchnPollVersion1( + IN PINTERFACE Interface, + IN BOOLEAN (*Function)(PVOID, ULONG), + IN PVOID Argument OPTIONAL + ) +{ + BOOLEAN DoneSomething; + + DoneSomething = FALSE; + + while (SharedInfoUpcallPending(Interface, 0)) + DoneSomething |= SharedInfoEvtchnPoll(Interface, + 0, + Function, + Argument); + return DoneSomething; } @@ -404,7 +440,7 @@ SharedInfoSuspendCallbackEarly( PXENBUS_SHARED_INFO_CONTEXT Context = Argument; SharedInfoMap(Context); - SharedInfoMaskAll(Context); + SharedInfoEvtchnMaskAll(Context); } static VOID @@ -423,17 +459,30 @@ SharedInfoDebugCallback( if (!Crashing) { shared_info_t *Shared; + LONG Cpu; ULONG Selector; Shared = Context->Shared; KeMemoryBarrier(); - XENBUS_DEBUG(Printf, - &Context->DebugInterface, - "CPU: PENDING: %s SELECTOR MASK: %p\n", - Shared->vcpu_info[0].evtchn_upcall_pending ? "TRUE" : "FALSE", - (PVOID)Shared->vcpu_info[0].evtchn_pending_sel); + for (Cpu = 0; Cpu < KeNumberProcessors; Cpu++) { + int vcpu_id = SystemVirtualCpuIndex(Cpu); + + XENBUS_DEBUG(Printf, + &Context->DebugInterface, + "CPU %u: PENDING: %s\n", + Cpu, + Shared->vcpu_info[vcpu_id].evtchn_upcall_pending ? + "TRUE" : + "FALSE"); + + XENBUS_DEBUG(Printf, + &Context->DebugInterface, + "CPU %u: SELECTOR MASK: %p\n", + Cpu, + (PVOID)Shared->vcpu_info[vcpu_id].evtchn_pending_sel); + } for (Selector = 0; Selector < XENBUS_SHARED_INFO_EVTCHN_SELECTOR_COUNT; Selector += 4) { XENBUS_DEBUG(Printf, @@ -490,7 +539,7 @@ SharedInfoAcquire( if (Context->Shared == NULL) goto fail2; - SharedInfoMaskAll(Context); + SharedInfoEvtchnMaskAll(Context); status = XENBUS_SUSPEND(Acquire, &Context->SuspendInterface); if (!NT_SUCCESS(status)) @@ -583,6 +632,8 @@ SharedInfoRelease ( Trace("====>\n"); + Context->Port = 0; + XENBUS_DEBUG(Deregister, &Context->DebugInterface, Context->DebugCallback); @@ -615,6 +666,18 @@ static struct _XENBUS_SHARED_INFO_INTERFACE_V1 SharedInfoInterfaceVersion1 = { { sizeof (struct _XENBUS_SHARED_INFO_INTERFACE_V1), 1, NULL, NULL, NULL }, SharedInfoAcquire, SharedInfoRelease, + SharedInfoEvtchnPollVersion1, + SharedInfoEvtchnAck, + SharedInfoEvtchnMask, + SharedInfoEvtchnUnmask, + SharedInfoGetTime +}; + +static struct _XENBUS_SHARED_INFO_INTERFACE_V2 SharedInfoInterfaceVersion2 = { + { sizeof (struct _XENBUS_SHARED_INFO_INTERFACE_V2), 2, NULL, NULL, NULL }, + SharedInfoAcquire, + SharedInfoRelease, + SharedInfoUpcallPending, SharedInfoEvtchnPoll, SharedInfoEvtchnAck, SharedInfoEvtchnMask, @@ -696,6 +759,23 @@ SharedInfoGetInterface( status = STATUS_SUCCESS; break; } + case 2: { + struct _XENBUS_SHARED_INFO_INTERFACE_V2 *SharedInfoInterface; + + SharedInfoInterface = (struct _XENBUS_SHARED_INFO_INTERFACE_V2 *)Interface; + + status = STATUS_BUFFER_OVERFLOW; + if (Size < sizeof (struct _XENBUS_SHARED_INFO_INTERFACE_V2)) + break; + + *SharedInfoInterface = SharedInfoInterfaceVersion2; + + ASSERT3U(Interface->Version, ==, Version); + Interface->Context = Context; + + status = STATUS_SUCCESS; + break; + } default: status = STATUS_NOT_SUPPORTED; break; -- 2.1.1 _______________________________________________ win-pv-devel mailing list win-pv-devel@xxxxxxxxxxxxxxxxxxxx http://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |