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

[win-pv-devel] [PATCH] Fix compatibility with older backends



There was a problem when XENVIF was brought up on backends that don't
implement a control ring. This patch fixes the issue.

Reportted-by: Rafal Wojdyla <omeg@xxxxxxxxxxxxxxxxxxxxxx>
Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
---
 src/xenvif/controller.c | 143 +++++++++++++++---------------------------------
 src/xenvif/frontend.c   | 115 ++++++++++++++++++++++++--------------
 src/xenvif/frontend.h   |   5 --
 src/xenvif/receiver.c   |  18 ------
 4 files changed, 119 insertions(+), 162 deletions(-)

diff --git a/src/xenvif/controller.c b/src/xenvif/controller.c
index 1d1f16e..e54c9fc 100644
--- a/src/xenvif/controller.c
+++ b/src/xenvif/controller.c
@@ -73,7 +73,6 @@ struct _XENVIF_CONTROLLER {
     ULONG                               Dpcs;
     ULONG                               Events;
     BOOLEAN                             Connected;
-    BOOLEAN                             Enabled;
     USHORT                              RequestId;
     struct xen_netif_ctrl_request       Request;
     struct xen_netif_ctrl_response      Response;
@@ -193,9 +192,13 @@ ControllerPutRequest(
     BOOLEAN                         Notify;
     NTSTATUS                        status;
 
+    status = STATUS_NOT_SUPPORTED;
+    if (!Controller->Connected)
+        goto fail1;
+
     status = STATUS_INSUFFICIENT_RESOURCES;
     if (RING_FULL(&Controller->Front))
-        goto fail1;
+        goto fail2;
 
     Controller->Request.type = Type;
     Controller->Request.id = Controller->RequestId++;
@@ -227,6 +230,9 @@ ControllerPutRequest(
 
     return STATUS_SUCCESS;
 
+fail2:
+    Error("fail2\n");
+
 fail1:
     Error("fail1 (%08x)\n", status);
 
@@ -340,11 +346,11 @@ ControllerWatchdog(
         KeRaiseIrql(DISPATCH_LEVEL, &Irql);
         __ControllerAcquireLock(Controller);
 
-        if (Controller->Enabled) {
+        if (Controller->Connected) {
             KeMemoryBarrier();
 
             if (Controller->Shared->rsp_prod != rsp_prod &&
-                 Controller->Front.rsp_cons == rsp_cons) {
+                Controller->Front.rsp_cons == rsp_cons) {
                 XENBUS_DEBUG(Trigger,
                              &Controller->DebugInterface,
                              Controller->DebugCallback);
@@ -392,7 +398,7 @@ ControllerDpc(
 
     __ControllerAcquireLock(Controller);
 
-    if (Controller->Enabled)
+    if (Controller->Connected)
         ControllerPoll(Controller);
 
     __ControllerReleaseLock(Controller);
@@ -767,15 +773,9 @@ ControllerEnable(
     IN  PXENVIF_CONTROLLER      Controller
     )
 {
-    Trace("====>\n");
-
-    __ControllerAcquireLock(Controller);
+    UNREFERENCED_PARAMETER(Controller);
 
-    Controller->Enabled = TRUE;
-
-    __ControllerReleaseLock(Controller);
-
-    Trace("<====\n");
+    Trace("<===>\n");
 }
 
 VOID
@@ -783,15 +783,9 @@ ControllerDisable(
     IN  PXENVIF_CONTROLLER      Controller
     )
 {
-    Trace("====>\n");
-
-    __ControllerAcquireLock(Controller);
-
-    Controller->Enabled = FALSE;
+    UNREFERENCED_PARAMETER(Controller);
 
-    __ControllerReleaseLock(Controller);
-
-    Trace("<====\n");
+    Trace("<===>\n");
 }
 
 VOID
@@ -906,29 +900,22 @@ ControllerSetHashAlgorithm(
 
     __ControllerAcquireLock(Controller);
 
-    status = STATUS_NOT_SUPPORTED;
-    if (!Controller->Connected)
-        goto fail1;
-
     status = ControllerPutRequest(Controller,
                                   XEN_NETIF_CTRL_TYPE_SET_HASH_ALGORITHM,
                                   Algorithm,
                                   0,
                                   0);
     if (!NT_SUCCESS(status))
-        goto fail2;
+        goto fail1;
 
     status = ControllerGetResponse(Controller, NULL);
     if (!NT_SUCCESS(status))
-        goto fail3;
+        goto fail2;
 
     __ControllerReleaseLock(Controller);
 
     return STATUS_SUCCESS;
 
-fail3:
-    Error("fail3\n");
-
 fail2:
     Error("fail2\n");
 
@@ -953,29 +940,22 @@ ControllerGetHashFlags(
 
     __ControllerAcquireLock(Controller);
 
-    status = STATUS_NOT_SUPPORTED;
-    if (!Controller->Enabled)
-        goto fail1;
-
     status = ControllerPutRequest(Controller,
                                   XEN_NETIF_CTRL_TYPE_GET_HASH_FLAGS,
                                   0,
                                   0,
                                   0);
     if (!NT_SUCCESS(status))
-        goto fail2;
+        goto fail1;
 
     status = ControllerGetResponse(Controller, Flags);
     if (!NT_SUCCESS(status))
-        goto fail3;
+        goto fail2;
 
     __ControllerReleaseLock(Controller);
 
     return STATUS_SUCCESS;
 
-fail3:
-    Error("fail3\n");
-
 fail2:
     Error("fail2\n");
 
@@ -1000,29 +980,22 @@ ControllerSetHashFlags(
 
     __ControllerAcquireLock(Controller);
 
-    status = STATUS_NOT_SUPPORTED;
-    if (!Controller->Connected)
-        goto fail1;
-
     status = ControllerPutRequest(Controller,
                                   XEN_NETIF_CTRL_TYPE_SET_HASH_FLAGS,
                                   Flags,
                                   0,
                                   0);
     if (!NT_SUCCESS(status))
-        goto fail2;
+        goto fail1;
 
     status = ControllerGetResponse(Controller, NULL);
     if (!NT_SUCCESS(status))
-        goto fail3;
+        goto fail2;
 
     __ControllerReleaseLock(Controller);
 
     return STATUS_SUCCESS;
 
-fail3:
-    Error("fail3\n");
-
 fail2:
     Error("fail2\n");
 
@@ -1052,15 +1025,11 @@ ControllerSetHashKey(
 
     __ControllerAcquireLock(Controller);
 
-    status = STATUS_NOT_SUPPORTED;
-    if (!Controller->Enabled)
-        goto fail1;
-
     Mdl = __AllocatePage();
 
     status = STATUS_NO_MEMORY;
     if (Controller->Mdl == NULL)
-        goto fail2;
+        goto fail1;
 
     Buffer = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority);
     ASSERT(Buffer != NULL);
@@ -1078,7 +1047,7 @@ ControllerSetHashKey(
                            FALSE,
                            &Entry);
     if (!NT_SUCCESS(status))
-        goto fail3;
+        goto fail2;
 
     status = ControllerPutRequest(Controller,
                                   XEN_NETIF_CTRL_TYPE_SET_HASH_KEY,
@@ -1088,11 +1057,11 @@ ControllerSetHashKey(
                                   Size,
                                   0);
     if (!NT_SUCCESS(status))
-        goto fail4;
+        goto fail3;
 
     status = ControllerGetResponse(Controller, NULL);
     if (!NT_SUCCESS(status))
-        goto fail5;
+        goto fail4;
 
     (VOID) XENBUS_GNTTAB(RevokeForeignAccess,
                          &Controller->GnttabInterface,
@@ -1106,26 +1075,23 @@ ControllerSetHashKey(
 
     return STATUS_SUCCESS;
 
-fail5:
-    Error("fail5\n");
-
 fail4:
     Error("fail4\n");
 
+fail3:
+    Error("fail3\n");
+
     (VOID) XENBUS_GNTTAB(RevokeForeignAccess,
                          &Controller->GnttabInterface,
                          Controller->GnttabCache,
                          TRUE,
                          Entry);
 
-fail3:
-    Error("fail3\n");
-
-    __FreePage(Mdl);
-
 fail2:
     Error("fail2\n");
 
+    __FreePage(Mdl);
+
 fail1:
     Error("fail1 (%08x)\n", status);
 
@@ -1147,29 +1113,22 @@ ControllerGetHashMappingSize(
 
     __ControllerAcquireLock(Controller);
 
-    status = STATUS_NOT_SUPPORTED;
-    if (!Controller->Enabled)
-        goto fail1;
-
     status = ControllerPutRequest(Controller,
                                   XEN_NETIF_CTRL_TYPE_GET_HASH_MAPPING_SIZE,
                                   0,
                                   0,
                                   0);
     if (!NT_SUCCESS(status))
-        goto fail2;
+        goto fail1;
 
     status = ControllerGetResponse(Controller, Size);
     if (!NT_SUCCESS(status))
-        goto fail3;
+        goto fail2;
 
     __ControllerReleaseLock(Controller);
 
     return STATUS_SUCCESS;
 
-fail3:
-    Error("fail3\n");
-
 fail2:
     Error("fail2\n");
 
@@ -1194,29 +1153,22 @@ ControllerSetHashMappingSize(
 
     __ControllerAcquireLock(Controller);
 
-    status = STATUS_NOT_SUPPORTED;
-    if (!Controller->Enabled)
-        goto fail1;
-
     status = ControllerPutRequest(Controller,
                                   XEN_NETIF_CTRL_TYPE_SET_HASH_MAPPING_SIZE,
                                   Size,
                                   0,
                                   0);
     if (!NT_SUCCESS(status))
-        goto fail2;
+        goto fail1;
 
     status = ControllerGetResponse(Controller, NULL);
     if (!NT_SUCCESS(status))
-        goto fail3;
+        goto fail2;
 
     __ControllerReleaseLock(Controller);
 
     return STATUS_SUCCESS;
 
-fail3:
-    Error("fail3\n");
-
 fail2:
     Error("fail2\n");
 
@@ -1247,19 +1199,15 @@ ControllerSetHashMapping(
 
     __ControllerAcquireLock(Controller);
 
-    status = STATUS_NOT_SUPPORTED;
-    if (!Controller->Enabled)
-        goto fail1;
-
     status = STATUS_INVALID_PARAMETER;
     if (Size * sizeof (ULONG) > PAGE_SIZE)
-        goto fail2;
+        goto fail1;
 
     Mdl = __AllocatePage();
 
     status = STATUS_NO_MEMORY;
     if (Controller->Mdl == NULL)
-        goto fail3;
+        goto fail2;
 
     Buffer = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority);
     ASSERT(Buffer != NULL);
@@ -1277,7 +1225,7 @@ ControllerSetHashMapping(
                            FALSE,
                            &Entry);
     if (!NT_SUCCESS(status))
-        goto fail4;
+        goto fail3;
 
     status = ControllerPutRequest(Controller,
                                   XEN_NETIF_CTRL_TYPE_SET_HASH_MAPPING,
@@ -1287,11 +1235,11 @@ ControllerSetHashMapping(
                                   Size,
                                   Offset);
     if (!NT_SUCCESS(status))
-        goto fail5;
+        goto fail4;
 
     status = ControllerGetResponse(Controller, NULL);
     if (!NT_SUCCESS(status))
-        goto fail6;
+        goto fail5;
 
     (VOID) XENBUS_GNTTAB(RevokeForeignAccess,
                          &Controller->GnttabInterface,
@@ -1305,26 +1253,23 @@ ControllerSetHashMapping(
 
     return STATUS_SUCCESS;
 
-fail6:
-    Error("fail6\n");
-
 fail5:
     Error("fail5\n");
 
+fail4:
+    Error("fail4\n");
+
     (VOID) XENBUS_GNTTAB(RevokeForeignAccess,
                          &Controller->GnttabInterface,
                          Controller->GnttabCache,
                          TRUE,
                          Entry);
 
-fail4:
-    Error("fail4\n");
-
-    __FreePage(Mdl);
-
 fail3:
     Error("fail3\n");
 
+    __FreePage(Mdl);
+
 fail2:
     Error("fail2\n");
 
diff --git a/src/xenvif/frontend.c b/src/xenvif/frontend.c
index 0fbd640..6a2019e 100644
--- a/src/xenvif/frontend.c
+++ b/src/xenvif/frontend.c
@@ -1808,16 +1808,16 @@ FrontendIsSplit(
 
 static FORCEINLINE NTSTATUS
 __FrontendUpdateHash(
-    IN  PXENVIF_FRONTEND                Frontend
+    PXENVIF_FRONTEND        Frontend,
+    PXENVIF_FRONTEND_HASH   Hash
     )
 {
-    PXENVIF_FRONTEND_HASH               Hash = &Frontend->Hash;
-    PXENVIF_CONTROLLER                  Controller;
-    ULONG                               Zero = 0;
-    ULONG                               Size;
-    PULONG                              Mapping;
-    ULONG                               Flags;
-    NTSTATUS                            status;
+    PXENVIF_CONTROLLER      Controller;
+    ULONG                   Zero = 0;
+    ULONG                   Size;
+    PULONG                  Mapping;
+    ULONG                   Flags;
+    NTSTATUS                status;
 
     Controller = __FrontendGetController(Frontend);
 
@@ -1884,35 +1884,17 @@ fail1:
 }
 
 NTSTATUS
-FrontendUpdateHash(
-    IN  PXENVIF_FRONTEND                Frontend
-    )
-{
-    KIRQL                               Irql;
-    NTSTATUS                            status;
-
-    KeAcquireSpinLock(&Frontend->Lock, &Irql);
-    status = __FrontendUpdateHash(Frontend);
-    KeReleaseSpinLock(&Frontend->Lock, Irql);
-
-    return status;
-}
-
-NTSTATUS
 FrontendSetHashAlgorithm(
     IN  PXENVIF_FRONTEND                Frontend,
     IN  XENVIF_PACKET_HASH_ALGORITHM    Algorithm
     )
 {
-    PXENVIF_FRONTEND_HASH               Hash = &Frontend->Hash;
+    XENVIF_FRONTEND_HASH                Hash;
     KIRQL                               Irql;
     NTSTATUS                            status;
 
     KeAcquireSpinLock(&Frontend->Lock, &Irql);
 
-    if (Algorithm == Hash->Algorithm)
-        goto done;
-
     switch (Algorithm) {
     case XENVIF_PACKET_HASH_ALGORITHM_NONE:
     case XENVIF_PACKET_HASH_ALGORITHM_UNSPECIFIED:
@@ -1934,13 +1916,23 @@ FrontendSetHashAlgorithm(
          (Algorithm == XENVIF_PACKET_HASH_ALGORITHM_TOEPLITZ) ? "TOEPLITZ" :
          "");
 
-    Hash->Algorithm = Algorithm;
+    Hash = Frontend->Hash;
+
+    Hash.Algorithm = Algorithm;
+
+    status = __FrontendUpdateHash(Frontend, &Hash);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    Frontend->Hash = Hash;
 
-done:
     KeReleaseSpinLock(&Frontend->Lock, Irql);
 
     return STATUS_SUCCESS;
 
+fail2:
+    Error("fail2\n");
+
 fail1:
     Error("fail1 (%08x)\n");
 
@@ -1995,7 +1987,7 @@ FrontendSetHashMapping(
     IN  ULONG               Size
     )
 {
-    PXENVIF_FRONTEND_HASH   Hash = &Frontend->Hash;
+    XENVIF_FRONTEND_HASH    Hash;
     KIRQL                   Irql;
     NTSTATUS                status;
 
@@ -2005,13 +1997,24 @@ FrontendSetHashMapping(
     if (Size > XENVIF_FRONTEND_MAXIMUM_HASH_MAPPING_SIZE)
         goto fail1;
 
-    RtlCopyMemory(Hash->Mapping, Mapping, sizeof (ULONG) * Size);
-    Hash->Size = Size;
+    Hash = Frontend->Hash;
+
+    RtlCopyMemory(Hash.Mapping, Mapping, sizeof (ULONG) * Size);
+    Hash.Size = Size;
+
+    status = __FrontendUpdateHash(Frontend, &Hash);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    Frontend->Hash = Hash;
 
     KeReleaseSpinLock(&Frontend->Lock, Irql);
 
     return STATUS_SUCCESS;
 
+fail2:
+    Error("fail2\n");
+
 fail1:
     Error("fail1 (%08x)\n", status);
 
@@ -2026,16 +2029,32 @@ FrontendSetHashKey(
     IN  PUCHAR              Key
     )
 {
-    PXENVIF_FRONTEND_HASH   Hash = &Frontend->Hash;
+    XENVIF_FRONTEND_HASH    Hash;
     KIRQL                   Irql;
+    NTSTATUS                status;
 
     KeAcquireSpinLock(&Frontend->Lock, &Irql);
 
-    RtlCopyMemory(Hash->Key, Key, XENVIF_VIF_HASH_KEY_SIZE);
+    Hash = Frontend->Hash;
+
+    RtlCopyMemory(Hash.Key, Key, XENVIF_VIF_HASH_KEY_SIZE);
+
+    status = __FrontendUpdateHash(Frontend, &Hash);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    Frontend->Hash = Hash;
 
     KeReleaseSpinLock(&Frontend->Lock, Irql);
 
     return STATUS_SUCCESS;
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    KeReleaseSpinLock(&Frontend->Lock, Irql);
+
+    return status;
 }
 
 NTSTATUS
@@ -2044,12 +2063,15 @@ FrontendSetHashTypes(
     IN  ULONG               Types
     )
 {
-    PXENVIF_FRONTEND_HASH   Hash = &Frontend->Hash;
+    XENVIF_FRONTEND_HASH    Hash;
     KIRQL                   Irql;
     ULONG                   Flags;
+    NTSTATUS                status;
 
     KeAcquireSpinLock(&Frontend->Lock, &Irql);
 
+    Hash = Frontend->Hash;
+
     Flags = 0;
     if (Types & (1 << XENVIF_PACKET_HASH_TYPE_IPV4))
         Flags |= XEN_NETIF_CTRL_HASH_TYPE_IPV4;
@@ -2060,11 +2082,24 @@ FrontendSetHashTypes(
     if (Types & (1 << XENVIF_PACKET_HASH_TYPE_IPV6_TCP))
         Flags |= XEN_NETIF_CTRL_HASH_TYPE_IPV6_TCP;
 
-    Hash->Flags = Flags;
+    Hash.Flags = Flags;
+
+    status = __FrontendUpdateHash(Frontend, &Hash);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    Frontend->Hash = Hash;
 
     KeReleaseSpinLock(&Frontend->Lock, Irql);
 
     return STATUS_SUCCESS;
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    KeReleaseSpinLock(&Frontend->Lock, Irql);
+
+    return status;
 }
 
 ULONG
@@ -2073,17 +2108,16 @@ FrontendGetQueue(
     IN  ULONG               Value
     )
 {
-    PXENVIF_FRONTEND_HASH   Hash = &Frontend->Hash;
     ULONG                   Queue;
 
-    switch (Hash->Algorithm) {
+    switch (Frontend->Hash.Algorithm) {
     case XENVIF_PACKET_HASH_ALGORITHM_NONE:
     case XENVIF_PACKET_HASH_ALGORITHM_UNSPECIFIED:
         Queue = Value % __FrontendGetNumQueues(Frontend);
         break;
 
     case XENVIF_PACKET_HASH_ALGORITHM_TOEPLITZ:
-        Queue = Hash->Mapping[Value % Hash->Size];
+        Queue = Frontend->Hash.Mapping[Value % Frontend->Hash.Size];
         break;
 
     default:
@@ -2226,6 +2260,7 @@ abort:
             break;
 
         case XenbusStateConnected:
+        case XenbusStateClosed:
             break;
 
         default:
@@ -2350,7 +2385,7 @@ FrontendEnable(
     if (!NT_SUCCESS(status))
         goto fail3;
 
-    status = __FrontendUpdateHash(Frontend);
+    status = __FrontendUpdateHash(Frontend, &Frontend->Hash);
     if (!NT_SUCCESS(status))
         goto fail4;
 
diff --git a/src/xenvif/frontend.h b/src/xenvif/frontend.h
index 513e812..06ae78a 100644
--- a/src/xenvif/frontend.h
+++ b/src/xenvif/frontend.h
@@ -206,11 +206,6 @@ FrontendAdvertiseIpAddresses(
     );
 
 extern NTSTATUS
-FrontendUpdateHash(
-    IN  PXENVIF_FRONTEND    Frontend
-    );
-
-extern NTSTATUS
 FrontendSetHashAlgorithm(
     IN  PXENVIF_FRONTEND                Frontend,
     IN  XENVIF_PACKET_HASH_ALGORITHM    Algorithm
diff --git a/src/xenvif/receiver.c b/src/xenvif/receiver.c
index f2d57ba..a33f8ce 100644
--- a/src/xenvif/receiver.c
+++ b/src/xenvif/receiver.c
@@ -3621,15 +3621,8 @@ ReceiverSetHashAlgorithm(
     if (!NT_SUCCESS(status))
         goto fail1;
 
-    status = FrontendUpdateHash(Frontend);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
     return STATUS_SUCCESS;
 
-fail2:
-    Error("fail2\n");
-
 fail1:
     Error("fail1 (%08x)\n", status);
 
@@ -3697,10 +3690,6 @@ ReceiverUpdateHashParameters(
 
     status = FrontendSetHashKey(Frontend, Key);
     if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status = FrontendUpdateHash(Frontend);
-    if (!NT_SUCCESS(status))
         goto fail2;
 
     return STATUS_SUCCESS;
@@ -3749,17 +3738,10 @@ ReceiverUpdateHashMapping(
     if (!NT_SUCCESS(status))
         goto fail3;
 
-    status = FrontendUpdateHash(Frontend);
-    if (!NT_SUCCESS(status))
-        goto fail4;
-
     __ReceiverFree(QueueMapping);
 
     return STATUS_SUCCESS;
 
-fail4:
-    Error("fail4\n");
-
 fail3:
     Error("fail3\n");
 
-- 
2.1.1


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

 


Rackspace

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