[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH xenbus 3/8] Introduce XENBUS_SHARED_INFO_PROCESSOR to hold per-CPU state
From: Paul Durrant <pdurrant@xxxxxxxxxx> This allows the vcpu_info pointer and vcpu_id to be retrieved once for each vCPU during SharedInfoAcquire(). It also provides a convenient place to save the event port that terminated the previous poll (which, for fairness, is where the next poll starts from). Signed-off-by: Paul Durrant <pdurrant@xxxxxxxxxx> --- src/xenbus/shared_info.c | 190 +++++++++++++++++++++++++++------------ 1 file changed, 132 insertions(+), 58 deletions(-) diff --git a/src/xenbus/shared_info.c b/src/xenbus/shared_info.c index 9c9f0b4cf3e3..20f07a82d801 100644 --- a/src/xenbus/shared_info.c +++ b/src/xenbus/shared_info.c @@ -42,17 +42,24 @@ #define XENBUS_SHARED_INFO_EVTCHN_PER_SELECTOR (sizeof (ULONG_PTR) * 8) #define XENBUS_SHARED_INFO_EVTCHN_SELECTOR_COUNT (RTL_FIELD_SIZE(shared_info_t, evtchn_pending) / sizeof (ULONG_PTR)) +typedef struct _XENBUS_SHARED_INFO_PROCESSOR { + unsigned int vcpu_id; + vcpu_info_t *Vcpu; + ULONG Port; +} XENBUS_SHARED_INFO_PROCESSOR, *PXENBUS_SHARED_INFO_PROCESSOR; + struct _XENBUS_SHARED_INFO_CONTEXT { - PXENBUS_FDO Fdo; - KSPIN_LOCK Lock; - LONG References; - PHYSICAL_ADDRESS Address; - shared_info_t *Shared; - ULONG Port[HVM_MAX_VCPUS]; - XENBUS_SUSPEND_INTERFACE SuspendInterface; - PXENBUS_SUSPEND_CALLBACK SuspendCallbackEarly; - XENBUS_DEBUG_INTERFACE DebugInterface; - PXENBUS_DEBUG_CALLBACK DebugCallback; + PXENBUS_FDO Fdo; + KSPIN_LOCK Lock; + LONG References; + PHYSICAL_ADDRESS Address; + shared_info_t *Shared; + PXENBUS_SHARED_INFO_PROCESSOR Processor; + ULONG ProcessorCount; + XENBUS_SUSPEND_INTERFACE SuspendInterface; + PXENBUS_SUSPEND_CALLBACK SuspendCallbackEarly; + XENBUS_DEBUG_INTERFACE DebugInterface; + PXENBUS_DEBUG_CALLBACK DebugCallback; }; #define XENBUS_SHARED_INFO_TAG 'OFNI' @@ -155,20 +162,22 @@ SharedInfoEvtchnMaskAll( static BOOLEAN SharedInfoUpcallPending( - IN PINTERFACE Interface, - IN ULONG Index + IN PINTERFACE Interface, + IN ULONG Index ) { - vcpu_info_t *Vcpu; - UCHAR Pending; - NTSTATUS status; + PXENBUS_SHARED_INFO_CONTEXT Context = Interface->Context; + PXENBUS_SHARED_INFO_PROCESSOR Processor = &Context->Processor[Index]; + vcpu_info_t *Vcpu; + UCHAR Pending; - UNREFERENCED_PARAMETER(Interface); + ASSERT3U(Index, <, Context->ProcessorCount); - status = SystemProcessorVcpuInfo(Index, &Vcpu); - if (!NT_SUCCESS(status)) + if (Processor->Vcpu == NULL) return FALSE; + Vcpu = Processor->Vcpu; + KeMemoryBarrier(); Pending = _InterlockedExchange8((CHAR *)&Vcpu->evtchn_upcall_pending, 0); @@ -185,37 +194,36 @@ SharedInfoEvtchnPoll( ) { PXENBUS_SHARED_INFO_CONTEXT Context = Interface->Context; + PXENBUS_SHARED_INFO_PROCESSOR Processor = &Context->Processor[Index]; shared_info_t *Shared = Context->Shared; unsigned int vcpu_id; vcpu_info_t *Vcpu; ULONG Port; ULONG_PTR SelectorMask; BOOLEAN DoneSomething; - NTSTATUS status; DoneSomething = FALSE; - status = SystemProcessorVcpuId(Index, &vcpu_id); - if (!NT_SUCCESS(status)) - goto done; + ASSERT3U(Index, <, Context->ProcessorCount); - status = SystemProcessorVcpuInfo(Index, &Vcpu); - if (!NT_SUCCESS(status)) + if (Processor->Vcpu == NULL) goto done; + vcpu_id = Processor->vcpu_id; + Vcpu = Processor->Vcpu; + KeMemoryBarrier(); SelectorMask = (ULONG_PTR)InterlockedExchangePointer((PVOID *)&Vcpu->evtchn_pending_sel, (PVOID)0); KeMemoryBarrier(); - Port = Context->Port[vcpu_id]; + Port = Processor->Port; while (SelectorMask != 0) { ULONG SelectorBit; ULONG PortBit; - SelectorBit = Port / XENBUS_SHARED_INFO_EVTCHN_PER_SELECTOR; PortBit = Port % XENBUS_SHARED_INFO_EVTCHN_PER_SELECTOR; @@ -246,7 +254,7 @@ SharedInfoEvtchnPoll( Port = 0; } - Context->Port[vcpu_id] = Port; + Processor->Port = Port; done: return DoneSomething; @@ -316,36 +324,35 @@ SharedInfoEvtchnUnmask( static VOID SharedInfoGetTime( - IN PINTERFACE Interface, - OUT PLARGE_INTEGER Time, - OUT PBOOLEAN Local + IN PINTERFACE Interface, + OUT PLARGE_INTEGER Time, + OUT PBOOLEAN Local ) { #define NS_PER_S 1000000000ull - PXENBUS_SHARED_INFO_CONTEXT Context = Interface->Context; - shared_info_t *Shared; - vcpu_info_t *Vcpu; - ULONG WcVersion; - ULONG TimeVersion; - ULONGLONG Seconds; - ULONGLONG NanoSeconds; - ULONGLONG Timestamp; - ULONGLONG Tsc; - ULONGLONG SystemTime; - ULONG TscSystemMul; - CHAR TscShift; - TIME_FIELDS TimeFields; - KIRQL Irql; - NTSTATUS status; + PXENBUS_SHARED_INFO_CONTEXT Context = Interface->Context; + PXENBUS_SHARED_INFO_PROCESSOR Processor = &Context->Processor[0]; + shared_info_t *Shared; + vcpu_info_t *Vcpu; + ULONG WcVersion; + ULONG TimeVersion; + ULONGLONG Seconds; + ULONGLONG NanoSeconds; + ULONGLONG Timestamp; + ULONGLONG Tsc; + ULONGLONG SystemTime; + ULONG TscSystemMul; + CHAR TscShift; + TIME_FIELDS TimeFields; + KIRQL Irql; // Make sure we don't suspend KeRaiseIrql(DISPATCH_LEVEL, &Irql); Shared = Context->Shared; - - status = SystemProcessorVcpuInfo(0, &Vcpu); - ASSERT(NT_SUCCESS(status)); + Vcpu = Processor->Vcpu; + ASSERT(Vcpu != NULL); // Loop until we can read a consistent set of values from the same update do { @@ -554,13 +561,16 @@ SharedInfoDebugCallback( static NTSTATUS SharedInfoAcquire( - IN PINTERFACE Interface + IN PINTERFACE Interface ) { - PXENBUS_SHARED_INFO_CONTEXT Context = Interface->Context; - PXENBUS_FDO Fdo = Context->Fdo; - KIRQL Irql; - NTSTATUS status; + PXENBUS_SHARED_INFO_CONTEXT Context = Interface->Context; + PXENBUS_FDO Fdo = Context->Fdo; + KIRQL Irql; + shared_info_t *Shared; + LONG Index; + PXENBUS_SHARED_INFO_PROCESSOR Processor; + NTSTATUS status; KeAcquireSpinLock(&Context->Lock, &Irql); @@ -602,6 +612,27 @@ SharedInfoAcquire( if (!NT_SUCCESS(status)) goto fail5; + Context->ProcessorCount = KeQueryMaximumProcessorCountEx(ALL_PROCESSOR_GROUPS); + Context->Processor = __SharedInfoAllocate(sizeof (XENBUS_SHARED_INFO_PROCESSOR) * Context->ProcessorCount); + + status = STATUS_NO_MEMORY; + if (Context->Processor == NULL) + goto fail6; + + Shared = Context->Shared; + + for (Index = 0; Index < (LONG)Context->ProcessorCount; Index++) { + Processor = &Context->Processor[Index]; + + status = SystemProcessorVcpuId(Index, &Processor->vcpu_id); + if (!NT_SUCCESS(status)) + goto fail7; + + status = SystemProcessorVcpuInfo(Index, &Processor->Vcpu); + if (!NT_SUCCESS(status) && status != STATUS_NOT_SUPPORTED) + goto fail8; + } + Trace("<====\n"); done: @@ -609,6 +640,35 @@ done: return STATUS_SUCCESS; +fail8: + Error("fail8\n"); + + Processor->vcpu_id = 0; + +fail7: + Error("fail7\n"); + + while (--Index >= 0) { + Processor = &Context->Processor[Index]; + + Processor->Vcpu = NULL; + Processor->vcpu_id = 0; + } + + ASSERT(IsZeroMemory(Context->Processor, sizeof (XENBUS_SHARED_INFO_PROCESSOR) * Context->ProcessorCount)); + __SharedInfoFree(Context->Processor); + Context->Processor = NULL; + +fail6: + Error("fail6\n"); + + Context->ProcessorCount = 0; + + XENBUS_DEBUG(Deregister, + &Context->DebugInterface, + Context->DebugCallback); + Context->DebugCallback = NULL; + fail5: Error("fail5\n"); @@ -648,12 +708,14 @@ fail1: static VOID SharedInfoRelease ( - IN PINTERFACE Interface + IN PINTERFACE Interface ) { - PXENBUS_SHARED_INFO_CONTEXT Context = Interface->Context; - PXENBUS_FDO Fdo = Context->Fdo; - KIRQL Irql; + PXENBUS_SHARED_INFO_CONTEXT Context = Interface->Context; + PXENBUS_FDO Fdo = Context->Fdo; + KIRQL Irql; + LONG Index; + PXENBUS_SHARED_INFO_PROCESSOR Processor; KeAcquireSpinLock(&Context->Lock, &Irql); @@ -662,7 +724,19 @@ SharedInfoRelease ( Trace("====>\n"); - RtlZeroMemory(Context->Port, sizeof (ULONG) * HVM_MAX_VCPUS); + Index = (LONG)Context->ProcessorCount; + while (--Index >= 0) { + Processor = &Context->Processor[Index]; + + Processor->Port = 0; + Processor->Vcpu = NULL; + Processor->vcpu_id = 0; + } + + ASSERT(IsZeroMemory(Context->Processor, sizeof (XENBUS_SHARED_INFO_PROCESSOR) * Context->ProcessorCount)); + __SharedInfoFree(Context->Processor); + Context->Processor = NULL; + Context->ProcessorCount = 0; XENBUS_DEBUG(Deregister, &Context->DebugInterface, -- 2.17.1
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |