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

[win-pv-devel] [PATCH for 8.1] Make sure XENBUS interfaces are released when going into S4



Because a transition into and out of S4 means a new domain is built, it's
crucial that all XENBUS interfaces are released (so that things like
event channels, grant tables and the xenstore ring get re-constructed).

This patch fixes code paths where this was not being done.

Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
---
 src/xenvif/receiver.c    | 249 +++++++++++++------------
 src/xenvif/transmitter.c | 461 +++++++++++++++++++++++------------------------
 src/xenvif/vif.c         | 138 ++++++++------
 3 files changed, 435 insertions(+), 413 deletions(-)

diff --git a/src/xenvif/receiver.c b/src/xenvif/receiver.c
index abe617d..c6f64b5 100644
--- a/src/xenvif/receiver.c
+++ b/src/xenvif/receiver.c
@@ -2129,7 +2129,6 @@ __ReceiverRingInitialize(
     )
 {
     PXENVIF_FRONTEND            Frontend;
-    CHAR                        Name[MAXNAMELEN];
     NTSTATUS                    status;
 
     Frontend = Receiver->Frontend;
@@ -2153,86 +2152,14 @@ __ReceiverRingInitialize(
 
     KeInitializeDpc(&(*Ring)->Dpc, ReceiverRingDpc, *Ring);
 
-    status = RtlStringCbPrintfA(Name,
-                                sizeof (Name),
-                                "%s_receiver_packet",
-                                (*Ring)->Path);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-
-    for (Index = 0; Name[Index] != '\0'; Index++)
-        if (Name[Index] == '/')
-            Name[Index] = '_';
-
-    status = XENBUS_CACHE(Create,
-                          &Receiver->CacheInterface,
-                          Name,
-                          sizeof (XENVIF_RECEIVER_PACKET),
-                          0,
-                          ReceiverPacketCtor,
-                          ReceiverPacketDtor,
-                          ReceiverRingAcquireLock,
-                          ReceiverRingReleaseLock,
-                          *Ring,
-                          &(*Ring)->PacketCache);
-    if (!NT_SUCCESS(status))
-        goto fail4;
-
-    status = RtlStringCbPrintfA(Name,
-                                sizeof (Name),
-                                "%s_receiver_fragment",
-                                (*Ring)->Path);
-    if (!NT_SUCCESS(status))
-        goto fail5;
-
-    for (Index = 0; Name[Index] != '\0'; Index++)
-        if (Name[Index] == '/')
-            Name[Index] = '_';
-
-    status = XENBUS_CACHE(Create,
-                          &Receiver->CacheInterface,
-                          Name,
-                          sizeof (XENVIF_RECEIVER_FRAGMENT),
-                          0,
-                          ReceiverFragmentCtor,
-                          ReceiverFragmentDtor,
-                          ReceiverRingAcquireLock,
-                          ReceiverRingReleaseLock,
-                          *Ring,
-                          &(*Ring)->FragmentCache);
-    if (!NT_SUCCESS(status))
-        goto fail6;
-
     status = ThreadCreate(ReceiverRingWatchdog,
                           *Ring,
                           &(*Ring)->WatchdogThread);
     if (!NT_SUCCESS(status))
-        goto fail7;
+        goto fail3;
 
     return STATUS_SUCCESS;
 
-fail7:
-    Error("fail7\n");
-
-    XENBUS_CACHE(Destroy,
-                 &Receiver->CacheInterface,
-                 (*Ring)->FragmentCache);
-    (*Ring)->FragmentCache = NULL;
-
-fail6:
-    Error("fail6\n");
-
-fail5:
-    Error("fail5\n");
-
-    XENBUS_CACHE(Destroy,
-                 &Receiver->CacheInterface,
-                 (*Ring)->PacketCache);
-    (*Ring)->PacketCache = NULL;
-
-fail4:
-    Error("fail4\n");
-
 fail3:
     Error("fail3\n");
 
@@ -2279,7 +2206,7 @@ __ReceiverRingConnect(
 
     status = RtlStringCbPrintfA(Name,
                                 sizeof (Name),
-                                "%s_receiver",
+                                "%s_receiver_packet",
                                 Ring->Path);
     if (!NT_SUCCESS(status))
         goto fail1;
@@ -2288,6 +2215,56 @@ __ReceiverRingConnect(
         if (Name[Index] == '/')
             Name[Index] = '_';
 
+    status = XENBUS_CACHE(Create,
+                          &Receiver->CacheInterface,
+                          Name,
+                          sizeof (XENVIF_RECEIVER_PACKET),
+                          0,
+                          ReceiverPacketCtor,
+                          ReceiverPacketDtor,
+                          ReceiverRingAcquireLock,
+                          ReceiverRingReleaseLock,
+                          Ring,
+                          &Ring->PacketCache);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    status = RtlStringCbPrintfA(Name,
+                                sizeof (Name),
+                                "%s_receiver_fragment",
+                                Ring->Path);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
+    for (Index = 0; Name[Index] != '\0'; Index++)
+        if (Name[Index] == '/')
+            Name[Index] = '_';
+
+    status = XENBUS_CACHE(Create,
+                          &Receiver->CacheInterface,
+                          Name,
+                          sizeof (XENVIF_RECEIVER_FRAGMENT),
+                          0,
+                          ReceiverFragmentCtor,
+                          ReceiverFragmentDtor,
+                          ReceiverRingAcquireLock,
+                          ReceiverRingReleaseLock,
+                          Ring,
+                          &Ring->FragmentCache);
+    if (!NT_SUCCESS(status))
+        goto fail4;
+
+    status = RtlStringCbPrintfA(Name,
+                                sizeof (Name),
+                                "%s_receiver",
+                                Ring->Path);
+    if (!NT_SUCCESS(status))
+        goto fail5;
+
+    for (Index = 0; Name[Index] != '\0'; Index++)
+        if (Name[Index] == '/')
+            Name[Index] = '_';
+
     status = XENBUS_GNTTAB(CreateCache,
                            &Receiver->GnttabInterface,
                            Name,
@@ -2297,13 +2274,13 @@ __ReceiverRingConnect(
                            Ring,
                            &Ring->GnttabCache);
     if (!NT_SUCCESS(status))
-        goto fail2;
+        goto fail6;
 
     Ring->Mdl = __AllocatePage();
 
     status = STATUS_NO_MEMORY;
     if (Ring->Mdl == NULL)
-        goto fail3;
+        goto fail7;
 
     Ring->Shared = MmGetSystemAddressForMdlSafe(Ring->Mdl, NormalPagePriority);
     ASSERT(Ring->Shared != NULL);
@@ -2323,14 +2300,14 @@ __ReceiverRingConnect(
                            FALSE,
                            &Ring->Entry);
     if (!NT_SUCCESS(status))
-        goto fail4;
+        goto fail8;
 
     status = RtlStringCbPrintfA(Name,
                                 sizeof (Name),
                                 __MODULE__ "|RECEIVER[%u]",
                                 Ring->Index);
     if (!NT_SUCCESS(status))
-        goto fail5;
+        goto fail9;
 
     ASSERT(!Ring->Connected);
 
@@ -2344,7 +2321,7 @@ __ReceiverRingConnect(
 
     status = STATUS_UNSUCCESSFUL;
     if (Ring->Channel == NULL)
-        goto fail6;
+        goto fail10;
 
     status = KeGetProcessorNumberFromIndex(Ring->Index, &ProcNumber);
     ASSERT(NT_SUCCESS(status));
@@ -2371,12 +2348,12 @@ __ReceiverRingConnect(
                           Ring,
                           &Ring->DebugCallback);
     if (!NT_SUCCESS(status))
-        goto fail7;
+        goto fail11;
 
     return STATUS_SUCCESS;
 
-fail7:
-    Error("fail7\n");
+fail11:
+    Error("fail11\n");
 
     Ring->Connected = FALSE;
 
@@ -2387,11 +2364,11 @@ fail7:
 
     Ring->Events = 0;
 
-fail6:
-    Error("fail6\n");
+fail10:
+    Error("fail10\n");
 
-fail5:
-    Error("fail5\n");
+fail9:
+    Error("fail9\n");
 
     (VOID) XENBUS_GNTTAB(RevokeForeignAccess,
                          &Receiver->GnttabInterface,
@@ -2400,8 +2377,8 @@ fail5:
                          Ring->Entry);
     Ring->Entry = NULL;
 
-fail4:
-    Error("fail4\n");
+fail8:
+    Error("fail8\n");
 
     RtlZeroMemory(&Ring->Front, sizeof (netif_rx_front_ring_t));
     RtlZeroMemory(Ring->Shared, PAGE_SIZE);
@@ -2410,14 +2387,36 @@ fail4:
     __FreePage(Ring->Mdl);
     Ring->Mdl = NULL;
 
-fail3:
-    Error("fail3\n");
+fail7:
+    Error("fail7\n");
 
     XENBUS_GNTTAB(DestroyCache,
                   &Receiver->GnttabInterface,
                   Ring->GnttabCache);
     Ring->GnttabCache = NULL;
 
+fail6:
+    Error("fail6\n");
+
+fail5:
+    Error("fail5\n");
+
+    XENBUS_CACHE(Destroy,
+                 &Receiver->CacheInterface,
+                 Ring->FragmentCache);
+    Ring->FragmentCache = NULL;
+
+fail4:
+    Error("fail4\n");
+
+fail3:
+    Error("fail3\n");
+
+    XENBUS_CACHE(Destroy,
+                 &Receiver->CacheInterface,
+                 Ring->PacketCache);
+    Ring->PacketCache = NULL;
+
 fail2:
     Error("fail2\n");
 
@@ -2590,6 +2589,16 @@ __ReceiverRingDisconnect(
                   &Receiver->GnttabInterface,
                   Ring->GnttabCache);
     Ring->GnttabCache = NULL;
+
+    XENBUS_CACHE(Destroy,
+                 &Receiver->CacheInterface,
+                 Ring->FragmentCache);
+    Ring->FragmentCache = NULL;
+
+    XENBUS_CACHE(Destroy,
+                 &Receiver->CacheInterface,
+                 Ring->PacketCache);
+    Ring->PacketCache = NULL;
 }
 
 static FORCEINLINE VOID
@@ -2613,16 +2622,6 @@ __ReceiverRingTeardown(
     ThreadJoin(Ring->WatchdogThread);
     Ring->WatchdogThread = NULL;
 
-    XENBUS_CACHE(Destroy,
-                 &Receiver->CacheInterface,
-                 Ring->FragmentCache);
-    Ring->FragmentCache = NULL;
-
-    XENBUS_CACHE(Destroy,
-                 &Receiver->CacheInterface,
-                 Ring->PacketCache);
-    Ring->PacketCache = NULL;
-
     ASSERT(IsListEmpty(&Ring->PacketList));
     RtlZeroMemory(&Ring->PacketList, sizeof (LIST_ENTRY));
 
@@ -2778,17 +2777,13 @@ ReceiverInitialize(
 
     (*Receiver)->Frontend = Frontend;
 
-    status = XENBUS_CACHE(Acquire, &(*Receiver)->CacheInterface);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
     (*Receiver)->MaxQueues = FrontendGetMaxQueues(Frontend);
     (*Receiver)->Ring = __ReceiverAllocate(sizeof (PXENVIF_RECEIVER_RING) *
                                            (*Receiver)->MaxQueues);
 
     status = STATUS_NO_MEMORY;
     if ((*Receiver)->Ring == NULL)
-        goto fail3;
+        goto fail2;
 
     Index = 0;
     while (Index < (*Receiver)->MaxQueues) {
@@ -2796,7 +2791,7 @@ ReceiverInitialize(
 
         status = __ReceiverRingInitialize(*Receiver, Index, &Ring);
         if (!NT_SUCCESS(status))
-            goto fail4;
+            goto fail3;
 
         (*Receiver)->Ring[Index] = Ring;
         Index++;
@@ -2804,8 +2799,8 @@ ReceiverInitialize(
 
     return STATUS_SUCCESS;
 
-fail4:
-    Error("fail4\n");
+fail3:
+    Error("fail3\n");
 
     while (--Index >= 0) {
         PXENVIF_RECEIVER_RING   Ring = (*Receiver)->Ring[Index];
@@ -2815,18 +2810,13 @@ fail4:
     }
 
     __ReceiverFree((*Receiver)->Ring);
-    (*Receiver)->Ring = NULL;
-
-fail3:
-    Error("fail3\n");
-
-    (*Receiver)->MaxQueues = 0;
 
-    XENBUS_CACHE(Release, &(*Receiver)->CacheInterface);
+    (*Receiver)->Ring = NULL;
 
 fail2:
     Error("fail2\n");
 
+    (*Receiver)->MaxQueues = 0;
     (*Receiver)->Frontend = NULL;
 
     RtlZeroMemory(&(*Receiver)->EvtchnInterface,
@@ -2888,10 +2878,14 @@ ReceiverConnect(
     if (!NT_SUCCESS(status))
         goto fail3;
 
-    status = XENBUS_GNTTAB(Acquire, &Receiver->GnttabInterface);
+    status = XENBUS_CACHE(Acquire, &Receiver->CacheInterface);
     if (!NT_SUCCESS(status))
         goto fail4;
 
+    status = XENBUS_GNTTAB(Acquire, &Receiver->GnttabInterface);
+    if (!NT_SUCCESS(status))
+        goto fail5;
+
     status = XENBUS_STORE(Read,
                           &Receiver->StoreInterface,
                           NULL,
@@ -2917,7 +2911,7 @@ ReceiverConnect(
 
         status = __ReceiverRingConnect(Ring);
         if (!NT_SUCCESS(status))
-            goto fail5;
+            goto fail6;
 
         Index++;
     }    
@@ -2929,18 +2923,18 @@ ReceiverConnect(
                           Receiver,
                           &Receiver->DebugCallback);
     if (!NT_SUCCESS(status))
-        goto fail6;
+        goto fail7;
 
     Trace("<====\n");
     return STATUS_SUCCESS;
 
-fail6:
-    Error("fail6\n");
+fail7:
+    Error("fail7\n");
 
     Index = Receiver->NumQueues;
 
-fail5:
-    Error("fail5\n");
+fail6:
+    Error("fail6\n");
 
     while (--Index >= 0) {
         PXENVIF_RECEIVER_RING   Ring = Receiver->Ring[Index];
@@ -2952,6 +2946,11 @@ fail5:
 
     XENBUS_GNTTAB(Release, &Receiver->GnttabInterface);
 
+fail5:
+    Error("fail5\n");
+
+    XENBUS_CACHE(Release, &Receiver->CacheInterface);
+
 fail4:
     Error("fail4\n");
 
@@ -3230,6 +3229,8 @@ ReceiverDisconnect(
 
     XENBUS_GNTTAB(Release, &Receiver->GnttabInterface);
 
+    XENBUS_CACHE(Release, &Receiver->CacheInterface);
+
     XENBUS_EVTCHN(Release, &Receiver->EvtchnInterface);
 
     XENBUS_STORE(Release, &Receiver->StoreInterface);
@@ -3265,8 +3266,6 @@ ReceiverTeardown(
     Receiver->Ring = NULL;
     Receiver->MaxQueues = 0;
 
-    XENBUS_CACHE(Release, &Receiver->CacheInterface);
-
     Receiver->Frontend = NULL;
 
     RtlZeroMemory(&Receiver->EvtchnInterface,
diff --git a/src/xenvif/transmitter.c b/src/xenvif/transmitter.c
index 8759be1..5f84eb5 100644
--- a/src/xenvif/transmitter.c
+++ b/src/xenvif/transmitter.c
@@ -3020,7 +3020,6 @@ __TransmitterRingInitialize(
     )
 {
     PXENVIF_FRONTEND                Frontend;
-    CHAR                            Name[MAXNAMELEN];
     NTSTATUS                        status;
 
     Frontend = Transmitter->Frontend;
@@ -3044,12 +3043,66 @@ __TransmitterRingInitialize(
 
     KeInitializeDpc(&(*Ring)->Dpc, TransmitterRingDpc, *Ring);
 
+    status = ThreadCreate(TransmitterRingWatchdog,
+                          *Ring,
+                          &(*Ring)->WatchdogThread);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
+    return STATUS_SUCCESS;
+
+fail3:
+    Error("fail3\n");
+
+    RtlZeroMemory(&(*Ring)->Dpc, sizeof (KDPC));
+
+    RtlZeroMemory(&(*Ring)->PacketComplete, sizeof (LIST_ENTRY));
+    RtlZeroMemory(&(*Ring)->RequestQueue, sizeof (LIST_ENTRY));
+    RtlZeroMemory(&(*Ring)->PacketQueue, sizeof (LIST_ENTRY));
+
+    FrontendFreePath(Frontend, (*Ring)->Path);
+    (*Ring)->Path = NULL;
+
+fail2:
+    Error("fail2\n");
+
+    (*Ring)->Index = 0;
+    (*Ring)->Transmitter = NULL;
+
+    ASSERT(IsZeroMemory(*Ring, sizeof (XENVIF_TRANSMITTER_RING)));
+    __TransmitterFree(*Ring);
+    *Ring = NULL;
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;
+}
+
+static FORCEINLINE NTSTATUS
+__TransmitterRingConnect(
+    IN  PXENVIF_TRANSMITTER_RING    Ring
+    )
+{
+    PXENVIF_TRANSMITTER             Transmitter;
+    PXENVIF_FRONTEND                Frontend;
+    PFN_NUMBER                      Pfn;
+    CHAR                            Name[MAXNAMELEN];
+    ULONG                           Index;
+    PROCESSOR_NUMBER                ProcNumber;
+    NTSTATUS                        status;
+
+    ASSERT(!Ring->Connected);
+
+    Transmitter = Ring->Transmitter;
+    Frontend = Transmitter->Frontend;
+
     status = RtlStringCbPrintfA(Name,
                                 sizeof (Name),
                                 "%s_transmitter_buffer",
-                                (*Ring)->Path);
+                                Ring->Path);
     if (!NT_SUCCESS(status))
-        goto fail3;
+        goto fail1;
 
     for (Index = 0; Name[Index] != '\0'; Index++)
         if (Name[Index] == '/')
@@ -3064,17 +3117,17 @@ __TransmitterRingInitialize(
                           TransmitterBufferDtor,
                           TransmitterRingAcquireLock,
                           TransmitterRingReleaseLock,
-                          *Ring,
-                          &(*Ring)->BufferCache);
+                          Ring,
+                          &Ring->BufferCache);
     if (!NT_SUCCESS(status))
-        goto fail4;
+        goto fail2;
 
     status = RtlStringCbPrintfA(Name,
                                 sizeof (Name),
                                 "%s_transmitter_multicast_control",
-                                (*Ring)->Path);
+                                Ring->Path);
     if (!NT_SUCCESS(status))
-        goto fail5;
+        goto fail3;
 
     for (Index = 0; Name[Index] != '\0'; Index++)
         if (Name[Index] == '/')
@@ -3089,17 +3142,17 @@ __TransmitterRingInitialize(
                           TransmitterMulticastControlDtor,
                           TransmitterRingAcquireLock,
                           TransmitterRingReleaseLock,
-                          *Ring,
-                          &(*Ring)->MulticastControlCache);
+                          Ring,
+                          &Ring->MulticastControlCache);
     if (!NT_SUCCESS(status))
-        goto fail6;
+        goto fail4;
 
     status = RtlStringCbPrintfA(Name,
                                 sizeof (Name),
                                 "%s_transmitter_req_id",
-                                (*Ring)->Path);
+                                Ring->Path);
     if (!NT_SUCCESS(status))
-        goto fail7;
+        goto fail5;
 
     for (Index = 0; Name[Index] != '\0'; Index++)
         if (Name[Index] == '/')
@@ -3108,24 +3161,24 @@ __TransmitterRingInitialize(
     status = XENBUS_RANGE_SET(Create,
                               &Transmitter->RangeSetInterface,
                               Name,
-                              &(*Ring)->RangeSet);
+                              &Ring->RangeSet);
     if (!NT_SUCCESS(status))
-        goto fail8;
+        goto fail6;
 
     status = XENBUS_RANGE_SET(Put,
                               &Transmitter->RangeSetInterface,
-                              (*Ring)->RangeSet,
+                              Ring->RangeSet,
                               1,
                               XENVIF_TRANSMITTER_MAXIMUM_FRAGMENT_ID);
     if (!NT_SUCCESS(status))
-        goto fail9;
+        goto fail7;
 
     status = RtlStringCbPrintfA(Name,
                                 sizeof (Name),
                                 "%s_transmitter_fragment",
-                                (*Ring)->Path);
+                                Ring->Path);
     if (!NT_SUCCESS(status))
-        goto fail10;
+        goto fail8;
 
     for (Index = 0; Name[Index] != '\0'; Index++)
         if (Name[Index] == '/')
@@ -3140,17 +3193,17 @@ __TransmitterRingInitialize(
                           TransmitterFragmentDtor,
                           TransmitterRingAcquireLock,
                           TransmitterRingReleaseLock,
-                          *Ring,
-                          &(*Ring)->FragmentCache);
+                          Ring,
+                          &Ring->FragmentCache);
     if (!NT_SUCCESS(status))
-        goto fail11;
+        goto fail9;
 
     status = RtlStringCbPrintfA(Name,
                                 sizeof (Name),
                                 "%s_transmitter_request",
-                                (*Ring)->Path);
+                                Ring->Path);
     if (!NT_SUCCESS(status))
-        goto fail12;
+        goto fail10;
 
     for (Index = 0; Name[Index] != '\0'; Index++)
         if (Name[Index] == '/')
@@ -3165,135 +3218,17 @@ __TransmitterRingInitialize(
                           TransmitterRequestDtor,
                           TransmitterRingAcquireLock,
                           TransmitterRingReleaseLock,
-                          *Ring,
-                          &(*Ring)->RequestCache);
-    if (!NT_SUCCESS(status))
-        goto fail13;
-
-    status = ThreadCreate(TransmitterRingWatchdog,
-                          *Ring,
-                          &(*Ring)->WatchdogThread);
+                          Ring,
+                          &Ring->RequestCache);
     if (!NT_SUCCESS(status))
-        goto fail14;
-
-    return STATUS_SUCCESS;
-
-fail14:
-    Error("fail14\n");
-
-    XENBUS_CACHE(Destroy,
-                 &Transmitter->CacheInterface,
-                 (*Ring)->RequestCache);
-    (*Ring)->RequestCache = NULL;
-
-fail13:
-    Error("fail13\n");
-
-fail12:
-    Error("fail12\n");
-
-    XENBUS_CACHE(Destroy,
-                 &Transmitter->CacheInterface,
-                 (*Ring)->FragmentCache);
-    (*Ring)->FragmentCache = NULL;
-
-fail11:
-    Error("fail11\n");
-
-fail10:
-    Error("fail10\n");
-
-    (VOID) XENBUS_RANGE_SET(Get,
-                            &Transmitter->RangeSetInterface,
-                            (*Ring)->RangeSet,
-                            1,
-                            XENVIF_TRANSMITTER_MAXIMUM_FRAGMENT_ID);
-
-fail9:
-    Error("fail9\n");
-
-    XENBUS_RANGE_SET(Destroy,
-                     &Transmitter->RangeSetInterface,
-                     (*Ring)->RangeSet);
-    (*Ring)->RangeSet = NULL;
-
-fail8:
-    Error("fail8\n");
-
-fail7:
-    Error("fail7\n");
-
-    XENBUS_CACHE(Destroy,
-                 &Transmitter->CacheInterface,
-                 (*Ring)->MulticastControlCache);
-    (*Ring)->MulticastControlCache = NULL;
-
-fail6:
-    Error("fail6\n");
-
-fail5:
-    Error("fail5\n");
-
-    XENBUS_CACHE(Destroy,
-                 &Transmitter->CacheInterface,
-                 (*Ring)->BufferCache);
-    (*Ring)->BufferCache = NULL;
-
-fail4:
-    Error("fail4\n");
-
-fail3:
-    Error("fail3\n");
-
-    RtlZeroMemory(&(*Ring)->Dpc, sizeof (KDPC));
-
-    RtlZeroMemory(&(*Ring)->PacketComplete, sizeof (LIST_ENTRY));
-    RtlZeroMemory(&(*Ring)->RequestQueue, sizeof (LIST_ENTRY));
-    RtlZeroMemory(&(*Ring)->PacketQueue, sizeof (LIST_ENTRY));
-
-    FrontendFreePath(Frontend, (*Ring)->Path);
-    (*Ring)->Path = NULL;
-
-fail2:
-    Error("fail2\n");
-
-    (*Ring)->Index = 0;
-    (*Ring)->Transmitter = NULL;
-
-    ASSERT(IsZeroMemory(*Ring, sizeof (XENVIF_TRANSMITTER_RING)));
-    __TransmitterFree(*Ring);
-    *Ring = NULL;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return status;
-}
-
-static FORCEINLINE NTSTATUS
-__TransmitterRingConnect(
-    IN  PXENVIF_TRANSMITTER_RING    Ring
-    )
-{
-    PXENVIF_TRANSMITTER             Transmitter;
-    PXENVIF_FRONTEND                Frontend;
-    PFN_NUMBER                      Pfn;
-    CHAR                            Name[MAXNAMELEN];
-    ULONG                           Index;
-    PROCESSOR_NUMBER                ProcNumber;
-    NTSTATUS                        status;
-
-    ASSERT(!Ring->Connected);
-
-    Transmitter = Ring->Transmitter;
-    Frontend = Transmitter->Frontend;
+        goto fail11;
 
     status = RtlStringCbPrintfA(Name,
                                 sizeof (Name),
                                 "%s_transmitter",
                                 Ring->Path);
     if (!NT_SUCCESS(status))
-        goto fail1;
+        goto fail12;
 
     for (Index = 0; Name[Index] != '\0'; Index++)
         if (Name[Index] == '/')
@@ -3308,13 +3243,13 @@ __TransmitterRingConnect(
                            Ring,
                            &Ring->GnttabCache);
     if (!NT_SUCCESS(status))
-        goto fail2;
+        goto fail13;
 
     Ring->Mdl = __AllocatePage();
 
     status = STATUS_NO_MEMORY;
     if (Ring->Mdl == NULL)
-        goto fail3;
+        goto fail14;
 
     Ring->Shared = MmGetSystemAddressForMdlSafe(Ring->Mdl, NormalPagePriority);
     ASSERT(Ring->Shared != NULL);
@@ -3334,14 +3269,14 @@ __TransmitterRingConnect(
                            FALSE,
                            &Ring->Entry);
     if (!NT_SUCCESS(status))
-        goto fail4;
+        goto fail15;
 
     status = RtlStringCbPrintfA(Name,
                                 sizeof (Name),
                                 __MODULE__ "|TRANSMITTER[%u]",
                                 Ring->Index);
     if (!NT_SUCCESS(status))
-        goto fail5;
+        goto fail16;
 
     ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
 
@@ -3356,7 +3291,7 @@ __TransmitterRingConnect(
 
         status = STATUS_UNSUCCESSFUL;
         if (Ring->Channel == NULL)
-            goto fail6;
+            goto fail17;
 
         status = KeGetProcessorNumberFromIndex(Ring->Index, &ProcNumber);
         ASSERT(NT_SUCCESS(status));
@@ -3382,14 +3317,14 @@ __TransmitterRingConnect(
                           Ring,
                           &Ring->DebugCallback);
     if (!NT_SUCCESS(status))
-        goto fail7;
+        goto fail18;
 
     Ring->Connected = TRUE;
 
     return STATUS_SUCCESS;
 
-fail7:
-    Error("fail7\n");
+fail18:
+    Error("fail18\n");
 
     XENBUS_EVTCHN(Close,
                   &Transmitter->EvtchnInterface,
@@ -3398,11 +3333,11 @@ fail7:
 
     Ring->Events = 0;
 
-fail6:
-    Error("fail6\n");
+fail17:
+    Error("fail17\n");
 
-fail5:
-    Error("fail5\n");
+fail16:
+    Error("fail16\n");
 
     (VOID) XENBUS_GNTTAB(RevokeForeignAccess,
                          &Transmitter->GnttabInterface,
@@ -3411,8 +3346,8 @@ fail5:
                          Ring->Entry);
     Ring->Entry = NULL;
 
-fail4:
-    Error("fail4\n");
+fail15:
+    Error("fail15\n");
 
     RtlZeroMemory(&Ring->Front, sizeof (netif_tx_front_ring_t));
     RtlZeroMemory(Ring->Shared, PAGE_SIZE);
@@ -3421,14 +3356,78 @@ fail4:
     __FreePage(Ring->Mdl);
     Ring->Mdl = NULL;
 
-fail3:
-    Error("fail3\n");
+fail14:
+    Error("fail14\n");
 
     XENBUS_GNTTAB(DestroyCache,
                   &Transmitter->GnttabInterface,
                   Ring->GnttabCache);
     Ring->GnttabCache = NULL;
 
+fail13:
+    Error("fail13\n");
+
+fail12:
+    Error("fail12\n");
+
+    XENBUS_CACHE(Destroy,
+                 &Transmitter->CacheInterface,
+                 Ring->RequestCache);
+    Ring->RequestCache = NULL;
+
+fail11:
+    Error("fail11\n");
+
+fail10:
+    Error("fail10\n");
+
+    XENBUS_CACHE(Destroy,
+                 &Transmitter->CacheInterface,
+                 Ring->FragmentCache);
+    Ring->FragmentCache = NULL;
+
+fail9:
+    Error("fail9\n");
+
+fail8:
+    Error("fail8\n");
+
+    (VOID) XENBUS_RANGE_SET(Get,
+                            &Transmitter->RangeSetInterface,
+                            Ring->RangeSet,
+                            1,
+                            XENVIF_TRANSMITTER_MAXIMUM_FRAGMENT_ID);
+
+fail7:
+    Error("fail7\n");
+
+    XENBUS_RANGE_SET(Destroy,
+                     &Transmitter->RangeSetInterface,
+                     Ring->RangeSet);
+    Ring->RangeSet = NULL;
+
+fail6:
+    Error("fail6\n");
+
+fail5:
+    Error("fail5\n");
+
+    XENBUS_CACHE(Destroy,
+                 &Transmitter->CacheInterface,
+                 Ring->MulticastControlCache);
+    Ring->MulticastControlCache = NULL;
+
+fail4:
+    Error("fail4\n");
+
+fail3:
+    Error("fail3\n");
+
+    XENBUS_CACHE(Destroy,
+                 &Transmitter->CacheInterface,
+                 Ring->BufferCache);
+    Ring->BufferCache = NULL;
+
 fail2:
     Error("fail2\n");
 
@@ -3660,6 +3659,37 @@ __TransmitterRingDisconnect(
                   &Transmitter->GnttabInterface,
                   Ring->GnttabCache);
     Ring->GnttabCache = NULL;
+
+    XENBUS_CACHE(Destroy,
+                 &Transmitter->CacheInterface,
+                 Ring->RequestCache);
+    Ring->RequestCache = NULL;
+
+    XENBUS_CACHE(Destroy,
+                 &Transmitter->CacheInterface,
+                 Ring->FragmentCache);
+    Ring->FragmentCache = NULL;
+
+    (VOID) XENBUS_RANGE_SET(Get,
+                            &Transmitter->RangeSetInterface,
+                            Ring->RangeSet,
+                            1,
+                            XENVIF_TRANSMITTER_MAXIMUM_FRAGMENT_ID);
+
+    XENBUS_RANGE_SET(Destroy,
+                     &Transmitter->RangeSetInterface,
+                     Ring->RangeSet);
+    Ring->RangeSet = NULL;
+
+    XENBUS_CACHE(Destroy,
+                 &Transmitter->CacheInterface,
+                 Ring->MulticastControlCache);
+    Ring->MulticastControlCache = NULL;
+
+    XENBUS_CACHE(Destroy,
+                 &Transmitter->CacheInterface,
+                 Ring->BufferCache);
+    Ring->BufferCache = NULL;
 }
 
 static FORCEINLINE VOID
@@ -3694,37 +3724,6 @@ __TransmitterRingTeardown(
     ThreadJoin(Ring->WatchdogThread);
     Ring->WatchdogThread = NULL;
 
-    XENBUS_CACHE(Destroy,
-                 &Transmitter->CacheInterface,
-                 Ring->RequestCache);
-    Ring->RequestCache = NULL;
-
-    XENBUS_CACHE(Destroy,
-                 &Transmitter->CacheInterface,
-                 Ring->FragmentCache);
-    Ring->FragmentCache = NULL;
-
-    (VOID) XENBUS_RANGE_SET(Get,
-                            &Transmitter->RangeSetInterface,
-                            Ring->RangeSet,
-                            1,
-                            XENVIF_TRANSMITTER_MAXIMUM_FRAGMENT_ID);
-
-    XENBUS_RANGE_SET(Destroy,
-                     &Transmitter->RangeSetInterface,
-                     Ring->RangeSet);
-    Ring->RangeSet = NULL;
-
-    XENBUS_CACHE(Destroy,
-                 &Transmitter->CacheInterface,
-                 Ring->MulticastControlCache);
-    Ring->MulticastControlCache = NULL;
-
-    XENBUS_CACHE(Destroy,
-                 &Transmitter->CacheInterface,
-                 Ring->BufferCache);
-    Ring->BufferCache = NULL;
-
     ASSERT(IsListEmpty(&Ring->PacketComplete));
     RtlZeroMemory(&Ring->PacketComplete, sizeof (LIST_ENTRY));
 
@@ -4049,21 +4048,13 @@ TransmitterInitialize(
     (*Transmitter)->Frontend = Frontend;
     KeInitializeSpinLock(&(*Transmitter)->Lock);
 
-    status = XENBUS_RANGE_SET(Acquire, &(*Transmitter)->RangeSetInterface);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    status = XENBUS_CACHE(Acquire, &(*Transmitter)->CacheInterface);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-
     (*Transmitter)->MaxQueues = FrontendGetMaxQueues(Frontend);
     (*Transmitter)->Ring = __TransmitterAllocate(sizeof 
(PXENVIF_TRANSMITTER_RING) *
                                                  (*Transmitter)->MaxQueues);
 
     status = STATUS_NO_MEMORY;
     if ((*Transmitter)->Ring == NULL)
-        goto fail4;
+        goto fail2;
 
     Index = 0;
     while (Index < (*Transmitter)->MaxQueues) {
@@ -4071,7 +4062,7 @@ TransmitterInitialize(
 
         status = __TransmitterRingInitialize(*Transmitter, Index, &Ring);
         if (!NT_SUCCESS(status))
-            goto fail5;
+            goto fail3;
 
         (*Transmitter)->Ring[Index] = Ring;
         Index++;
@@ -4079,8 +4070,8 @@ TransmitterInitialize(
 
     return STATUS_SUCCESS;
 
-fail5:
-    Error("fail5\n");
+fail3:
+    Error("fail3\n");
 
     while (--Index > 0) {
         PXENVIF_TRANSMITTER_RING    Ring = (*Transmitter)->Ring[Index];
@@ -4092,21 +4083,11 @@ fail5:
     __TransmitterFree((*Transmitter)->Ring);
     (*Transmitter)->Ring = NULL;
 
-fail4:
-    Error("fail4\n");
-
-    (*Transmitter)->MaxQueues = 0;
-
-    XENBUS_CACHE(Release, &(*Transmitter)->CacheInterface);
-
-fail3:
-    Error("fail3\n");
-
-    XENBUS_RANGE_SET(Release, &(*Transmitter)->RangeSetInterface);
-
 fail2:
     Error("fail2\n");
 
+    (*Transmitter)->MaxQueues = 0;
+
     (*Transmitter)->Frontend = NULL;
 
     RtlZeroMemory(&(*Transmitter)->Lock,
@@ -4167,16 +4148,24 @@ TransmitterConnect(
     if (!NT_SUCCESS(status))
         goto fail3;
 
-    status = XENBUS_GNTTAB(Acquire, &Transmitter->GnttabInterface);
+    status = XENBUS_RANGE_SET(Acquire, &Transmitter->RangeSetInterface);
     if (!NT_SUCCESS(status))
         goto fail4;
 
+    status = XENBUS_CACHE(Acquire, &Transmitter->CacheInterface);
+    if (!NT_SUCCESS(status))
+        goto fail5;
+
+    status = XENBUS_GNTTAB(Acquire, &Transmitter->GnttabInterface);
+    if (!NT_SUCCESS(status))
+        goto fail6;
+
     status = RtlStringCbPrintfA(Name,
                                 sizeof (Name),
                                 "%s_transmitter_packet",
                                 FrontendGetPath(Frontend));
     if (!NT_SUCCESS(status))
-        goto fail5;
+        goto fail7;
 
     for (Index = 0; Name[Index] != '\0'; Index++)
         if (Name[Index] == '/')
@@ -4194,7 +4183,7 @@ TransmitterConnect(
                           Transmitter,
                           &Transmitter->PacketCache);
     if (!NT_SUCCESS(status))
-        goto fail6;
+        goto fail8;
 
     status = XENBUS_STORE(Read,
                           &Transmitter->StoreInterface,
@@ -4237,7 +4226,7 @@ TransmitterConnect(
 
         status = __TransmitterRingConnect(Ring);
         if (!NT_SUCCESS(status))
-            goto fail7;
+            goto fail9;
 
         Index++;
     }    
@@ -4249,18 +4238,18 @@ TransmitterConnect(
                           Transmitter,
                           &Transmitter->DebugCallback);
     if (!NT_SUCCESS(status))
-        goto fail8;
+        goto fail10;
 
     Trace("<====\n");
     return STATUS_SUCCESS;
 
-fail8:
-    Error("fail8\n");
+fail10:
+    Error("fail10\n");
 
     Index = Transmitter->NumQueues;
 
-fail7:
-    Error("fail7\n");
+fail9:
+    Error("fail9\n");
 
     while (--Index >= 0) {
         PXENVIF_TRANSMITTER_RING    Ring;
@@ -4277,13 +4266,23 @@ fail7:
                  Transmitter->PacketCache);
     Transmitter->PacketCache = NULL;
 
+fail8:
+    Error("fail8\n");
+
+fail7:
+    Error("fail7\n");
+
+    XENBUS_GNTTAB(Release, &Transmitter->GnttabInterface);
+
 fail6:
     Error("fail6\n");
 
+    XENBUS_CACHE(Release, &Transmitter->CacheInterface);
+
 fail5:
     Error("fail5\n");
 
-    XENBUS_GNTTAB(Release, &Transmitter->GnttabInterface);
+    XENBUS_RANGE_SET(Release, &Transmitter->RangeSetInterface);
 
 fail4:
     Error("fail4\n");
@@ -4426,6 +4425,10 @@ TransmitterDisconnect(
 
     XENBUS_GNTTAB(Release, &Transmitter->GnttabInterface);
 
+    XENBUS_CACHE(Release, &Transmitter->CacheInterface);
+
+    XENBUS_RANGE_SET(Release, &Transmitter->RangeSetInterface);
+
     XENBUS_EVTCHN(Release, &Transmitter->EvtchnInterface);
 
     XENBUS_STORE(Release, &Transmitter->StoreInterface);
@@ -4457,10 +4460,6 @@ TransmitterTeardown(
     Transmitter->Ring = NULL;
     Transmitter->MaxQueues = 0;
 
-    XENBUS_CACHE(Release, &Transmitter->CacheInterface);
-
-    XENBUS_RANGE_SET(Release, &Transmitter->RangeSetInterface);
-
     Transmitter->Frontend = NULL;
 
     RtlZeroMemory(&Transmitter->Lock,
diff --git a/src/xenvif/vif.c b/src/xenvif/vif.c
index 556280b..ac4d454 100644
--- a/src/xenvif/vif.c
+++ b/src/xenvif/vif.c
@@ -115,6 +115,26 @@ VifMac(
     return STATUS_SUCCESS;
 }
 
+static DECLSPEC_NOINLINE VOID
+VifSuspendCallbackLate(
+    IN  PVOID           Argument
+    )
+{
+    PXENVIF_VIF_CONTEXT Context = Argument;
+    NTSTATUS            status;
+
+    if (!Context->Enabled)
+        return;
+
+    status = FrontendSetState(Context->Frontend, FRONTEND_ENABLED);
+    ASSERT(NT_SUCCESS(status));
+
+    // We do this three times to make sure switches take note
+    FrontendAdvertiseIpAddresses(Context->Frontend);
+    FrontendAdvertiseIpAddresses(Context->Frontend);
+    FrontendAdvertiseIpAddresses(Context->Frontend);
+}
+
 static NTSTATUS
 VifEnable(
     IN  PINTERFACE          Interface,
@@ -124,11 +144,13 @@ VifEnable(
 {
     PXENVIF_VIF_CONTEXT     Context = Interface->Context;
     KIRQL                   Irql;
+    BOOLEAN                 Exclusive;
     NTSTATUS                status;
 
     Trace("====>\n");
 
     AcquireMrswLockExclusive(&Context->Lock, &Irql);
+    Exclusive = TRUE;
 
     if (Context->Enabled)
         goto done;
@@ -140,24 +162,74 @@ VifEnable(
 
     KeMemoryBarrier();
 
-    status = FrontendSetState(Context->Frontend, FRONTEND_ENABLED);
+    status = XENBUS_SUSPEND(Acquire, &Context->SuspendInterface);
     if (!NT_SUCCESS(status))
         goto fail1;
 
+    status = FrontendSetState(Context->Frontend, FRONTEND_ENABLED);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    status = XENBUS_SUSPEND(Register,
+                            &Context->SuspendInterface,
+                            SUSPEND_CALLBACK_LATE,
+                            VifSuspendCallbackLate,
+                            Context,
+                            &Context->SuspendCallbackLate);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
 done:
+    ASSERT(Exclusive);
     ReleaseMrswLockExclusive(&Context->Lock, Irql, FALSE);
 
     Trace("<====\n");
 
     return STATUS_SUCCESS;
 
+fail3:
+    Error("fail3\n");
+
+    (VOID) FrontendSetState(Context->Frontend, FRONTEND_CONNECTED);
+
+    ReleaseMrswLockExclusive(&Context->Lock, Irql, TRUE);
+    Exclusive = FALSE;
+
+    ReceiverWaitForPackets(FrontendGetReceiver(Context->Frontend));
+    TransmitterAbortPackets(FrontendGetTransmitter(Context->Frontend));
+
+    Trace("waiting for mac thread..\n");
+
+    KeClearEvent(&Context->MacEvent);
+    ThreadWake(Context->MacThread);
+
+    (VOID) KeWaitForSingleObject(&Context->MacEvent,
+                                 Executive,
+                                 KernelMode,
+                                 FALSE,
+                                 NULL);
+
+    Trace("done\n");
+
+fail2:
+    Error("fail2\n");
+
+    XENBUS_SUSPEND(Release, &Context->SuspendInterface);
+
 fail1:
     Error("fail1 (%08x)\n", status);
 
+    Context->Enabled = FALSE;
+
+    KeMemoryBarrier();
+
     Context->Argument = NULL;
     Context->Callback = NULL;
 
-    ReleaseMrswLockExclusive(&Context->Lock, Irql, FALSE);
+    if (Exclusive)
+        ReleaseMrswLockExclusive(&Context->Lock, Irql, FALSE);
+    else
+        ReleaseMrswLockShared(&Context->Lock);
 
     return status;
 }
@@ -183,6 +255,11 @@ VifDisable(
 
     KeMemoryBarrier();
 
+    XENBUS_SUSPEND(Deregister,
+                   &Context->SuspendInterface,
+                   Context->SuspendCallbackLate);
+    Context->SuspendCallbackLate = NULL;
+
     (VOID) FrontendSetState(Context->Frontend, FRONTEND_CONNECTED);
 
     ReleaseMrswLockExclusive(&Context->Lock, Irql, TRUE);
@@ -203,6 +280,8 @@ VifDisable(
 
     Trace("done\n");
 
+    XENBUS_SUSPEND(Release, &Context->SuspendInterface);
+
     Context->Argument = NULL;
     Context->Callback = NULL;
 
@@ -557,26 +636,6 @@ VifTransmitterQueryRingSize(
     ReleaseMrswLockShared(&Context->Lock);
 }
 
-static DECLSPEC_NOINLINE VOID
-VifSuspendCallbackLate(
-    IN  PVOID           Argument
-    )
-{
-    PXENVIF_VIF_CONTEXT Context = Argument;
-    NTSTATUS            status;
-
-    if (!Context->Enabled)
-        return;
-
-    status = FrontendSetState(Context->Frontend, FRONTEND_ENABLED);
-    ASSERT(NT_SUCCESS(status));
-
-    // We do this three times to make sure switches take note
-    FrontendAdvertiseIpAddresses(Context->Frontend);
-    FrontendAdvertiseIpAddresses(Context->Frontend);
-    FrontendAdvertiseIpAddresses(Context->Frontend);
-}
-
 static NTSTATUS
 VifAcquire(
     PINTERFACE              Interface
@@ -584,7 +643,6 @@ VifAcquire(
 {
     PXENVIF_VIF_CONTEXT     Context = Interface->Context;
     KIRQL                   Irql;
-    NTSTATUS                status;
 
     AcquireMrswLockExclusive(&Context->Lock, &Irql);
 
@@ -593,19 +651,6 @@ VifAcquire(
 
     Trace("====>\n");
 
-    status = XENBUS_SUSPEND(Acquire, &Context->SuspendInterface);
-    if (!NT_SUCCESS(status))
-        goto fail1;   
-
-    status = XENBUS_SUSPEND(Register,
-                            &Context->SuspendInterface,
-                            SUSPEND_CALLBACK_LATE,
-                            VifSuspendCallbackLate,
-                            Context,
-                            &Context->SuspendCallbackLate);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
     Context->Frontend = PdoGetFrontend(Context->Pdo);
 
     Trace("<====\n");
@@ -614,20 +659,6 @@ done:
     ReleaseMrswLockExclusive(&Context->Lock, Irql, FALSE);
 
     return STATUS_SUCCESS;
-
-fail2:
-    Error("fail2\n");
-
-    XENBUS_SUSPEND(Release, &Context->SuspendInterface);
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    --Context->References;
-    ASSERT3U(Context->References, ==, 0);
-    ReleaseMrswLockExclusive(&Context->Lock, Irql, FALSE);
-
-    return status;
 }
 
 VOID
@@ -649,13 +680,6 @@ VifRelease(
 
     Context->Frontend = NULL;
 
-    XENBUS_SUSPEND(Deregister,
-                   &Context->SuspendInterface,
-                   Context->SuspendCallbackLate);
-    Context->SuspendCallbackLate = NULL;
-
-    XENBUS_SUSPEND(Release, &Context->SuspendInterface);
-
     Trace("<====\n");
 
 done:
-- 
2.1.1


_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
http://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®.