[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[win-pv-devel] [RFC PATCH 6/6] Fix up more than 1 queue



Fix several issues determining the correct number of queues to use.
Will now use max(1, min(multi-queue-max-queues, number-of-vcpus,
frontend-registry-override))

Signed-off-by: owensm <owen.smith@xxxxxxxxxx>
---
 src/xenvbd/frontend.c |  82 ++++++++++++++++++++++++++++++++-------
 src/xenvbd/frontend.h |   1 +
 src/xenvbd/protocol.c | 104 ++++++++++++++++++++++++++++++++------------------
 3 files changed, 136 insertions(+), 51 deletions(-)

diff --git a/src/xenvbd/frontend.c b/src/xenvbd/frontend.c
index 40fdbca..80b12d9 100644
--- a/src/xenvbd/frontend.c
+++ b/src/xenvbd/frontend.c
@@ -75,6 +75,7 @@ struct _XENVBD_FRONTEND {
     XENVBD_PAGE                 Page80;
     XENVBD_PAGE                 Page83;
     ULONG                       MultiQueueMaxQueues;
+    ULONG                       MultiQueueNumQueues;
 
     // Interfaces to XenBus
     XENBUS_STORE_INTERFACE      StoreInterface;
@@ -785,7 +786,6 @@ FrontendReadFeatures(
     IN  PXENVBD_FRONTEND    Frontend
     )
 {
-    ULONG                   ProcessorCount;
     BOOLEAN                 Changed;
 
     Changed = FrontendReadFeature(Frontend,
@@ -798,14 +798,6 @@ FrontendReadFeatures(
     Changed |= FrontendReadFeature(Frontend,
                                    FeaturePersistent,
                                    &Frontend->Features.Persistent);
-    Changed |= FrontendReadValue32(Frontend,
-                                   FeatureMultiQueueMaxQueues,
-                                   TRUE,
-                                   &Frontend->MultiQueueMaxQueues);
-
-    ProcessorCount = KeQueryActiveProcessorCount(NULL);
-    if (ProcessorCount < Frontend->MultiQueueMaxQueues)
-        Frontend->MultiQueueMaxQueues = ProcessorCount;
 
     if (!Changed)
         return;
@@ -821,10 +813,6 @@ FrontendReadFeatures(
                     Frontend->TargetId,
                     Frontend->Features.Indirect);
     }
-
-    Verbose("Target[%d] : MultiQueueMaxQueues %u\n",
-            Frontend->TargetId,
-            Frontend->MultiQueueMaxQueues);
 }
 
 static FORCEINLINE VOID
@@ -1095,6 +1083,41 @@ fail1:
     Error("Fail1 (%08x)\n", Status);
     return Status;
 }
+
+static VOID
+FrontendSetNumQueues(
+    IN  PXENVBD_FRONTEND    Frontend
+    )
+{
+    PCHAR                   Buffer;
+    ULONG                   BackendMaxQueues;
+    NTSTATUS                status;
+
+    status = XENBUS_STORE(Read,
+                          &Frontend->StoreInterface,
+                          NULL,
+                          FrontendGetBackendPath(Frontend),
+                          "multi-queue-max-queues",
+                          &Buffer);
+    if (NT_SUCCESS(status)) {
+        BackendMaxQueues = (ULONG)strtoul(Buffer, NULL, 10);
+
+        XENBUS_STORE(Free,
+                     &Frontend->StoreInterface,
+                     Buffer);
+    }
+    else {
+        BackendMaxQueues = 1;
+    }
+
+    Frontend->MultiQueueNumQueues = 
__min(FrontendGetMultiQueueMaxQueues(Frontend),
+                                          BackendMaxQueues);
+
+    Verbose("Target[%d] %u\n",
+            Frontend->TargetId,
+            Frontend->MultiQueueNumQueues);
+}
+
 __drv_requiresIRQL(DISPATCH_LEVEL)
 static NTSTATUS
 FrontendConnect(
@@ -1109,6 +1132,8 @@ FrontendConnect(
     if (!NT_SUCCESS(Status))
         goto fail1;
 
+    FrontendSetNumQueues(Frontend);
+
     Status = ProtocolConnect(Frontend->Protocol);
     if (!NT_SUCCESS(Status))
         goto fail2;
@@ -1537,6 +1562,12 @@ FrontendDebugCallback(
                      Frontend->DiskInfo.DiscardGranularity);
     }
 
+    XENBUS_DEBUG(Printf,
+                 &Frontend->DebugInterface,
+                 "MultiQueueNumQueues: %u / %u\n",
+                 Frontend->MultiQueueNumQueues,
+                 Frontend->MultiQueueMaxQueues);
+
     XENBUS_DEBUG(Printf,
                  &Frontend->DebugInterface,
                  "DiskInfo: %llu @ %u (%u) %08x\n",
@@ -1740,6 +1771,28 @@ fail1:
     return status;
 }
 
+static FORCEINLINE VOID
+FrontendSetMaxQueues(
+    IN  PXENVBD_FRONTEND    Frontend
+    )
+{
+    ULONG                   FrontendMaxQueues;
+
+    Frontend->MultiQueueMaxQueues = 
KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS);;
+
+    if (DriverGetFeatureOverride(FeatureMultiQueueMaxQueues,
+                                 &FrontendMaxQueues) &&
+        FrontendMaxQueues < Frontend->MultiQueueMaxQueues)
+        Frontend->MultiQueueMaxQueues = FrontendMaxQueues;
+
+    if (Frontend->MultiQueueMaxQueues == 0)
+        Frontend->MultiQueueMaxQueues = 1;
+
+    Verbose("Target[%d] : MultiQueueMaxQueues %u\n",
+            Frontend->TargetId,
+            Frontend->MultiQueueMaxQueues);
+}
+
 NTSTATUS
 FrontendCreate(
     IN  PXENVBD_TARGET      Target,
@@ -1781,6 +1834,7 @@ FrontendCreate(
     if (!NT_SUCCESS(status))
         goto fail3;
 
+    FrontendSetMaxQueues(Frontend);
     status = ProtocolCreate(Frontend, &Frontend->Protocol);
     if (!NT_SUCCESS(status))
         goto fail4;
@@ -1944,6 +1998,6 @@ FrontendGetBarrier(
     return Frontend->DiskInfo.Barrier;
 }
 FRONTEND_GET_PROPERTY(MultiQueueMaxQueues, ULONG)
-
+FRONTEND_GET_PROPERTY(MultiQueueNumQueues, ULONG)
 
 #undef FRONTEND_GET_PROPERTY
diff --git a/src/xenvbd/frontend.h b/src/xenvbd/frontend.h
index 0ffb261..e068f51 100644
--- a/src/xenvbd/frontend.h
+++ b/src/xenvbd/frontend.h
@@ -168,6 +168,7 @@ FRONTEND_GET_PROPERTY(Discard, BOOLEAN)
 FRONTEND_GET_PROPERTY(FlushCache, BOOLEAN)
 FRONTEND_GET_PROPERTY(Barrier, BOOLEAN)
 FRONTEND_GET_PROPERTY(MultiQueueMaxQueues, ULONG)
+FRONTEND_GET_PROPERTY(MultiQueueNumQueues, ULONG)
 
 #undef FRONTEND_GET_PROPERTY
 
diff --git a/src/xenvbd/protocol.c b/src/xenvbd/protocol.c
index 8aa6ec8..bfca3bb 100644
--- a/src/xenvbd/protocol.c
+++ b/src/xenvbd/protocol.c
@@ -106,7 +106,6 @@ struct _XENVBD_PROTOCOL {
     PXENBUS_CACHE                   IndirectCache;
 
     ULONG                           Order;
-    ULONG                           NumQueues;
     PXENVBD_RING                    *Rings;
 
     ULONG64                         SegsGranted;
@@ -1008,9 +1007,9 @@ RingCreate(
     (*Ring)->Protocol = Protocol;
     (*Ring)->Index = Index;
 
-    Length = 1 + (ULONG)strlen(FrontendGetFrontendPath(Frontend)) + 
(ULONG)strlen("queue-xx");
+    Length = (ULONG)strlen(FrontendGetFrontendPath(Frontend)) + 
(ULONG)strlen("/queue-xxx");
 
-    (*Ring)->Path = __ProtocolAllocate(sizeof(CHAR) * Length);
+    (*Ring)->Path = __ProtocolAllocate(sizeof(CHAR) * (Length + 1));
 
     status = STATUS_NO_MEMORY;
     if ((*Ring)->Path == NULL)
@@ -1198,12 +1197,15 @@ RingStoreWrite(
     PXENVBD_GRANTER     Granter = FrontendGetGranter(Protocol->Frontend);
     PCHAR               Path;
     ULONG               Port;
+    ULONG               NumQueues;
     NTSTATUS            status;
 
-    if (FrontendGetMultiQueueMaxQueues(Protocol->Frontend) > 1)
-        Path = Ring->Path;
-    else
-        Path = FrontendGetFrontendPath(Protocol->Frontend);
+    NumQueues = FrontendGetMultiQueueNumQueues(Protocol->Frontend);
+
+    ASSERT(NumQueues != 0);
+    Path = (NumQueues == 1) ?
+           FrontendGetFrontendPath(Protocol->Frontend) :
+           Ring->Path;
 
     if (Protocol->Order == 0) {
         status = XENBUS_STORE(Printf,
@@ -1935,6 +1937,7 @@ ProtocolCreate(
     PXENVBD_ADAPTER         Adapter = TargetGetAdapter(Target);
     CHAR                    Name[MAX_NAME_LEN];
     ULONG                   Index;
+    ULONG                   MaxQueues;
     NTSTATUS                status;
 
     *Protocol = __ProtocolAllocate(sizeof(XENVBD_PROTOCOL));
@@ -2015,28 +2018,32 @@ ProtocolCreate(
     if (!NT_SUCCESS(status))
         goto fail8;
 
-    (*Protocol)->NumQueues = FrontendGetMultiQueueMaxQueues(Frontend);
-    if ((*Protocol)->NumQueues == 0)
-        (*Protocol)->NumQueues = 1;
-    (*Protocol)->Rings = __ProtocolAllocate(sizeof(PXENVBD_RING) * 
(*Protocol)->NumQueues);
+    MaxQueues = FrontendGetMultiQueueMaxQueues(Frontend);
+
+    (*Protocol)->Rings = __ProtocolAllocate(sizeof(PXENVBD_RING) *
+                                            MaxQueues);
 
     status = STATUS_NO_MEMORY;
     if ((*Protocol)->Rings == NULL)
         goto fail9;
 
-    for (Index = 0; Index < (*Protocol)->NumQueues; ++Index) {
+    for (Index = 0; Index < MaxQueues; ++Index) {
+        PXENVBD_RING        Ring;
+
         status = RingCreate(*Protocol,
                             Index,
-                            &(*Protocol)->Rings[Index]);
+                            &Ring);
         if (!NT_SUCCESS(status))
             goto fail10;
+
+        (*Protocol)->Rings[Index] = Ring;
     }
 
     return STATUS_SUCCESS;
 
 fail10:
     Error("fail10\n");
-    for (Index = 0; Index < (*Protocol)->NumQueues; ++Index) {
+    for (Index = 0; Index < MaxQueues; ++Index) {
         if ((*Protocol)->Rings[Index])
             RingDestroy((*Protocol)->Rings[Index]);
         (*Protocol)->Rings[Index] = NULL;
@@ -2045,7 +2052,6 @@ fail10:
     (*Protocol)->Rings = NULL;
 fail9:
     Error("fail9\n");
-    (*Protocol)->NumQueues = 0;
     XENBUS_CACHE(Destroy,
                  &(*Protocol)->CacheInterface,
                  (*Protocol)->IndirectCache);
@@ -2094,9 +2100,12 @@ ProtocolDestroy(
     IN  PXENVBD_PROTOCOL    Protocol
     )
 {
+    ULONG                   MaxQueues;
     ULONG                   Index;
 
-    for (Index = 0; Index < Protocol->NumQueues; ++Index) {
+    MaxQueues = FrontendGetMultiQueueMaxQueues(Protocol->Frontend);
+
+    for (Index = 0; Index < MaxQueues; ++Index) {
         if (Protocol->Rings[Index])
             RingDestroy(Protocol->Rings[Index]);
         Protocol->Rings[Index] = 0;
@@ -2105,8 +2114,6 @@ ProtocolDestroy(
     __ProtocolFree(Protocol->Rings);
     Protocol->Rings = NULL;
 
-    Protocol->NumQueues = 0;
-
     XENBUS_CACHE(Destroy,
                  &Protocol->CacheInterface,
                  Protocol->IndirectCache);
@@ -2146,11 +2153,14 @@ ProtocolConnect(
     PXENVBD_TARGET      Target = FrontendGetTarget(Protocol->Frontend);
     PXENVBD_ADAPTER     Adapter = TargetGetAdapter(Target);
     PCHAR               Buffer;
+    ULONG               NumQueues;
     ULONG               Index;
     NTSTATUS            status;
 
     ASSERT(Protocol->Connected == FALSE);
 
+    NumQueues = FrontendGetMultiQueueNumQueues(Protocol->Frontend);
+
     AdapterGetStoreInterface(Adapter, &Protocol->StoreInterface);
     AdapterGetEvtchnInterface(Adapter, &Protocol->EvtchnInterface);
     AdapterGetDebugInterface(Adapter, &Protocol->DebugInterface);
@@ -2193,7 +2203,7 @@ ProtocolConnect(
         Protocol->Order = 0;
     }
 
-    for (Index = 0; Index < Protocol->NumQueues; ++Index) {
+    for (Index = 0; Index < NumQueues; ++Index) {
         status = RingConnect(Protocol->Rings[Index]);
         if (!NT_SUCCESS(status))
             goto fail4;
@@ -2213,7 +2223,7 @@ ProtocolConnect(
 
 fail5:
     Error("fail5\n");
-    Index = Protocol->NumQueues;
+    Index = FrontendGetMultiQueueNumQueues(Protocol->Frontend);
 fail4:
     Error("fail4\n");
     while (Index-- != 0) {
@@ -2247,9 +2257,12 @@ ProtocolStoreWrite(
     )
 {
     ULONG                   Index;
+    ULONG                   NumQueues;
     NTSTATUS                status;
 
-    for (Index = 0; Index < Protocol->NumQueues; ++Index) {
+    NumQueues = FrontendGetMultiQueueNumQueues(Protocol->Frontend);
+
+    for (Index = 0; Index < NumQueues; ++Index) {
         status = RingStoreWrite(Protocol->Rings[Index],
                                 Transaction);
         if (!NT_SUCCESS(status))
@@ -2268,15 +2281,17 @@ ProtocolStoreWrite(
             return status;
     }
 
-    status = XENBUS_STORE(Printf,
-                          &Protocol->StoreInterface,
-                          Transaction,
-                          FrontendGetFrontendPath(Protocol->Frontend),
-                          "multi-queue-num-queues",
-                          "%u",
-                          Protocol->NumQueues);
-    if (!NT_SUCCESS(status))
-        return status;
+    if (FrontendGetMultiQueueNumQueues(Protocol->Frontend) > 1) {
+        status = XENBUS_STORE(Printf,
+                              &Protocol->StoreInterface,
+                              Transaction,
+                              FrontendGetFrontendPath(Protocol->Frontend),
+                              "multi-queue-num-queues",
+                              "%u",
+                              
FrontendGetMultiQueueNumQueues(Protocol->Frontend));
+        if (!NT_SUCCESS(status))
+            return status;
+    }
 
     status = XENBUS_STORE(Printf,
                           &Protocol->StoreInterface,
@@ -2296,11 +2311,14 @@ ProtocolEnable(
     )
 {
     ULONG                   Index;
+    ULONG                   NumQueues;
 
     ASSERT(Protocol->Enabled == FALSE);
     Protocol->Enabled = TRUE;
 
-    for (Index = 0; Index < Protocol->NumQueues; ++Index)
+    NumQueues = FrontendGetMultiQueueNumQueues(Protocol->Frontend);
+
+    for (Index = 0; Index < NumQueues; ++Index)
         RingEnable(Protocol->Rings[Index]);
 }
 
@@ -2310,11 +2328,14 @@ ProtocolDisable(
     )
 {
     ULONG                   Index;
+    ULONG                   NumQueues;
 
     ASSERT(Protocol->Enabled == TRUE);
     Protocol->Enabled = FALSE;
 
-    for (Index = 0; Index < Protocol->NumQueues; ++Index)
+    NumQueues = FrontendGetMultiQueueNumQueues(Protocol->Frontend);
+
+    for (Index = 0; Index < NumQueues; ++Index)
         RingDisable(Protocol->Rings[Index]);
 }
 
@@ -2324,16 +2345,19 @@ ProtocolDisconnect(
     )
 {
     ULONG               Index;
+    ULONG               NumQueues;
 
     ASSERT(Protocol->Connected);
     Protocol->Connected = FALSE;
 
+    NumQueues = FrontendGetMultiQueueNumQueues(Protocol->Frontend);
+
     XENBUS_DEBUG(Deregister,
                  &Protocol->DebugInterface,
                  Protocol->DebugCallback);
     Protocol->DebugCallback = NULL;
 
-    for (Index = 0; Index < Protocol->NumQueues; ++Index)
+    for (Index = 0; Index < NumQueues; ++Index)
         RingDisconnect(Protocol->Rings[Index]);
 
     Protocol->Order = 0;
@@ -2356,11 +2380,14 @@ ProtocolTrigger(
     )
 {
     ULONG                   Index;
+    ULONG                   NumQueues;
 
     if (!Protocol->Enabled)
         return;
 
-    for (Index = 0; Index < Protocol->NumQueues; ++Index)
+    NumQueues = FrontendGetMultiQueueNumQueues(Protocol->Frontend);
+
+    for (Index = 0; Index < NumQueues; ++Index)
         RingTrigger(Protocol->Rings[Index]);
 }
 
@@ -2369,13 +2396,16 @@ __ProtocolGetRing(
     IN  PXENVBD_PROTOCOL    Protocol
     )
 {
+    ULONG                   NumQueues;
     ULONG                   Index;
 
-    if (Protocol->NumQueues == 0)
+    NumQueues = FrontendGetMultiQueueNumQueues(Protocol->Frontend);
+
+    if (NumQueues == 0)
         return Protocol->Rings[0];
 
-    Index = KeGetCurrentProcessorNumberEx(NULL) % Protocol->NumQueues;
-    ASSERT(Index < Protocol->NumQueues);
+    Index = KeGetCurrentProcessorNumberEx(NULL) % NumQueues;
+    ASSERT(Index < NumQueues);
 
     return Protocol->Rings[Index];
 }
-- 
2.16.2.windows.1


_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/win-pv-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.