|
[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 |