\param Interface The interface header
\param DeviceID The DeviceID of the device
- \param InstanceID The (un-prefixed) InstanceID of the device
+ \param InstanceID The (un-prefixed) InstanceID of the device or
+ NULL to match any device instance
\return TRUE if the specified device is present in the system or
FALSE if it is not
*/
(*XENFILT_EMULATED_IS_DEVICE_PRESENT)(
IN PVOID Context,
IN PCHAR DeviceID,
- IN PCHAR InstanceID
+ IN PCHAR InstanceID OPTIONAL
);
/*! \typedef XENFILT_EMULATED_IS_DISK_PRESENT
...
);
+typedef NTSTATUS
+(*XENBUS_EVTCHN_BIND_V2)(
+ IN PINTERFACE Interface,
+ IN PXENBUS_EVTCHN_CHANNEL Channel,
+ IN ULONG Cpu
+ );
+
/*! \typedef XENBUS_EVTCHN_BIND
\brief Bind an event channel to a specific CPU
\param Interface The interface header
\param Channel The channel handle
- \param Cpu The CPU that should handle events
+ \param Group The group number of the CPU that should handle events
+ \param Number The relative number of the CPU that should handle events
*/
typedef NTSTATUS
(*XENBUS_EVTCHN_BIND)(
IN PINTERFACE Interface,
IN PXENBUS_EVTCHN_CHANNEL Channel,
- IN ULONG Cpu
+ IN USHORT Group,
+ IN UCHAR Number
);
typedef BOOLEAN
XENBUS_EVTCHN_ACQUIRE EvtchnAcquire;
XENBUS_EVTCHN_RELEASE EvtchnRelease;
XENBUS_EVTCHN_OPEN EvtchnOpen;
- XENBUS_EVTCHN_BIND EvtchnBind;
+ XENBUS_EVTCHN_BIND_V2 EvtchnBindVersion2;
XENBUS_EVTCHN_UNMASK_V1 EvtchnUnmaskVersion1;
XENBUS_EVTCHN_SEND EvtchnSend;
XENBUS_EVTCHN_TRIGGER EvtchnTrigger;
\ingroup interfaces
*/
struct _XENBUS_EVTCHN_INTERFACE_V3 {
+ INTERFACE Interface;
+ XENBUS_EVTCHN_ACQUIRE EvtchnAcquire;
+ XENBUS_EVTCHN_RELEASE EvtchnRelease;
+ XENBUS_EVTCHN_OPEN EvtchnOpen;
+ XENBUS_EVTCHN_BIND_V2 EvtchnBindVersion2;
+ XENBUS_EVTCHN_UNMASK EvtchnUnmask;
+ XENBUS_EVTCHN_SEND EvtchnSend;
+ XENBUS_EVTCHN_TRIGGER EvtchnTrigger;
+ XENBUS_EVTCHN_GET_PORT EvtchnGetPort;
+ XENBUS_EVTCHN_CLOSE EvtchnClose;
+};
+
+/*! \struct _XENBUS_EVTCHN_INTERFACE_V4
+ \brief EVTCHN interface version 4
+ \ingroup interfaces
+*/
+struct _XENBUS_EVTCHN_INTERFACE_V4 {
INTERFACE Interface;
XENBUS_EVTCHN_ACQUIRE EvtchnAcquire;
XENBUS_EVTCHN_RELEASE EvtchnRelease;
XENBUS_EVTCHN_CLOSE EvtchnClose;
};
-typedef struct _XENBUS_EVTCHN_INTERFACE_V3 XENBUS_EVTCHN_INTERFACE, *PXENBUS_EVTCHN_INTERFACE;
+typedef struct _XENBUS_EVTCHN_INTERFACE_V4 XENBUS_EVTCHN_INTERFACE, *PXENBUS_EVTCHN_INTERFACE;
/*! \def XENBUS_EVTCHN
\brief Macro at assist in method invocation
#endif // _WINDLL
#define XENBUS_EVTCHN_INTERFACE_VERSION_MIN 1
-#define XENBUS_EVTCHN_INTERFACE_VERSION_MAX 3
+#define XENBUS_EVTCHN_INTERFACE_VERSION_MAX 4
#endif // _XENBUS_EVTCHN_INTERFACE_H
*/
#include <ntddk.h>
+#include <procgrp.h>
#include <version.h>
#include "registry.h"
PDRIVER_OBJECT DriverObject;
HANDLE ParametersKey;
HANDLE AddressesKey;
- ULONG MaximumQueues;
} XENVIF_DRIVER, *PXENVIF_DRIVER;
static XENVIF_DRIVER Driver;
return __DriverGetAddressesKey();
}
-static FORCEINLINE VOID
-__DriverSetMaximumQueueCount(
- IN ULONG Count
- )
-{
- Driver.MaximumQueues = Count;
-}
-
-static FORCEINLINE ULONG
-__DriverGetMaximumQueueCount(
- VOID
- )
-{
- return Driver.MaximumQueues;
-}
-
-ULONG
-DriverGetMaximumQueueCount(
- VOID
- )
-{
- return __DriverGetMaximumQueueCount();
-}
-
DRIVER_UNLOAD DriverUnload;
VOID
ParametersKey = __DriverGetParametersKey();
__DriverSetParametersKey(NULL);
- __DriverSetMaximumQueueCount(0);
-
RegistryCloseKey(ParametersKey);
RegistryTeardown();
HANDLE ParametersKey;
HANDLE AddressesKey;
ULONG Index;
- ULONG MaxQueues;
- ULONG Processors;
NTSTATUS status;
ASSERT3P(__DriverGetDriverObject(), ==, NULL);
ExInitializeDriverRuntime(DrvRtPoolNxOptIn);
+ WdmlibProcgrpInitialize();
__DbgPrintEnable();
__DriverSetAddressesKey(AddressesKey);
- status = RegistryQueryDwordValue(ParametersKey,
- "MultiQueueMaxQueues",
- &MaxQueues);
- if (!NT_SUCCESS(status))
- MaxQueues = MAXIMUM_PROCESSORS;
-
- Processors = KeQueryActiveProcessorCount(NULL);
- __DriverSetMaximumQueueCount(MaxQueues > Processors ?
- Processors :
- MaxQueues);
-
RegistryCloseKey(ServiceKey);
DriverObject->DriverExtension->AddDevice = AddDevice;
VOID
);
-extern ULONG
-DriverGetMaximumQueueCount(
- VOID
- );
-
typedef struct _XENVIF_PDO XENVIF_PDO, *PXENVIF_PDO;
typedef struct _XENVIF_FDO XENVIF_FDO, *PXENVIF_FDO;
*/
#include <ntddk.h>
+#include <procgrp.h>
#include <ntstrsafe.h>
#include <stdlib.h>
#include <netioapi.h>
#include "assert.h"
#include "util.h"
+typedef struct _XENVIF_FRONTEND_STATISTICS {
+ ULONGLONG Value[XENVIF_VIF_STATISTIC_COUNT];
+} XENVIF_FRONTEND_STATISTICS, *PXENVIF_FRONTEND_STATISTICS;
+
struct _XENVIF_FRONTEND {
PXENVIF_PDO Pdo;
PCHAR Path;
PCHAR BackendPath;
USHORT BackendDomain;
- ULONG QueueCount;
+ ULONG MaxQueues;
+ ULONG NumQueues;
PXENVIF_MAC Mac;
PXENVIF_RECEIVER Receiver;
PXENBUS_DEBUG_CALLBACK DebugCallback;
PXENBUS_STORE_WATCH Watch;
- ULONGLONG Statistic[XENVIF_VIF_STATISTIC_COUNT][MAXIMUM_PROCESSORS];
+ PXENVIF_FRONTEND_STATISTICS Statistics;
+ ULONG StatisticsCount;
};
static const PCHAR
}
static FORCEINLINE VOID
-__FrontendSetQueueCount(
- IN PXENVIF_FRONTEND Frontend,
- IN ULONG Count
+__FrontendSetMaxQueues(
+ IN PXENVIF_FRONTEND Frontend
)
{
- Frontend->QueueCount = Count;
+ HANDLE ParametersKey;
+ ULONG FrontendMaxQueues;
+ NTSTATUS status;
+
+ Frontend->MaxQueues = KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS);
+
+ ParametersKey = DriverGetParametersKey();
+
+ status = RegistryQueryDwordValue(ParametersKey,
+ "FrontendMaxQueues",
+ &FrontendMaxQueues);
+ if (NT_SUCCESS(status) && FrontendMaxQueues < Frontend->MaxQueues)
+ Frontend->MaxQueues = FrontendMaxQueues;
+
+ Info("%u\n", Frontend->MaxQueues);
}
static FORCEINLINE ULONG
-__FrontendGetQueueCount(
+__FrontendGetMaxQueues(
IN PXENVIF_FRONTEND Frontend
)
{
- return Frontend->QueueCount;
+ return Frontend->MaxQueues;
}
ULONG
-FrontendGetQueueCount(
+FrontendGetMaxQueues(
IN PXENVIF_FRONTEND Frontend
)
{
- return __FrontendGetQueueCount(Frontend);
+ return __FrontendGetMaxQueues(Frontend);
}
PCHAR
static FORCEINLINE VOID
__FrontendQueryStatistic(
IN PXENVIF_FRONTEND Frontend,
- IN XENVIF_VIF_STATISTIC Index,
+ IN XENVIF_VIF_STATISTIC Name,
OUT PULONGLONG Value
)
{
- ULONG Cpu;
+ ULONG Index;
- ASSERT(Index < XENVIF_VIF_STATISTIC_COUNT);
+ ASSERT(Name < XENVIF_VIF_STATISTIC_COUNT);
*Value = 0;
- for (Cpu = 0; Cpu < MAXIMUM_PROCESSORS; Cpu++)
- *Value += Frontend->Statistic[Index][Cpu];
+ for (Index = 0; Index < Frontend->StatisticsCount; Index++) {
+ PXENVIF_FRONTEND_STATISTICS Statistics;
+
+ Statistics = &Frontend->Statistics[Index];
+ *Value += Statistics->Value[Name];
+ }
}
VOID
FrontendQueryStatistic(
IN PXENVIF_FRONTEND Frontend,
- IN XENVIF_VIF_STATISTIC Index,
+ IN XENVIF_VIF_STATISTIC Name,
OUT PULONGLONG Value
)
{
- __FrontendQueryStatistic(Frontend, Index, Value);
+ __FrontendQueryStatistic(Frontend, Name, Value);
}
VOID
FrontendIncrementStatistic(
IN PXENVIF_FRONTEND Frontend,
- IN XENVIF_VIF_STATISTIC Index,
+ IN XENVIF_VIF_STATISTIC Name,
IN ULONGLONG Delta
)
{
- ULONG Cpu;
+ ULONG Index;
+ PXENVIF_FRONTEND_STATISTICS Statistics;
- ASSERT(Index < XENVIF_VIF_STATISTIC_COUNT);
+ ASSERT(Name < XENVIF_VIF_STATISTIC_COUNT);
ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
- Cpu = KeGetCurrentProcessorNumber();
- Frontend->Statistic[Index][Cpu] += Delta;
+ Index = KeGetCurrentProcessorNumberEx(NULL);
+
+ ASSERT3U(Index, <, Frontend->StatisticsCount);
+ Statistics = &Frontend->Statistics[Index];
+
+ Statistics->Value[Name] += Delta;
}
static FORCEINLINE const CHAR *
__FrontendStatisticName(
- IN XENVIF_VIF_STATISTIC Index
+ IN XENVIF_VIF_STATISTIC Name
)
{
-#define _FRONTEND_STATISTIC_NAME(_Index) \
- case XENVIF_ ## _Index: \
- return #_Index;
+#define _FRONTEND_STATISTIC_NAME(_Name) \
+ case XENVIF_ ## _Name: \
+ return #_Name;
- switch (Index) {
+ switch (Name) {
_FRONTEND_STATISTIC_NAME(TRANSMITTER_PACKETS_DROPPED);
_FRONTEND_STATISTIC_NAME(TRANSMITTER_BACKEND_ERRORS);
_FRONTEND_STATISTIC_NAME(TRANSMITTER_FRONTEND_ERRORS);
)
{
PXENVIF_FRONTEND Frontend = Argument;
- XENVIF_VIF_STATISTIC Index;
+ XENVIF_VIF_STATISTIC Name;
UNREFERENCED_PARAMETER(Crashing);
&Frontend->DebugInterface,
"STATISTICS:\n");
- for (Index = 0; Index < XENVIF_VIF_STATISTIC_COUNT; Index++) {
+ for (Name = 0; Name < XENVIF_VIF_STATISTIC_COUNT; Name++) {
ULONGLONG Value;
- __FrontendQueryStatistic(Frontend, Index, &Value);
+ __FrontendQueryStatistic(Frontend, Name, &Value);
XENBUS_DEBUG(Printf,
&Frontend->DebugInterface,
" - %40s %lu\n",
- __FrontendStatisticName(Index),
+ __FrontendStatisticName(Name),
Value);
}
}
static FORCEINLINE VOID
-__FrontendReadQueueCount(
+__FrontendSetNumQueues(
IN PXENVIF_FRONTEND Frontend
)
{
PCHAR Buffer;
- ULONG Value;
+ ULONG BackendMaxQueues;
NTSTATUS status;
- // default to 1 queue.
- // backend must advertise "multi-queue-max-queues" to enable
- // multi-queue support.
- Value = 1;
-
status = XENBUS_STORE(Read,
&Frontend->StoreInterface,
NULL,
"multi-queue-max-queues",
&Buffer);
if (NT_SUCCESS(status)) {
- Value = (ULONG)strtoul(Buffer, NULL, 10);
+ BackendMaxQueues = (ULONG)strtoul(Buffer, NULL, 10);
XENBUS_STORE(Free,
&Frontend->StoreInterface,
Buffer);
-
- // set value to minimum of what frontend supports (vCPUs) and
- // what backend supports (Dom0 vCPUs)
- if (Value > DriverGetMaximumQueueCount())
- Value = DriverGetMaximumQueueCount();
+ } else {
+ BackendMaxQueues = 1;
}
- __FrontendSetQueueCount(Frontend, Value);
+ Frontend->NumQueues = __min(Frontend->MaxQueues, BackendMaxQueues);
+
+ Info("%u\n", Frontend->NumQueues);
+}
+
+static FORCEINLINE ULONG
+__FrontendGetNumQueues(
+ IN PXENVIF_FRONTEND Frontend
+ )
+{
+ return Frontend->NumQueues;
+}
+
+ULONG
+FrontendGetNumQueues(
+ IN PXENVIF_FRONTEND Frontend
+ )
+{
+ return __FrontendGetNumQueues(Frontend);
}
static FORCEINLINE NTSTATUS
Trace("====>\n");
+ Frontend->StatisticsCount = KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS);
+ Frontend->Statistics = __FrontendAllocate(sizeof (XENVIF_FRONTEND_STATISTICS) * Frontend->StatisticsCount);
+
+ status = STATUS_NO_MEMORY;
+ if (Frontend->Statistics == NULL)
+ goto fail1;
+
status = XENBUS_DEBUG(Acquire, &Frontend->DebugInterface);
if (!NT_SUCCESS(status))
- goto fail1;
+ goto fail2;
status = XENBUS_DEBUG(Register,
&Frontend->DebugInterface,
Frontend,
&Frontend->DebugCallback);
if (!NT_SUCCESS(status))
- goto fail2;
+ goto fail3;
status = MacConnect(__FrontendGetMac(Frontend));
if (!NT_SUCCESS(status))
- goto fail3;
+ goto fail4;
+
+ __FrontendSetNumQueues(Frontend);
- __FrontendReadQueueCount(Frontend);
status = ReceiverConnect(__FrontendGetReceiver(Frontend));
if (!NT_SUCCESS(status))
- goto fail4;
+ goto fail5;
status = TransmitterConnect(__FrontendGetTransmitter(Frontend));
if (!NT_SUCCESS(status))
- goto fail5;
+ goto fail6;
Attempt = 0;
do {
__FrontendGetPath(Frontend),
"multi-queue-num-queues",
"%u",
- __FrontendGetQueueCount(Frontend));
+ __FrontendGetNumQueues(Frontend));
if (!NT_SUCCESS(status))
goto abort;
} while (status == STATUS_RETRY);
if (!NT_SUCCESS(status))
- goto fail6;
+ goto fail7;
status = XENBUS_STORE(Printf,
&Frontend->StoreInterface,
"%u",
XenbusStateConnected);
if (!NT_SUCCESS(status))
- goto fail7;
+ goto fail8;
State = XenbusStateInitWait;
status = __FrontendWaitForStateChange(Frontend, Path, &State);
if (!NT_SUCCESS(status))
- goto fail8;
+ goto fail9;
status = STATUS_UNSUCCESSFUL;
if (State != XenbusStateConnected)
- goto fail9;
+ goto fail10;
ThreadWake(Frontend->MibThread);
Trace("<====\n");
return STATUS_SUCCESS;
+fail10:
+ Error("fail10\n");
+
fail9:
Error("fail9\n");
fail7:
Error("fail7\n");
+ TransmitterDisconnect(__FrontendGetTransmitter(Frontend));
+
fail6:
Error("fail6\n");
- TransmitterDisconnect(__FrontendGetTransmitter(Frontend));
+ ReceiverDisconnect(__FrontendGetReceiver(Frontend));
fail5:
Error("fail5\n");
- ReceiverDisconnect(__FrontendGetReceiver(Frontend));
+ MacDisconnect(__FrontendGetMac(Frontend));
+
+ Frontend->NumQueues = 0;
fail4:
Error("fail4\n");
- MacDisconnect(__FrontendGetMac(Frontend));
-
-fail3:
- Error("fail3\n");
-
XENBUS_DEBUG(Deregister,
&Frontend->DebugInterface,
Frontend->DebugCallback);
Frontend->DebugCallback = NULL;
+fail3:
+ Error("fail3\n");
+
+ XENBUS_DEBUG(Release, &Frontend->DebugInterface);
+
fail2:
Error("fail2\n");
- XENBUS_DEBUG(Release, &Frontend->DebugInterface);
+ __FrontendFree(Frontend->Statistics);
+ Frontend->StatisticsCount = 0;
fail1:
Error("fail1 (%08x)\n", status);
ReceiverDisconnect(__FrontendGetReceiver(Frontend));
MacDisconnect(__FrontendGetMac(Frontend));
+ Frontend->NumQueues = 0;
+
XENBUS_DEBUG(Deregister,
&Frontend->DebugInterface,
Frontend->DebugCallback);
XENBUS_DEBUG(Release, &Frontend->DebugInterface);
- RtlZeroMemory(&Frontend->Statistic, sizeof (Frontend->Statistic));
+ __FrontendFree(Frontend->Statistics);
+ Frontend->StatisticsCount = 0;
Trace("<====\n");
}
FdoGetSuspendInterface(PdoGetFdo(Pdo), &(*Frontend)->SuspendInterface);
FdoGetStoreInterface(PdoGetFdo(Pdo), &(*Frontend)->StoreInterface);
+ __FrontendSetMaxQueues(*Frontend);
+
status = MacInitialize(*Frontend, &(*Frontend)->Mac);
if (!NT_SUCCESS(status))
goto fail6;
fail6:
Error("fail6\n");
+ (*Frontend)->MaxQueues = 0;
+
RtlZeroMemory(&(*Frontend)->StoreInterface,
sizeof (XENBUS_STORE_INTERFACE));
sizeof (XENBUS_DEBUG_INTERFACE));
(*Frontend)->State = FRONTEND_STATE_INVALID;
+
RtlZeroMemory(&(*Frontend)->Lock, sizeof (KSPIN_LOCK));
(*Frontend)->BackendDomain = 0;
MacTeardown(__FrontendGetMac(Frontend));
Frontend->Mac = NULL;
+ Frontend->MaxQueues = 0;
+
RtlZeroMemory(&Frontend->StoreInterface,
sizeof (XENBUS_STORE_INTERFACE));
sizeof (XENBUS_DEBUG_INTERFACE));
Frontend->State = FRONTEND_STATE_INVALID;
+
RtlZeroMemory(&Frontend->Lock, sizeof (KSPIN_LOCK));
Frontend->BackendDomain = 0;
- __FrontendSetQueueCount(Frontend, 0);
__FrontendFree(Frontend->Prefix);
Frontend->Prefix = NULL;
);
extern ULONG
-FrontendGetQueueCount(
+FrontendGetMaxQueues(
+ IN PXENVIF_FRONTEND Frontend
+ );
+
+extern ULONG
+FrontendGetNumQueues(
IN PXENVIF_FRONTEND Frontend
);
PXENVIF_THREAD Thread;
NTSTATUS status;
+ Trace("====>\n");
+
Frontend = Mac->Frontend;
ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
KeReleaseSpinLockFromDpcLevel(&Mac->Lock);
+ Trace("<====\n");
return STATUS_SUCCESS;
fail1:
{
PXENVIF_FRONTEND Frontend;
+ Trace("====>\n");
+
Frontend = Mac->Frontend;
ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
Mac->Watch = NULL;
KeReleaseSpinLockFromDpcLevel(&Mac->Lock);
+
+ Trace("<====\n");
}
VOID
*/
#include <ntddk.h>
+#include <procgrp.h>
#include <ntstrsafe.h>
#include <stdlib.h>
#include <xen.h>
XENBUS_CACHE_INTERFACE CacheInterface;
XENBUS_GNTTAB_INTERFACE GnttabInterface;
XENBUS_EVTCHN_INTERFACE EvtchnInterface;
- PXENVIF_RECEIVER_RING Rings[MAXIMUM_PROCESSORS];
+ PXENVIF_RECEIVER_RING *Ring;
+ LONG MaxQueues;
+ LONG NumQueues;
BOOLEAN Split;
LONG Loaned;
LONG Returned;
Frontend = Receiver->Frontend;
if (Ring->Enabled) {
- if (Receiver->Split) {
- __ReceiverRingNotify(Ring);
- } else {
- TransmitterRingNotify(FrontendGetTransmitter(Frontend),
- Ring->Index);
- __ReceiverRingNotify(Ring);
- }
+ __ReceiverRingNotify(Ring);
+ if (!Receiver->Split)
+ TransmitterNotify(FrontendGetTransmitter(Frontend),
+ Ring->Index);
}
__ReceiverRingUnmask(Ring);
PFN_NUMBER Pfn;
CHAR Name[MAXNAMELEN];
ULONG Index;
+ PROCESSOR_NUMBER ProcNumber;
NTSTATUS status;
Receiver = Ring->Receiver;
if (Ring->Channel == NULL)
goto fail6;
- if (FrontendGetQueueCount(Frontend) > 1) {
- (VOID) XENBUS_EVTCHN(Bind,
- &Receiver->EvtchnInterface,
- Ring->Channel,
- Ring->Index);
+ status = KeGetProcessorNumberFromIndex(Ring->Index, &ProcNumber);
+ ASSERT(NT_SUCCESS(status));
- KeSetTargetProcessorDpc(&Ring->Dpc,
- (CCHAR)Ring->Index);
- }
+ KeSetTargetProcessorDpcEx(&Ring->Dpc, &ProcNumber);
+
+ (VOID) XENBUS_EVTCHN(Bind,
+ &Receiver->EvtchnInterface,
+ Ring->Channel,
+ ProcNumber.Group,
+ ProcNumber.Number);
XENBUS_EVTCHN(Unmask,
&Receiver->EvtchnInterface,
Receiver = Ring->Receiver;
Frontend = Receiver->Frontend;
- ASSERT(IMPLY(FrontendGetQueueCount(Frontend) == 1, Ring->Index == 0));
- Path = (FrontendGetQueueCount(Frontend) == 1) ?
- FrontendGetPath(Frontend) :
- Ring->Path;
+ Path = (Receiver->NumQueues == 1) ?
+ FrontendGetPath(Frontend) :
+ Ring->Path;
status = XENBUS_STORE(Printf,
&Receiver->StoreInterface,
)
{
HANDLE ParametersKey;
- ULONG Index;
- ULONG Count;
+ LONG Index;
NTSTATUS status;
- Count = DriverGetMaximumQueueCount();
*Receiver = __ReceiverAllocate(sizeof (XENVIF_RECEIVER));
status = STATUS_NO_MEMORY;
(*Receiver)->DisableIpVersion6Gso = 0;
(*Receiver)->IpAlignOffset = 0;
(*Receiver)->AlwaysPullup = 0;
- (*Receiver)->Split = FALSE;
if (ParametersKey != NULL) {
ULONG ReceiverCalculateChecksums;
if (!NT_SUCCESS(status))
goto fail2;
- ASSERT3U(Count, <=, MAXIMUM_PROCESSORS);
- for (Index = 0; Index < Count; ++Index) {
+ (*Receiver)->MaxQueues = FrontendGetMaxQueues(Frontend);
+ (*Receiver)->Ring = __ReceiverAllocate(sizeof (PXENVIF_RECEIVER_RING) *
+ (*Receiver)->MaxQueues);
+
+ status = STATUS_NO_MEMORY;
+ if ((*Receiver)->Ring == NULL)
+ goto fail3;
+
+ Index = 0;
+ while (Index < (*Receiver)->MaxQueues) {
PXENVIF_RECEIVER_RING Ring;
status = __ReceiverRingInitialize(*Receiver, Index, &Ring);
if (!NT_SUCCESS(status))
- goto fail3;
+ goto fail4;
- (*Receiver)->Rings[Index] = Ring;
+ (*Receiver)->Ring[Index] = Ring;
+ Index++;
}
return STATUS_SUCCESS;
-fail3:
- Error("fail3\n");
-
- for (Index = 0; Index < MAXIMUM_PROCESSORS; ++Index) {
- PXENVIF_RECEIVER_RING Ring;
-
- Ring = (*Receiver)->Rings[Index];
- (*Receiver)->Rings[Index] = NULL;
+fail4:
+ Error("fail4\n");
- if (Ring == NULL)
- continue; // ensure all rings are destroyed
+ while (--Index >= 0) {
+ PXENVIF_RECEIVER_RING Ring = (*Receiver)->Ring[Index];
+ (*Receiver)->Ring[Index] = NULL;
__ReceiverRingTeardown(Ring);
}
+ __ReceiverFree((*Receiver)->Ring);
+ (*Receiver)->Ring = NULL;
+
+fail3:
+ Error("fail3\n");
+
+ (*Receiver)->MaxQueues = 0;
+
XENBUS_CACHE(Release, &(*Receiver)->CacheInterface);
fail2:
(*Receiver)->DisableIpVersion6Gso = 0;
(*Receiver)->IpAlignOffset = 0;
(*Receiver)->AlwaysPullup = 0;
- (*Receiver)->Split = FALSE;
ASSERT(IsZeroMemory(*Receiver, sizeof (XENVIF_RECEIVER)));
__ReceiverFree(*Receiver);
)
{
PXENVIF_FRONTEND Frontend;
- ULONG Index;
- ULONG Count;
+ LONG Index;
PCHAR Buffer;
NTSTATUS status;
Buffer);
}
- Count = FrontendGetQueueCount(Frontend);
- ASSERT3U(Count, <=, MAXIMUM_PROCESSORS);
-
- for (Index = 0; Index < Count; ++Index) {
- PXENVIF_RECEIVER_RING Ring;
+ Receiver->NumQueues = FrontendGetNumQueues(Frontend);
+ ASSERT3U(Receiver->NumQueues, <=, Receiver->MaxQueues);
- Ring = Receiver->Rings[Index];
- if (Ring == NULL)
- break;
+ Index = 0;
+ while (Index < Receiver->NumQueues) {
+ PXENVIF_RECEIVER_RING Ring = Receiver->Ring[Index];
status = __ReceiverRingConnect(Ring);
if (!NT_SUCCESS(status))
goto fail5;
+
+ Index++;
}
status = XENBUS_DEBUG(Register,
fail6:
Error("fail6\n");
+ Index = Receiver->NumQueues;
+
fail5:
Error("fail5\n");
- for (Index = 0; Index < Count; ++Index) {
- PXENVIF_RECEIVER_RING Ring;
-
- Ring = Receiver->Rings[Index];
- if (Ring == NULL)
- break;
+ while (--Index >= 0) {
+ PXENVIF_RECEIVER_RING Ring = Receiver->Ring[Index];
__ReceiverRingDisconnect(Ring);
}
+ Receiver->NumQueues = 0;
+
XENBUS_GNTTAB(Release, &Receiver->GnttabInterface);
fail4:
)
{
PXENVIF_FRONTEND Frontend;
- ULONG Index;
- ULONG Count;
+ LONG Index;
NTSTATUS status;
Frontend = Receiver->Frontend;
if (!NT_SUCCESS(status))
goto fail5;
- Count = FrontendGetQueueCount(Frontend);
- ASSERT3U(Count, <=, MAXIMUM_PROCESSORS);
-
- for (Index = 0; Index < Count; ++Index) {
- PXENVIF_RECEIVER_RING Ring;
-
- Ring = Receiver->Rings[Index];
- if (Ring == NULL)
- break;
+ Index = 0;
+ while (Index < Receiver->NumQueues) {
+ PXENVIF_RECEIVER_RING Ring = Receiver->Ring[Index];
status = __ReceiverRingStoreWrite(Ring, Transaction);
if (!NT_SUCCESS(status))
goto fail6;
+
+ Index++;
}
return STATUS_SUCCESS;
IN PXENVIF_RECEIVER Receiver
)
{
- PXENVIF_FRONTEND Frontend;
- ULONG Index;
- ULONG Count;
+ LONG Index;
NTSTATUS status;
- Frontend = Receiver->Frontend;
-
- Count = FrontendGetQueueCount(Frontend);
- ASSERT3U(Count, <=, MAXIMUM_PROCESSORS);
-
- for (Index = 0; Index < Count; ++Index) {
- PXENVIF_RECEIVER_RING Ring;
+ Trace("====>\n");
- Ring = Receiver->Rings[Index];
- if (Ring == NULL)
- break;
+ Index = 0;
+ while (Index < Receiver->NumQueues) {
+ PXENVIF_RECEIVER_RING Ring = Receiver->Ring[Index];
status = __ReceiverRingEnable(Ring);
if (!NT_SUCCESS(status))
goto fail1;
+
+ Index++;
}
+ Trace("<====\n");
return STATUS_SUCCESS;
fail1:
Error("fail1 (%08x)\n", status);
- for (Index = 0; Index < Count; ++Index) {
+ while (--Index >= 0) {
PXENVIF_RECEIVER_RING Ring;
- Ring = Receiver->Rings[Index];
+ Ring = Receiver->Ring[Index];
if (Ring == NULL)
break;
IN PXENVIF_RECEIVER Receiver
)
{
- ULONG Index;
- ULONG Count;
+ LONG Index;
- Count = FrontendGetQueueCount(Receiver->Frontend);
- ASSERT3U(Count, <=, MAXIMUM_PROCESSORS);
-
- for (Index = 0; Index < Count; ++Index) {
- PXENVIF_RECEIVER_RING Ring;
+ Trace("====>\n");
- Ring = Receiver->Rings[Index];
- if (Ring == NULL)
- break;
+ Index = Receiver->NumQueues;
+ while (--Index >= 0) {
+ PXENVIF_RECEIVER_RING Ring = Receiver->Ring[Index];
__ReceiverRingDisable(Ring);
}
+
+ Trace("<====\n");
}
VOID
)
{
PXENVIF_FRONTEND Frontend;
- ULONG Index;
- ULONG Count;
+ LONG Index;
Frontend = Receiver->Frontend;
Receiver->DebugCallback);
Receiver->DebugCallback = NULL;
- Count = FrontendGetQueueCount(Frontend);
- ASSERT3U(Count, <=, MAXIMUM_PROCESSORS);
-
- for (Index = 0; Index < Count; ++Index) {
- PXENVIF_RECEIVER_RING Ring;
-
- Ring = Receiver->Rings[Index];
- if (Ring == NULL)
- break;
+ Index = Receiver->NumQueues;
+ while (--Index >= 0) {
+ PXENVIF_RECEIVER_RING Ring = Receiver->Ring[Index];
__ReceiverRingDisconnect(Ring);
}
+ Receiver->NumQueues = 0;
+
XENBUS_GNTTAB(Release, &Receiver->GnttabInterface);
XENBUS_EVTCHN(Release, &Receiver->EvtchnInterface);
IN PXENVIF_RECEIVER Receiver
)
{
- ULONG Index;
+ LONG Index;
ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
KeFlushQueuedDpcs();
Receiver->Loaned = 0;
Receiver->Returned = 0;
- for (Index = 0; Index < MAXIMUM_PROCESSORS; ++Index) {
- PXENVIF_RECEIVER_RING Ring;
-
- Ring = Receiver->Rings[Index];
- Receiver->Rings[Index] = NULL;
-
- if (Ring == NULL)
- continue; // ensure all rings are destroyed
+ Index = Receiver->MaxQueues;
+ while (--Index >= 0) {
+ PXENVIF_RECEIVER_RING Ring = Receiver->Ring[Index];
+ Receiver->Ring[Index] = NULL;
__ReceiverRingTeardown(Ring);
}
+ __ReceiverFree(Receiver->Ring);
+ Receiver->Ring = NULL;
+ Receiver->MaxQueues;
+
XENBUS_CACHE(Release, &Receiver->CacheInterface);
Receiver->Frontend = NULL;
- Receiver->Split = FALSE;
RtlZeroMemory(&Receiver->EvtchnInterface,
sizeof (XENBUS_EVTCHN_INTERFACE));
IN XENVIF_VIF_OFFLOAD_OPTIONS Options
)
{
- ULONG Index;
- ULONG Count;
+ LONG Index;
if (Receiver->AllowGsoPackets == 0) {
Warning("RECEIVER GSO DISALLOWED\n");
Options.OffloadIpVersion6LargePacket = 0;
}
- Count = FrontendGetQueueCount(Receiver->Frontend);
- ASSERT3U(Count, <=, MAXIMUM_PROCESSORS);
-
- for (Index = 0; Index < Count; ++Index) {
+ for (Index = 0; Index < Receiver->MaxQueues; ++Index) {
PXENVIF_RECEIVER_RING Ring;
- Ring = Receiver->Rings[Index];
+ Ring = Receiver->Ring[Index];
if (Ring == NULL)
break;
{
PXENVIF_RECEIVER_RING Ring;
- if (Index >= MAXIMUM_PROCESSORS)
- return;
-
- Ring = Receiver->Rings[Index];
- if (Ring == NULL)
- return;
+ ASSERT3U(Index, <, (ULONG)Receiver->NumQueues);
+ Ring = Receiver->Ring[Index];
__ReceiverRingSend(Ring, FALSE);
}
*/
#include <ntddk.h>
+#include <procgrp.h>
#include <ntstrsafe.h>
#include <stdlib.h>
#include <netioapi.h>
XENBUS_GNTTAB_INTERFACE GnttabInterface;
XENBUS_RANGE_SET_INTERFACE RangeSetInterface;
XENBUS_EVTCHN_INTERFACE EvtchnInterface;
- PXENVIF_TRANSMITTER_RING Rings[MAXIMUM_PROCESSORS];
+ PXENVIF_TRANSMITTER_RING *Ring;
+ LONG MaxQueues;
+ LONG NumQueues;
LONG_PTR Offset[XENVIF_TRANSMITTER_PACKET_OFFSET_COUNT];
BOOLEAN Split;
ULONG DisableIpVersion4Gso;
PFN_NUMBER Pfn;
CHAR Name[MAXNAMELEN];
ULONG Index;
+ PROCESSOR_NUMBER ProcNumber;
NTSTATUS status;
ASSERT(!Ring->Connected);
if (Ring->Channel == NULL)
goto fail6;
- if (FrontendGetQueueCount(Frontend) > 1) {
- (VOID) XENBUS_EVTCHN(Bind,
- &Transmitter->EvtchnInterface,
- Ring->Channel,
- Ring->Index);
+ status = KeGetProcessorNumberFromIndex(Ring->Index, &ProcNumber);
+ ASSERT(NT_SUCCESS(status));
- KeSetTargetProcessorDpc(&Ring->Dpc,
- (CCHAR)Ring->Index);
- }
+ KeSetTargetProcessorDpcEx(&Ring->Dpc, &ProcNumber);
+
+ (VOID) XENBUS_EVTCHN(Bind,
+ &Transmitter->EvtchnInterface,
+ Ring->Channel,
+ ProcNumber.Group,
+ ProcNumber.Number);
XENBUS_EVTCHN(Unmask,
&Transmitter->EvtchnInterface,
Transmitter = Ring->Transmitter;
Frontend = Transmitter->Frontend;
- ASSERT(IMPLY(FrontendGetQueueCount(Frontend) == 1, Ring->Index == 0));
- Path = (FrontendGetQueueCount(Frontend) == 1) ?
- FrontendGetPath(Frontend) :
- Ring->Path;
+ Path = (Transmitter->NumQueues == 1) ?
+ FrontendGetPath(Frontend) :
+ Ring->Path;
status = XENBUS_STORE(Printf,
&Transmitter->StoreInterface,
Packet = __TransmitterRingUnpreparePacket(Ring);
// Put any packet back on the head of the queue
- if (Packet != NULL) {
+ if (Packet != NULL)
InsertHeadList(&Ring->Queued, &Packet->ListEntry);
- }
Ring->AddressIndex = 0;
)
{
HANDLE ParametersKey;
- ULONG Index;
- ULONG Count;
+ LONG Index;
NTSTATUS status;
- Count = DriverGetMaximumQueueCount();
*Transmitter = __TransmitterAllocate(sizeof (XENVIF_TRANSMITTER));
status = STATUS_NO_MEMORY;
(*Transmitter)->DisableIpVersion4Gso = 0;
(*Transmitter)->DisableIpVersion6Gso = 0;
(*Transmitter)->AlwaysCopy = 0;
- (*Transmitter)->Split = FALSE;
if (ParametersKey != NULL) {
ULONG TransmitterDisableIpVersion4Gso;
if (!NT_SUCCESS(status))
goto fail3;
- ASSERT3U(Count, <=, MAXIMUM_PROCESSORS);
- for (Index = 0; Index < Count; ++Index) {
+ (*Transmitter)->MaxQueues = FrontendGetMaxQueues(Frontend);
+ (*Transmitter)->Ring = __TransmitterAllocate(sizeof (PXENVIF_TRANSMITTER_RING) *
+ (*Transmitter)->MaxQueues);
+
+ status = STATUS_NO_MEMORY;
+ if ((*Transmitter)->Ring == NULL)
+ goto fail4;
+
+ Index = 0;
+ while (Index < (*Transmitter)->MaxQueues) {
PXENVIF_TRANSMITTER_RING Ring;
status = __TransmitterRingInitialize(*Transmitter, Index, &Ring);
if (!NT_SUCCESS(status))
- goto fail4;
+ goto fail5;
- (*Transmitter)->Rings[Index] = Ring;
+ (*Transmitter)->Ring[Index] = Ring;
+ Index++;
}
return STATUS_SUCCESS;
-fail4:
- Error("fail4\n");
-
- for (Index = 0; Index < MAXIMUM_PROCESSORS; ++Index) {
- PXENVIF_TRANSMITTER_RING Ring;
-
- Ring = (*Transmitter)->Rings[Index];
- (*Transmitter)->Rings[Index] = NULL;
+fail5:
+ Error("fail5\n");
- if (Ring == NULL)
- continue; // ensure all rings are destroyed
+ while (--Index > 0) {
+ PXENVIF_TRANSMITTER_RING Ring = (*Transmitter)->Ring[Index];
+ (*Transmitter)->Ring[Index] = NULL;
__TransmitterRingTeardown(Ring);
}
+ __TransmitterFree((*Transmitter)->Ring);
+ (*Transmitter)->Ring = NULL;
+
+fail4:
+ Error("fail4\n");
+
+ (*Transmitter)->MaxQueues = 0;
+
XENBUS_CACHE(Release, &(*Transmitter)->CacheInterface);
fail3:
PXENVIF_FRONTEND Frontend;
CHAR Name[MAXNAMELEN];
PCHAR Buffer;
- ULONG Index;
- ULONG Count;
+ LONG Index;
NTSTATUS status;
Frontend = Transmitter->Frontend;
Buffer);
}
- Count = FrontendGetQueueCount(Frontend);
- ASSERT3U(Count, <=, MAXIMUM_PROCESSORS);
+ Transmitter->NumQueues = FrontendGetNumQueues(Frontend);
+ ASSERT3U(Transmitter->NumQueues, <=, Transmitter->MaxQueues);
- for (Index = 0; Index < Count; ++Index) {
- PXENVIF_TRANSMITTER_RING Ring;
-
- Ring = Transmitter->Rings[Index];
- if (Ring == NULL)
- break;
+ Index = 0;
+ while (Index < Transmitter->NumQueues) {
+ PXENVIF_TRANSMITTER_RING Ring = Transmitter->Ring[Index];
status = __TransmitterRingConnect(Ring);
if (!NT_SUCCESS(status))
goto fail7;
+
+ Index++;
}
status = XENBUS_DEBUG(Register,
fail8:
Error("fail8\n");
+ Index = Transmitter->NumQueues;
+
fail7:
Error("fail7\n");
- for (Index = 0; Index < MAXIMUM_PROCESSORS; ++Index) {
+ while (--Index >= 0) {
PXENVIF_TRANSMITTER_RING Ring;
- Ring = Transmitter->Rings[Index];
- if (Ring == NULL)
- continue; // ensure all rings are destroyed
+ Ring = Transmitter->Ring[Index];
__TransmitterRingDisconnect(Ring);
}
+ Transmitter->NumQueues = 0;
+
XENBUS_CACHE(Destroy,
&Transmitter->CacheInterface,
Transmitter->PacketCache);
)
{
NTSTATUS status;
- ULONG Index;
- ULONG Count;
-
- Count = FrontendGetQueueCount(Transmitter->Frontend);
- ASSERT3U(Count, <=, MAXIMUM_PROCESSORS);
-
- for (Index = 0; Index < Count; ++Index) {
- PXENVIF_TRANSMITTER_RING Ring;
+ LONG Index;
- Ring = Transmitter->Rings[Index];
- if (Ring == NULL)
- break;
+ Index = 0;
+ while (Index < Transmitter->NumQueues) {
+ PXENVIF_TRANSMITTER_RING Ring = Transmitter->Ring[Index];
status = __TransmitterRingStoreWrite(Ring, Transaction);
if (!NT_SUCCESS(status))
goto fail1;
+
+ Index++;
}
return STATUS_SUCCESS;
IN PXENVIF_TRANSMITTER Transmitter
)
{
- ULONG Index;
- ULONG Count;
+ LONG Index;
- Count = FrontendGetQueueCount(Transmitter->Frontend);
- ASSERT3U(Count, <=, MAXIMUM_PROCESSORS);
+ Trace("====>\n");
- for (Index = 0; Index < Count; ++Index) {
- PXENVIF_TRANSMITTER_RING Ring;
-
- Ring = Transmitter->Rings[Index];
- if (Ring == NULL)
- break;
+ Index = 0;
+ while (Index < Transmitter->NumQueues) {
+ PXENVIF_TRANSMITTER_RING Ring = Transmitter->Ring[Index];
__TransmitterRingEnable(Ring);
+ Index++;
}
+ Trace("<====\n");
return STATUS_SUCCESS;
}
IN PXENVIF_TRANSMITTER Transmitter
)
{
- ULONG Index;
- ULONG Count;
+ LONG Index;
- Count = FrontendGetQueueCount(Transmitter->Frontend);
- ASSERT3U(Count, <=, MAXIMUM_PROCESSORS);
-
- for (Index = 0; Index < Count; ++Index) {
- PXENVIF_TRANSMITTER_RING Ring;
+ Trace("====>\n");
- Ring = Transmitter->Rings[Index];
- if (Ring == NULL)
- break;
+ Index = Transmitter->NumQueues;
+ while (--Index >= 0) {
+ PXENVIF_TRANSMITTER_RING Ring = Transmitter->Ring[Index];
__TransmitterRingDisable(Ring);
}
+
+ Trace("<====\n");
}
VOID
{
PXENVIF_FRONTEND Frontend;
ULONG Index;
- ULONG Count;
Frontend = Transmitter->Frontend;
Transmitter->DebugCallback);
Transmitter->DebugCallback = NULL;
- Count = FrontendGetQueueCount(Frontend);
- ASSERT3U(Count, <=, MAXIMUM_PROCESSORS);
-
- for (Index = 0; Index < Count; ++Index) {
- PXENVIF_TRANSMITTER_RING Ring;
-
- Ring = Transmitter->Rings[Index];
- if (Ring == NULL)
- break;
+ Index = Transmitter->NumQueues;
+ while (--Index >- 0) {
+ PXENVIF_TRANSMITTER_RING Ring = Transmitter->Ring[Index];
__TransmitterRingDisconnect(Ring);
}
+ Transmitter->NumQueues = 0;
+
XENBUS_CACHE(Destroy,
&Transmitter->CacheInterface,
Transmitter->PacketCache);
RtlZeroMemory(Transmitter->Offset,
sizeof (LONG_PTR) * XENVIF_TRANSMITTER_PACKET_OFFSET_COUNT);
- for (Index = 0; Index < MAXIMUM_PROCESSORS; ++Index) {
- PXENVIF_TRANSMITTER_RING Ring;
-
- Ring = Transmitter->Rings[Index];
- Transmitter->Rings[Index] = NULL;
-
- if (Ring == NULL)
- continue; // ensure all rings are destroyed
+ Index = Transmitter->MaxQueues;
+ while (--Index >- 0) {
+ PXENVIF_TRANSMITTER_RING Ring = Transmitter->Ring[Index];
+ Transmitter->Ring[Index] = NULL;
__TransmitterRingTeardown(Ring);
}
+ __TransmitterFree(Transmitter->Ring);
+ Transmitter->Ring = NULL;
+ Transmitter->MaxQueues;
+
XENBUS_CACHE(Release, &Transmitter->CacheInterface);
XENBUS_RANGE_SET(Release, &Transmitter->RangeSetInterface);
Transmitter->Frontend = NULL;
- Transmitter->Split = FALSE;
RtlZeroMemory(&Transmitter->Lock,
sizeof (KSPIN_LOCK));
KeRaiseIrql(DISPATCH_LEVEL, &Irql);
// Use the first ring for address advertisment
- Ring = Transmitter->Rings[0];
+ Ring = Transmitter->Ring[0];
ASSERT3U(Ring, !=, NULL);
__TransmitterRingUpdateAddressTable(Ring, Table, Count);
PXENVIF_TRANSMITTER_RING Ring;
// Use the first ring for address advertisment
- Ring = Transmitter->Rings[0];
+ Ring = Transmitter->Ring[0];
ASSERT3U(Ring, !=, NULL);
__TransmitterRingAdvertiseAddresses(Ring);
#undef OFFSET_EXISTS
}
-static FORCEINLINE ULONG
-__GetQueue(
- IN ULONG QueueCount,
- IN ULONG HashValue
- )
-{
- return HashValue % QueueCount;
-}
-
VOID
TransmitterQueuePackets(
- IN PXENVIF_TRANSMITTER Transmitter,
- IN PLIST_ENTRY List
+ IN PXENVIF_TRANSMITTER Transmitter,
+ IN PLIST_ENTRY List
)
{
PXENVIF_TRANSMITTER_RING Ring;
PXENVIF_FRONTEND Frontend;
- ULONG QueueCount;
Frontend = Transmitter->Frontend;
- QueueCount = FrontendGetQueueCount(Frontend);
-
- if (QueueCount == 1) {
- Ring = Transmitter->Rings[0];
- ASSERT3P(Ring, !=, NULL);
+ if (Transmitter->NumQueues == 1) {
+ Ring = Transmitter->Ring[0];
__TransmitterRingQueuePackets(Ring, List);
} else {
while (!IsListEmpty(List)) {
PXENVIF_TRANSMITTER_PACKET Packet;
- PLIST_ENTRY ListEntry;
- LIST_ENTRY ListHead;
- ULONG Queue;
+ LIST_ENTRY HashList;
+ ULONG Index;
- InitializeListHead(&ListHead);
+ InitializeListHead(&HashList);
+ Index = 0;
- ListEntry = List->Flink;
- Packet = CONTAINING_RECORD(ListEntry, XENVIF_TRANSMITTER_PACKET, ListEntry);
- Queue = __GetQueue(QueueCount, Packet->Value);
+ while (!IsListEmpty(List)) {
+ PLIST_ENTRY ListEntry;
+ ULONG Hash;
- (VOID) RemoveHeadList(List);
- InsertTailList(&ListHead, ListEntry);
+ ListEntry = RemoveHeadList(List);
+ ASSERT3P(ListEntry, !=, List);
+
+ RtlZeroMemory(ListEntry, sizeof (LIST_ENTRY));
- while (!IsListEmpty(List)) {
- ListEntry = List->Flink;
Packet = CONTAINING_RECORD(ListEntry, XENVIF_TRANSMITTER_PACKET, ListEntry);
- if (Queue != __GetQueue(QueueCount, Packet->Value))
- break;
- (VOID) RemoveHeadList(List);
- InsertTailList(&ListHead, ListEntry);
+ Hash = Packet->Value % Transmitter->NumQueues;
+ if (Hash != Index) {
+ if (!IsListEmpty(&HashList)) {
+ Ring = Transmitter->Ring[Index];
+ ASSERT3P(Ring, !=, NULL);
+
+ __TransmitterRingQueuePackets(Ring, &HashList);
+ InitializeListHead(&HashList);
+ }
+
+ Index = Hash;
+ }
+
+ InsertTailList(&HashList, ListEntry);
}
- Ring = Transmitter->Rings[Queue];
- ASSERT3P(Ring, !=, NULL);
+ if (!IsListEmpty(&HashList)) {
+ Ring = Transmitter->Ring[Index];
+ ASSERT3P(Ring, !=, NULL);
+
+ __TransmitterRingQueuePackets(Ring, &HashList);
+ InitializeListHead(&HashList);
+ }
- __TransmitterRingQueuePackets(Ring, &ListHead);
+ ASSERT(IsListEmpty(&HashList));
}
}
}
IN PXENVIF_TRANSMITTER Transmitter
)
{
- ULONG Index;
- ULONG Count;
KIRQL Irql;
+ LONG Index;
KeRaiseIrql(DISPATCH_LEVEL, &Irql);
- Count = FrontendGetQueueCount(Transmitter->Frontend);
- ASSERT3U(Count, <=, MAXIMUM_PROCESSORS);
-
- for (Index = 0; Index < Count; ++Index) {
- PXENVIF_TRANSMITTER_RING Ring;
-
- Ring = Transmitter->Rings[Index];
- if (Ring == NULL)
- break;
+ Index = Transmitter->NumQueues;
+ while (--Index >= 0) {
+ PXENVIF_TRANSMITTER_RING Ring = Transmitter->Ring[Index];
__TransmitterRingAbortPackets(Ring);
}
}
VOID
-TransmitterRingNotify(
- IN PXENVIF_TRANSMITTER Transmitter,
- IN ULONG Index
+TransmitterNotify(
+ IN PXENVIF_TRANSMITTER Transmitter,
+ IN ULONG Index
)
{
PXENVIF_TRANSMITTER_RING Ring;
- if (Index >= MAXIMUM_PROCESSORS)
- return;
-
- Ring = Transmitter->Rings[Index];
- if (Ring == NULL)
- return;
+ ASSERT3U(Index, <, (ULONG)Transmitter->NumQueues);
+ Ring = Transmitter->Ring[Index];
__TransmitterRingNotify(Ring);
}
);
extern VOID
-TransmitterRingNotify(
+TransmitterNotify(
IN PXENVIF_TRANSMITTER Transmitter,
IN ULONG Index
);
<Inputs>..\..\src\xenvif.inf;..\..\include\version.hx</Inputs>
</CustomBuildStep>
<ClCompile>
- <PreprocessorDefinitions>__MODULE__="XENVIF";POOL_NX_OPTIN=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>__MODULE__="XENVIF";POOL_NX_OPTIN=1;NT_PROCESSOR_GROUPS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>EnableAllWarnings</WarningLevel>
<DisableSpecificWarnings>4711;4548;4820;4668;4255;6001;6054;28196;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
- <AdditionalDependencies>$(DDK_LIB_PATH)/libcntpr.lib;$(DDK_LIB_PATH)/aux_klib.lib;$(DDK_LIB_PATH)/ksecdd.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>$(DDK_LIB_PATH)/libcntpr.lib;$(DDK_LIB_PATH)/aux_klib.lib;$(DDK_LIB_PATH)/ksecdd.lib;$(DDK_LIB_PATH)/procgrp.lib;%(AdditionalDependencies)</AdditionalDependencies>
<EnableCOMDATFolding>false</EnableCOMDATFolding>
</Link>
<Inf>
</CustomBuildStep>
<ClCompile>
<AdditionalIncludeDirectories>$(WindowsSdkDir)\include\km;..\..\include;..\..\include\xen;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>__MODULE__="XENVIF";POOL_NX_OPTIN=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>__MODULE__="XENVIF";POOL_NX_OPTIN=1;NT_PROCESSOR_GROUPS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>EnableAllWarnings</WarningLevel>
<DisableSpecificWarnings>4711;4548;4820;4668;4255;6001;6054;28196;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ResourceCompile>
<Link>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
- <AdditionalDependencies>$(DDK_LIB_PATH)/libcntpr.lib;$(DDK_LIB_PATH)/aux_klib.lib;$(DDK_LIB_PATH)/ksecdd.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>$(DDK_LIB_PATH)/libcntpr.lib;$(DDK_LIB_PATH)/aux_klib.lib;$(DDK_LIB_PATH)/ksecdd.lib;$(DDK_LIB_PATH)/procgrp.lib;%(AdditionalDependencies)</AdditionalDependencies>
<EnableCOMDATFolding>false</EnableCOMDATFolding>
</Link>
<Inf>