]> xenbits.xensource.com Git - people/pauldu/xenvif.git/commitdiff
Make XENVIF processor group aware
authorPaul Durrant <paul.durrant@citrix.com>
Fri, 20 Mar 2015 12:01:47 +0000 (12:01 +0000)
committerPaul Durrant <paul.durrant@citrix.com>
Fri, 20 Mar 2015 12:52:54 +0000 (12:52 +0000)
Processor groups have been around for a long time in Windows and
contnuing to ignore them becomes ever more painful when trying to
pass the HCK multiple processor group device test. This patch, therefore,
modifies all the code that uses the non-group-aware kernel calls to use
the newer group aware calls.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
12 files changed:
include/emulated_interface.h
include/evtchn_interface.h
src/xenvif/driver.c
src/xenvif/driver.h
src/xenvif/frontend.c
src/xenvif/frontend.h
src/xenvif/mac.c
src/xenvif/receiver.c
src/xenvif/transmitter.c
src/xenvif/transmitter.h
vs2012/xenvif/xenvif.vcxproj
vs2013/xenvif/xenvif.vcxproj

index 85ed2b8b5cf775ef5bce4d2656e143370a1f2028..9361f8d470ff8854610cdfc6d5fd7c5ae74a5ee4 100644 (file)
@@ -66,7 +66,8 @@ typedef VOID
 
     \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
 */  
@@ -74,7 +75,7 @@ typedef BOOLEAN
 (*XENFILT_EMULATED_IS_DEVICE_PRESENT)(
     IN  PVOID   Context,
     IN  PCHAR   DeviceID,
-    IN  PCHAR   InstanceID
+    IN  PCHAR   InstanceID OPTIONAL
     );
 
 /*! \typedef XENFILT_EMULATED_IS_DISK_PRESENT
index 1bc456a7d82bf5655c985ee261b66ca8832b1843..6f8fe421e4836df1ccb7106555b537251a97fe0c 100644 (file)
@@ -112,18 +112,27 @@ typedef PXENBUS_EVTCHN_CHANNEL
     ...
     );
 
+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
@@ -225,7 +234,7 @@ struct _XENBUS_EVTCHN_INTERFACE_V2 {
     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;
@@ -238,6 +247,23 @@ struct _XENBUS_EVTCHN_INTERFACE_V2 {
     \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;
@@ -250,7 +276,7 @@ struct _XENBUS_EVTCHN_INTERFACE_V3 {
     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
@@ -261,7 +287,7 @@ typedef struct _XENBUS_EVTCHN_INTERFACE_V3 XENBUS_EVTCHN_INTERFACE, *PXENBUS_EVT
 #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
 
index 589bee90efdf5e3bcb0c432344df62a2e6dd7942..8cf843f8c83579262cb1d1fd1acec4276ee995f0 100644 (file)
@@ -30,6 +30,7 @@
  */
 
 #include <ntddk.h>
+#include <procgrp.h>
 #include <version.h>
 
 #include "registry.h"
@@ -47,7 +48,6 @@ typedef struct _XENVIF_DRIVER {
     PDRIVER_OBJECT      DriverObject;
     HANDLE              ParametersKey;
     HANDLE              AddressesKey;
-    ULONG               MaximumQueues;
 } XENVIF_DRIVER, *PXENVIF_DRIVER;
 
 static XENVIF_DRIVER    Driver;
@@ -124,30 +124,6 @@ DriverGetAddressesKey(
     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
@@ -173,8 +149,6 @@ DriverUnload(
     ParametersKey = __DriverGetParametersKey();
     __DriverSetParametersKey(NULL);
 
-    __DriverSetMaximumQueueCount(0);
-
     RegistryCloseKey(ParametersKey);
 
     RegistryTeardown();
@@ -281,13 +255,12 @@ DriverEntry(
     HANDLE              ParametersKey;
     HANDLE              AddressesKey;
     ULONG               Index;
-    ULONG               MaxQueues;
-    ULONG               Processors;
     NTSTATUS            status;
 
     ASSERT3P(__DriverGetDriverObject(), ==, NULL);
 
     ExInitializeDriverRuntime(DrvRtPoolNxOptIn);
+    WdmlibProcgrpInitialize();
 
     __DbgPrintEnable();
 
@@ -335,17 +308,6 @@ DriverEntry(
 
     __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;
index bbea23b4524e87cbd3b050dd38b9b967e9d5a4f9..cdef7d1ae07f993e5b41bf2aad946a7217484b7f 100644 (file)
@@ -52,11 +52,6 @@ DriverGetAliasesKey(
     VOID
     );
 
-extern ULONG
-DriverGetMaximumQueueCount(
-    VOID
-    );
-
 typedef struct _XENVIF_PDO  XENVIF_PDO, *PXENVIF_PDO;
 typedef struct _XENVIF_FDO  XENVIF_FDO, *PXENVIF_FDO;
 
index 12b97899cb4bc843f03e2ec25a1b05d68e3d344a..3c03e50763af284afb50339a37a4055fc9712567 100644 (file)
@@ -30,6 +30,7 @@
  */
 
 #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;
@@ -62,7 +67,8 @@ struct _XENVIF_FRONTEND {
 
     PCHAR                       BackendPath;
     USHORT                      BackendDomain;
-    ULONG                       QueueCount;
+    ULONG                       MaxQueues;
+    ULONG                       NumQueues;
 
     PXENVIF_MAC                 Mac;
     PXENVIF_RECEIVER            Receiver;
@@ -76,7 +82,8 @@ struct _XENVIF_FRONTEND {
     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
@@ -201,28 +208,41 @@ FrontendGetBackendDomain(
 }
 
 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
@@ -1233,56 +1253,65 @@ fail1:
 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);
@@ -1317,7 +1346,7 @@ FrontendDebugCallback(
     )
 {
     PXENVIF_FRONTEND        Frontend = Argument;
-    XENVIF_VIF_STATISTIC    Index;
+    XENVIF_VIF_STATISTIC    Name;
 
     UNREFERENCED_PARAMETER(Crashing);
 
@@ -1330,33 +1359,28 @@ FrontendDebugCallback(
                  &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,
@@ -1364,19 +1388,34 @@ __FrontendReadQueueCount(
                           "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
@@ -1391,9 +1430,16 @@ __FrontendConnect(
 
     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,
@@ -1402,20 +1448,21 @@ __FrontendConnect(
                           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 {
@@ -1443,7 +1490,7 @@ __FrontendConnect(
                               __FrontendGetPath(Frontend),
                               "multi-queue-num-queues",
                               "%u",
-                              __FrontendGetQueueCount(Frontend));
+                              __FrontendGetNumQueues(Frontend));
         if (!NT_SUCCESS(status))
             goto abort;
 
@@ -1465,7 +1512,7 @@ abort:
     } while (status == STATUS_RETRY);
 
     if (!NT_SUCCESS(status))
-        goto fail6;
+        goto fail7;
 
     status = XENBUS_STORE(Printf,
                           &Frontend->StoreInterface,
@@ -1475,22 +1522,25 @@ abort:
                           "%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");
 
@@ -1500,33 +1550,38 @@ fail8:
 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);
@@ -1546,6 +1601,8 @@ __FrontendDisconnect(
     ReceiverDisconnect(__FrontendGetReceiver(Frontend));
     MacDisconnect(__FrontendGetMac(Frontend));
 
+    Frontend->NumQueues = 0;
+
     XENBUS_DEBUG(Deregister,
                  &Frontend->DebugInterface,
                  Frontend->DebugCallback);
@@ -1553,7 +1610,8 @@ __FrontendDisconnect(
 
     XENBUS_DEBUG(Release, &Frontend->DebugInterface);
 
-    RtlZeroMemory(&Frontend->Statistic, sizeof (Frontend->Statistic));
+    __FrontendFree(Frontend->Statistics);
+    Frontend->StatisticsCount = 0;
 
     Trace("<====\n");
 }
@@ -1958,6 +2016,8 @@ FrontendInitialize(
     FdoGetSuspendInterface(PdoGetFdo(Pdo), &(*Frontend)->SuspendInterface);
     FdoGetStoreInterface(PdoGetFdo(Pdo), &(*Frontend)->StoreInterface);
 
+    __FrontendSetMaxQueues(*Frontend);
+
     status = MacInitialize(*Frontend, &(*Frontend)->Mac);
     if (!NT_SUCCESS(status))
         goto fail6;
@@ -2010,6 +2070,8 @@ fail7:
 fail6:
     Error("fail6\n");
 
+    (*Frontend)->MaxQueues = 0;
+
     RtlZeroMemory(&(*Frontend)->StoreInterface,
                   sizeof (XENBUS_STORE_INTERFACE));
 
@@ -2020,6 +2082,7 @@ fail6:
                   sizeof (XENBUS_DEBUG_INTERFACE));
 
     (*Frontend)->State = FRONTEND_STATE_INVALID;
+
     RtlZeroMemory(&(*Frontend)->Lock, sizeof (KSPIN_LOCK));
 
     (*Frontend)->BackendDomain = 0;
@@ -2091,6 +2154,8 @@ FrontendTeardown(
     MacTeardown(__FrontendGetMac(Frontend));
     Frontend->Mac = NULL;
 
+    Frontend->MaxQueues = 0;
+
     RtlZeroMemory(&Frontend->StoreInterface,
                   sizeof (XENBUS_STORE_INTERFACE));
 
@@ -2101,10 +2166,10 @@ FrontendTeardown(
                   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;
index adcf53c84a10d73e9e8c805e0ee608137a028dfc..1673facd9cd8c29265dcee20252bd5df86017926 100644 (file)
@@ -113,7 +113,12 @@ FrontendGetBackendDomain(
     );
 
 extern ULONG
-FrontendGetQueueCount(
+FrontendGetMaxQueues(
+    IN  PXENVIF_FRONTEND    Frontend
+    );
+
+extern ULONG
+FrontendGetNumQueues(
     IN  PXENVIF_FRONTEND    Frontend
     );
 
index 1d60a1f3c07193a070f140f6fb8f43770ec208a1..b255d583bf3c16cc89b628af1d1320aa19c1bdf4 100644 (file)
@@ -349,6 +349,8 @@ MacEnable(
     PXENVIF_THREAD      Thread;
     NTSTATUS            status;
 
+    Trace("====>\n");
+
     Frontend = Mac->Frontend;
 
     ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
@@ -370,6 +372,7 @@ MacEnable(
 
     KeReleaseSpinLockFromDpcLevel(&Mac->Lock);
 
+    Trace("<====\n");
     return STATUS_SUCCESS;
 
 fail1:
@@ -387,6 +390,8 @@ MacDisable(
 {
     PXENVIF_FRONTEND    Frontend;
 
+    Trace("====>\n");
+
     Frontend = Mac->Frontend;
 
     ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
@@ -401,6 +406,8 @@ MacDisable(
     Mac->Watch = NULL;
 
     KeReleaseSpinLockFromDpcLevel(&Mac->Lock);
+
+    Trace("<====\n");
 }
 
 VOID
index 6f45627beb194d87b96d1878c3f48562e1c8cbb9..f09b71c30776b95171c2e0cf645612b87e245a43 100644 (file)
@@ -30,6 +30,7 @@
  */
 
 #include <ntddk.h>
+#include <procgrp.h>
 #include <ntstrsafe.h>
 #include <stdlib.h>
 #include <xen.h>
@@ -108,7 +109,9 @@ struct _XENVIF_RECEIVER {
     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;
@@ -1914,13 +1917,10 @@ ReceiverRingDpc(
     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);
@@ -2175,6 +2175,7 @@ __ReceiverRingConnect(
     PFN_NUMBER                  Pfn;
     CHAR                        Name[MAXNAMELEN];
     ULONG                       Index;
+    PROCESSOR_NUMBER            ProcNumber;
     NTSTATUS                    status;
 
     Receiver = Ring->Receiver;
@@ -2249,15 +2250,16 @@ __ReceiverRingConnect(
     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,
@@ -2344,10 +2346,9 @@ __ReceiverRingStoreWrite(
     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,
@@ -2581,11 +2582,9 @@ ReceiverInitialize(
     )
 {
     HANDLE                  ParametersKey;
-    ULONG                   Index;
-    ULONG                   Count;
+    LONG                    Index;
     NTSTATUS                status;
 
-    Count = DriverGetMaximumQueueCount();
     *Receiver = __ReceiverAllocate(sizeof (XENVIF_RECEIVER));
 
     status = STATUS_NO_MEMORY;
@@ -2600,7 +2599,6 @@ ReceiverInitialize(
     (*Receiver)->DisableIpVersion6Gso = 0;
     (*Receiver)->IpAlignOffset = 0;
     (*Receiver)->AlwaysPullup = 0;
-    (*Receiver)->Split = FALSE;
 
     if (ParametersKey != NULL) {
         ULONG   ReceiverCalculateChecksums;
@@ -2670,34 +2668,46 @@ ReceiverInitialize(
     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:
@@ -2728,7 +2738,6 @@ fail2:
     (*Receiver)->DisableIpVersion6Gso = 0;
     (*Receiver)->IpAlignOffset = 0;
     (*Receiver)->AlwaysPullup = 0;
-    (*Receiver)->Split = FALSE;
 
     ASSERT(IsZeroMemory(*Receiver, sizeof (XENVIF_RECEIVER)));
     __ReceiverFree(*Receiver);
@@ -2745,8 +2754,7 @@ ReceiverConnect(
     )
 {
     PXENVIF_FRONTEND        Frontend;
-    ULONG                   Index;
-    ULONG                   Count;
+    LONG                    Index;
     PCHAR                   Buffer;
     NTSTATUS                status;
 
@@ -2784,19 +2792,18 @@ ReceiverConnect(
                      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,
@@ -2813,19 +2820,19 @@ ReceiverConnect(
 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:
@@ -2940,8 +2947,7 @@ ReceiverStoreWrite(
     )
 {
     PXENVIF_FRONTEND                Frontend;
-    ULONG                           Index;
-    ULONG                           Count;
+    LONG                            Index;
     NTSTATUS                        status;
 
     Frontend = Receiver->Frontend;
@@ -2984,19 +2990,15 @@ ReceiverStoreWrite(
     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;
@@ -3027,37 +3029,32 @@ ReceiverEnable(
     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;
 
@@ -3072,21 +3069,18 @@ ReceiverDisable(
     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
@@ -3095,8 +3089,7 @@ ReceiverDisconnect(
     )
 {
     PXENVIF_FRONTEND        Frontend;
-    ULONG                   Index;
-    ULONG                   Count;
+    LONG                    Index;
 
     Frontend = Receiver->Frontend;
 
@@ -3107,19 +3100,15 @@ ReceiverDisconnect(
                  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);
@@ -3134,7 +3123,7 @@ ReceiverTeardown(
     IN  PXENVIF_RECEIVER    Receiver
     )
 {
-    ULONG                   Index;
+    LONG                    Index;
 
     ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
     KeFlushQueuedDpcs();
@@ -3143,22 +3132,21 @@ ReceiverTeardown(
     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));
@@ -3194,8 +3182,7 @@ ReceiverSetOffloadOptions(
     IN  XENVIF_VIF_OFFLOAD_OPTIONS  Options
     )
 {
-    ULONG                           Index;
-    ULONG                           Count;
+    LONG                            Index;
 
     if (Receiver->AllowGsoPackets == 0) {
         Warning("RECEIVER GSO DISALLOWED\n");
@@ -3203,13 +3190,10 @@ ReceiverSetOffloadOptions(
         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;
 
@@ -3304,12 +3288,8 @@ ReceiverSend(
 {
     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);
 }
index 9f81ca12a16096176de847afd5d2745d67cb23ba..d6357f1661b11e12f0dee168e79c3d52df4a1988 100644 (file)
@@ -30,6 +30,7 @@
  */
 
 #include <ntddk.h>
+#include <procgrp.h>
 #include <ntstrsafe.h>
 #include <stdlib.h>
 #include <netioapi.h>
@@ -149,7 +150,9 @@ struct _XENVIF_TRANSMITTER {
     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;
@@ -3030,6 +3033,7 @@ __TransmitterRingConnect(
     PFN_NUMBER                      Pfn;
     CHAR                            Name[MAXNAMELEN];
     ULONG                           Index;
+    PROCESSOR_NUMBER                ProcNumber;
     NTSTATUS                        status;
 
     ASSERT(!Ring->Connected);
@@ -3107,15 +3111,16 @@ __TransmitterRingConnect(
         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,
@@ -3201,10 +3206,9 @@ __TransmitterRingStoreWrite(
     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,
@@ -3290,9 +3294,8 @@ __TransmitterRingDisable(
     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;
 
@@ -3559,11 +3562,9 @@ TransmitterInitialize(
     )
 {
     HANDLE                  ParametersKey;
-    ULONG                   Index;
-    ULONG                   Count;
+    LONG                    Index;
     NTSTATUS                status;
 
-    Count = DriverGetMaximumQueueCount();
     *Transmitter = __TransmitterAllocate(sizeof (XENVIF_TRANSMITTER));
 
     status = STATUS_NO_MEMORY;
@@ -3575,7 +3576,6 @@ TransmitterInitialize(
     (*Transmitter)->DisableIpVersion4Gso = 0;
     (*Transmitter)->DisableIpVersion6Gso = 0;
     (*Transmitter)->AlwaysCopy = 0;
-    (*Transmitter)->Split = FALSE;
 
     if (ParametersKey != NULL) {
         ULONG   TransmitterDisableIpVersion4Gso;
@@ -3630,34 +3630,46 @@ TransmitterInitialize(
     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:
@@ -3709,8 +3721,7 @@ TransmitterConnect(
     PXENVIF_FRONTEND            Frontend;
     CHAR                        Name[MAXNAMELEN];
     PCHAR                       Buffer;
-    ULONG                       Index;
-    ULONG                       Count;
+    LONG                        Index;
     NTSTATUS                    status;
 
     Frontend = Transmitter->Frontend;
@@ -3772,19 +3783,18 @@ TransmitterConnect(
                      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,
@@ -3801,19 +3811,21 @@ TransmitterConnect(
 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);
@@ -3855,22 +3867,17 @@ TransmitterStoreWrite(
     )
 {
     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;
@@ -3886,22 +3893,19 @@ TransmitterEnable(
     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;
 }
 
@@ -3910,21 +3914,18 @@ TransmitterDisable(
     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
@@ -3934,7 +3935,6 @@ TransmitterDisconnect(
 {
     PXENVIF_FRONTEND        Frontend;
     ULONG                   Index;
-    ULONG                   Count;
 
     Frontend = Transmitter->Frontend;
 
@@ -3945,19 +3945,15 @@ TransmitterDisconnect(
                  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);
@@ -3985,24 +3981,23 @@ TransmitterTeardown(
     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));
@@ -4047,7 +4042,7 @@ TransmitterUpdateAddressTable(
     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);
@@ -4063,7 +4058,7 @@ TransmitterAdvertiseAddresses(
     PXENVIF_TRANSMITTER_RING    Ring;
 
     // Use the first ring for address advertisment
-    Ring = Transmitter->Rings[0];
+    Ring = Transmitter->Ring[0];
     ASSERT3U(Ring, !=, NULL);
 
     __TransmitterRingAdvertiseAddresses(Ring);
@@ -4248,64 +4243,66 @@ TransmitterQueuePacketsVersion1(
 #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));
         }
     }
 }
@@ -4315,21 +4312,14 @@ TransmitterAbortPackets(
     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);
     }    
@@ -4349,19 +4339,15 @@ TransmitterQueryRingSize(
 }
 
 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);
 }
index 8dc4e3c813482c8e4922843ef8e39f8ec3a4a401..fad0762b35f8b065257909e7d01379a4f7eb18a6 100644 (file)
@@ -78,7 +78,7 @@ TransmitterTeardown(
     );
 
 extern VOID
-TransmitterRingNotify(
+TransmitterNotify(
     IN  PXENVIF_TRANSMITTER Transmitter,
     IN  ULONG               Index
     );
index f3f4372d9171914020bb94b9a8b51324c4586baa..c2c37d1dc1e9d1ca375ef9e713d40ed636599158 100644 (file)
@@ -36,7 +36,7 @@
       <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>
@@ -44,7 +44,7 @@
     </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>
index 8dd18be64eb4fe738661e5ec394d3a8dd0013059..879fe1d9be3a8a7d4f3cd422f330842548476019 100644 (file)
@@ -36,7 +36,7 @@
     </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>
@@ -47,7 +47,7 @@
     </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>