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

[win-pv-devel] [PATCH] Partially revert commit ab655bb1 "Make sure XENBUS interfaces...



...are released when going into S4".

Not all interfaces need to be released (since they don't all depend on
Xen) and crucially the receiver packet caches CANNOT be destroyed (and
hence the CACHE interface CANNOT be released) because there may be packets
outstanding in the stack... not necessarily in an S4 transtion, but
across a suspend/resume (which involves the same frontend state
transitions).

This patch also increases the log level of a couple of messages
emitted during frontend state transtions from 'trace' to 'info'.

Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
---
 src/xenvif/frontend.c    |  16 +-
 src/xenvif/receiver.c    | 258 +++++++++++++-------------
 src/xenvif/transmitter.c | 459 +++++++++++++++++++++++------------------------
 3 files changed, 371 insertions(+), 362 deletions(-)

diff --git a/src/xenvif/frontend.c b/src/xenvif/frontend.c
index f6570e8..b443a35 100644
--- a/src/xenvif/frontend.c
+++ b/src/xenvif/frontend.c
@@ -2458,10 +2458,10 @@ FrontendSetState(
 
     KeAcquireSpinLock(&Frontend->Lock, &Irql);
 
-    Trace("%s: ====> '%s' -> '%s'\n",
-          __FrontendGetPath(Frontend),
-          FrontendStateName(Frontend->State),
-          FrontendStateName(State));
+    Info("%s: ====> '%s' -> '%s'\n",
+         __FrontendGetPath(Frontend),
+         FrontendStateName(Frontend->State),
+         FrontendStateName(State));
 
     Failed = FALSE;
     while (Frontend->State != State && !Failed) {
@@ -2589,14 +2589,14 @@ FrontendSetState(
             break;
         }
 
-        Trace("%s in state '%s'\n",
-              __FrontendGetPath(Frontend),
-              FrontendStateName(Frontend->State));
+        Info("%s in state '%s'\n",
+             __FrontendGetPath(Frontend),
+             FrontendStateName(Frontend->State));
     }
 
     KeReleaseSpinLock(&Frontend->Lock, Irql);
 
-    Trace("%s: <=====\n", __FrontendGetPath(Frontend));
+    Info("%s: <=====\n", __FrontendGetPath(Frontend));
 
     return (!Failed) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
 }
diff --git a/src/xenvif/receiver.c b/src/xenvif/receiver.c
index 196a4c1..8562259 100644
--- a/src/xenvif/receiver.c
+++ b/src/xenvif/receiver.c
@@ -249,6 +249,7 @@ __ReceiverRingGetPacket(
                           Locked);
 
     ASSERT(IsZeroMemory(&Packet->Info, sizeof (XENVIF_PACKET_INFO)));
+    ASSERT3P(Packet->Ring, ==, Ring);
 
     return Packet;
 }
@@ -267,6 +268,7 @@ __ReceiverRingPutPacket(
     Receiver = Ring->Receiver;
     Frontend = Receiver->Frontend;
 
+    ASSERT3P(Packet->Ring, ==, Ring);
     ASSERT(IsZeroMemory(&Packet->ListEntry, sizeof (LIST_ENTRY)));
 
     Packet->Offset = 0;
@@ -2362,6 +2364,7 @@ __ReceiverRingInitialize(
     )
 {
     PXENVIF_FRONTEND            Frontend;
+    CHAR                        Name[MAXNAMELEN];
     NTSTATUS                    status;
 
     Frontend = Receiver->Frontend;
@@ -2387,14 +2390,86 @@ __ReceiverRingInitialize(
     KeInitializeTimer(&(*Ring)->Timer);
     KeInitializeDpc(&(*Ring)->TimerDpc, 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 fail3;
+        goto fail7;
 
     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");
 
@@ -2443,60 +2518,10 @@ __ReceiverRingConnect(
 
     status = RtlStringCbPrintfA(Name,
                                 sizeof (Name),
-                                "%s_receiver_packet",
-                                Ring->Path);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    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 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;
+        goto fail1;
 
     for (Index = 0; Name[Index] != '\0'; Index++)
         if (Name[Index] == '/')
@@ -2511,13 +2536,13 @@ __ReceiverRingConnect(
                            Ring,
                            &Ring->GnttabCache);
     if (!NT_SUCCESS(status))
-        goto fail6;
+        goto fail2;
 
     Ring->Mdl = __AllocatePage();
 
     status = STATUS_NO_MEMORY;
     if (Ring->Mdl == NULL)
-        goto fail7;
+        goto fail3;
 
     Ring->Shared = MmGetSystemAddressForMdlSafe(Ring->Mdl, NormalPagePriority);
     ASSERT(Ring->Shared != NULL);
@@ -2537,14 +2562,14 @@ __ReceiverRingConnect(
                            FALSE,
                            &Ring->Entry);
     if (!NT_SUCCESS(status))
-        goto fail8;
+        goto fail4;
 
     status = RtlStringCbPrintfA(Name,
                                 sizeof (Name),
                                 __MODULE__ "|RECEIVER[%u]",
                                 Ring->Index);
     if (!NT_SUCCESS(status))
-        goto fail9;
+        goto fail5;
 
     ASSERT(!Ring->Connected);
 
@@ -2558,7 +2583,7 @@ __ReceiverRingConnect(
 
     status = STATUS_UNSUCCESSFUL;
     if (Ring->Channel == NULL)
-        goto fail10;
+        goto fail6;
 
     status = KeGetProcessorNumberFromIndex(Ring->Index, &ProcNumber);
     ASSERT(NT_SUCCESS(status));
@@ -2586,12 +2611,12 @@ __ReceiverRingConnect(
                           Ring,
                           &Ring->DebugCallback);
     if (!NT_SUCCESS(status))
-        goto fail11;
+        goto fail7;
 
     return STATUS_SUCCESS;
 
-fail11:
-    Error("fail11\n");
+fail7:
+    Error("fail7\n");
 
     Ring->Connected = FALSE;
 
@@ -2602,11 +2627,11 @@ fail11:
 
     Ring->Events = 0;
 
-fail10:
-    Error("fail10\n");
+fail6:
+    Error("fail6\n");
 
-fail9:
-    Error("fail9\n");
+fail5:
+    Error("fail5\n");
 
     (VOID) XENBUS_GNTTAB(RevokeForeignAccess,
                          &Receiver->GnttabInterface,
@@ -2615,8 +2640,8 @@ fail9:
                          Ring->Entry);
     Ring->Entry = NULL;
 
-fail8:
-    Error("fail8\n");
+fail4:
+    Error("fail4\n");
 
     RtlZeroMemory(&Ring->Front, sizeof (netif_rx_front_ring_t));
     RtlZeroMemory(Ring->Shared, PAGE_SIZE);
@@ -2625,36 +2650,14 @@ fail8:
     __FreePage(Ring->Mdl);
     Ring->Mdl = NULL;
 
-fail7:
-    Error("fail7\n");
+fail3:
+    Error("fail3\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");
 
@@ -2833,16 +2836,6 @@ __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
@@ -2868,6 +2861,16 @@ __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));
 
@@ -3024,13 +3027,17 @@ ReceiverInitialize(
 
     (*Receiver)->Frontend = Frontend;
 
+    status = XENBUS_CACHE(Acquire, &(*Receiver)->CacheInterface);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
     MaxQueues = FrontendGetMaxQueues(Frontend);
     (*Receiver)->Ring = __ReceiverAllocate(sizeof (PXENVIF_RECEIVER_RING) *
                                            MaxQueues);
 
     status = STATUS_NO_MEMORY;
     if ((*Receiver)->Ring == NULL)
-        goto fail2;
+        goto fail3;
 
     Index = 0;
     while (Index < MaxQueues) {
@@ -3038,7 +3045,7 @@ ReceiverInitialize(
 
         status = __ReceiverRingInitialize(*Receiver, Index, &Ring);
         if (!NT_SUCCESS(status))
-            goto fail3;
+            goto fail4;
 
         (*Receiver)->Ring[Index] = Ring;
         Index++;
@@ -3046,8 +3053,8 @@ ReceiverInitialize(
 
     return STATUS_SUCCESS;
 
-fail3:
-    Error("fail3\n");
+fail4:
+    Error("fail4\n");
 
     while (--Index >= 0) {
         PXENVIF_RECEIVER_RING   Ring = (*Receiver)->Ring[Index];
@@ -3060,6 +3067,11 @@ fail3:
 
     (*Receiver)->Ring = NULL;
 
+fail3:
+    Error("fail3\n");
+
+    XENBUS_CACHE(Release, &(*Receiver)->CacheInterface);
+
 fail2:
     Error("fail2\n");
 
@@ -3123,13 +3135,9 @@ ReceiverConnect(
     if (!NT_SUCCESS(status))
         goto fail3;
 
-    status = XENBUS_CACHE(Acquire, &Receiver->CacheInterface);
-    if (!NT_SUCCESS(status))
-        goto fail4;
-
     status = XENBUS_GNTTAB(Acquire, &Receiver->GnttabInterface);
     if (!NT_SUCCESS(status))
-        goto fail5;
+        goto fail4;
 
     Index = 0;
     while (Index < (LONG)FrontendGetNumQueues(Frontend)) {
@@ -3137,7 +3145,7 @@ ReceiverConnect(
 
         status = __ReceiverRingConnect(Ring);
         if (!NT_SUCCESS(status))
-            goto fail6;
+            goto fail5;
 
         Index++;
     }    
@@ -3149,18 +3157,18 @@ ReceiverConnect(
                           Receiver,
                           &Receiver->DebugCallback);
     if (!NT_SUCCESS(status))
-        goto fail7;
+        goto fail6;
 
     Trace("<====\n");
     return STATUS_SUCCESS;
 
-fail7:
-    Error("fail7\n");
+fail6:
+    Error("fail6\n");
 
     Index = FrontendGetNumQueues(Frontend);
 
-fail6:
-    Error("fail6\n");
+fail5:
+    Error("fail5\n");
 
     while (--Index >= 0) {
         PXENVIF_RECEIVER_RING   Ring = Receiver->Ring[Index];
@@ -3170,11 +3178,6 @@ fail6:
 
     XENBUS_GNTTAB(Release, &Receiver->GnttabInterface);
 
-fail5:
-    Error("fail5\n");
-
-    XENBUS_CACHE(Release, &Receiver->CacheInterface);
-
 fail4:
     Error("fail4\n");
 
@@ -3467,8 +3470,6 @@ ReceiverDisconnect(
 
     XENBUS_GNTTAB(Release, &Receiver->GnttabInterface);
 
-    XENBUS_CACHE(Release, &Receiver->CacheInterface);
-
     XENBUS_EVTCHN(Release, &Receiver->EvtchnInterface);
 
     XENBUS_STORE(Release, &Receiver->StoreInterface);
@@ -3506,6 +3507,8 @@ ReceiverTeardown(
     __ReceiverFree(Receiver->Ring);
     Receiver->Ring = NULL;
 
+    XENBUS_CACHE(Release, &Receiver->CacheInterface);
+
     Receiver->Frontend = NULL;
 
     RtlZeroMemory(&Receiver->EvtchnInterface,
@@ -3618,6 +3621,8 @@ ReceiverReturnPacket(
 
     __ReceiverRingReturnPacket(Ring, Packet, FALSE);
 
+    KeMemoryBarrier();
+
     Returned = InterlockedIncrement(&Receiver->Returned);
 
     // Make sure Loaned is not sampled before Returned
@@ -3646,7 +3651,7 @@ ReceiverWaitForPackets(
 
     Frontend = Receiver->Frontend;
 
-    Info("%s: ====>\n", FrontendGetPath(Frontend));
+    Trace("%s: ====>\n", FrontendGetPath(Frontend));
 
     Returned = Receiver->Returned;
 
@@ -3677,7 +3682,12 @@ ReceiverWaitForPackets(
         ASSERT3S(Loaned, ==, Receiver->Loaned);
     }
 
-    Info("%s: <====\n", FrontendGetPath(Frontend));
+    Info("%s: (Loaned = %d Returned = %d)\n",
+         FrontendGetPath(Frontend),
+         Loaned,
+         Returned);
+
+    Trace("%s: <====\n", FrontendGetPath(Frontend));
 }
 
 VOID
diff --git a/src/xenvif/transmitter.c b/src/xenvif/transmitter.c
index 1fbe766..1c88c51 100644
--- a/src/xenvif/transmitter.c
+++ b/src/xenvif/transmitter.c
@@ -3422,6 +3422,7 @@ __TransmitterRingInitialize(
     )
 {
     PXENVIF_FRONTEND                Frontend;
+    CHAR                            Name[MAXNAMELEN];
     NTSTATUS                        status;
 
     Frontend = Transmitter->Frontend;
@@ -3447,68 +3448,12 @@ __TransmitterRingInitialize(
     KeInitializeTimer(&(*Ring)->Timer);
     KeInitializeDpc(&(*Ring)->TimerDpc, TransmitterRingDpc, *Ring);
 
-    status = ThreadCreate(TransmitterRingWatchdog,
-                          *Ring,
-                          &(*Ring)->WatchdogThread);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-
-    return STATUS_SUCCESS;
-
-fail3:
-    Error("fail3\n");
-
-    RtlZeroMemory(&(*Ring)->TimerDpc, sizeof (KDPC));
-    RtlZeroMemory(&(*Ring)->Timer, sizeof (KTIMER));
-    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 fail1;
+        goto fail3;
 
     for (Index = 0; Name[Index] != '\0'; Index++)
         if (Name[Index] == '/')
@@ -3523,17 +3468,17 @@ __TransmitterRingConnect(
                           TransmitterBufferDtor,
                           TransmitterRingAcquireLock,
                           TransmitterRingReleaseLock,
-                          Ring,
-                          &Ring->BufferCache);
+                          *Ring,
+                          &(*Ring)->BufferCache);
     if (!NT_SUCCESS(status))
-        goto fail2;
+        goto fail4;
 
     status = RtlStringCbPrintfA(Name,
                                 sizeof (Name),
                                 "%s_transmitter_multicast_control",
-                                Ring->Path);
+                                (*Ring)->Path);
     if (!NT_SUCCESS(status))
-        goto fail3;
+        goto fail5;
 
     for (Index = 0; Name[Index] != '\0'; Index++)
         if (Name[Index] == '/')
@@ -3548,17 +3493,17 @@ __TransmitterRingConnect(
                           TransmitterMulticastControlDtor,
                           TransmitterRingAcquireLock,
                           TransmitterRingReleaseLock,
-                          Ring,
-                          &Ring->MulticastControlCache);
+                          *Ring,
+                          &(*Ring)->MulticastControlCache);
     if (!NT_SUCCESS(status))
-        goto fail4;
+        goto fail6;
 
     status = RtlStringCbPrintfA(Name,
                                 sizeof (Name),
                                 "%s_transmitter_req_id",
-                                Ring->Path);
+                                (*Ring)->Path);
     if (!NT_SUCCESS(status))
-        goto fail5;
+        goto fail7;
 
     for (Index = 0; Name[Index] != '\0'; Index++)
         if (Name[Index] == '/')
@@ -3567,24 +3512,24 @@ __TransmitterRingConnect(
     status = XENBUS_RANGE_SET(Create,
                               &Transmitter->RangeSetInterface,
                               Name,
-                              &Ring->RangeSet);
+                              &(*Ring)->RangeSet);
     if (!NT_SUCCESS(status))
-        goto fail6;
+        goto fail8;
 
     status = XENBUS_RANGE_SET(Put,
                               &Transmitter->RangeSetInterface,
-                              Ring->RangeSet,
+                              (*Ring)->RangeSet,
                               1,
                               XENVIF_TRANSMITTER_MAXIMUM_FRAGMENT_ID);
     if (!NT_SUCCESS(status))
-        goto fail7;
+        goto fail9;
 
     status = RtlStringCbPrintfA(Name,
                                 sizeof (Name),
                                 "%s_transmitter_fragment",
-                                Ring->Path);
+                                (*Ring)->Path);
     if (!NT_SUCCESS(status))
-        goto fail8;
+        goto fail10;
 
     for (Index = 0; Name[Index] != '\0'; Index++)
         if (Name[Index] == '/')
@@ -3599,17 +3544,17 @@ __TransmitterRingConnect(
                           TransmitterFragmentDtor,
                           TransmitterRingAcquireLock,
                           TransmitterRingReleaseLock,
-                          Ring,
-                          &Ring->FragmentCache);
+                          *Ring,
+                          &(*Ring)->FragmentCache);
     if (!NT_SUCCESS(status))
-        goto fail9;
+        goto fail11;
 
     status = RtlStringCbPrintfA(Name,
                                 sizeof (Name),
                                 "%s_transmitter_request",
-                                Ring->Path);
+                                (*Ring)->Path);
     if (!NT_SUCCESS(status))
-        goto fail10;
+        goto fail12;
 
     for (Index = 0; Name[Index] != '\0'; Index++)
         if (Name[Index] == '/')
@@ -3624,17 +3569,135 @@ __TransmitterRingConnect(
                           TransmitterRequestDtor,
                           TransmitterRingAcquireLock,
                           TransmitterRingReleaseLock,
-                          Ring,
-                          &Ring->RequestCache);
+                          *Ring,
+                          &(*Ring)->RequestCache);
     if (!NT_SUCCESS(status))
-        goto fail11;
+        goto fail13;
+
+    status = ThreadCreate(TransmitterRingWatchdog,
+                          *Ring,
+                          &(*Ring)->WatchdogThread);
+    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;
 
     status = RtlStringCbPrintfA(Name,
                                 sizeof (Name),
                                 "%s_transmitter",
                                 Ring->Path);
     if (!NT_SUCCESS(status))
-        goto fail12;
+        goto fail1;
 
     for (Index = 0; Name[Index] != '\0'; Index++)
         if (Name[Index] == '/')
@@ -3649,13 +3712,13 @@ __TransmitterRingConnect(
                            Ring,
                            &Ring->GnttabCache);
     if (!NT_SUCCESS(status))
-        goto fail13;
+        goto fail2;
 
     Ring->Mdl = __AllocatePage();
 
     status = STATUS_NO_MEMORY;
     if (Ring->Mdl == NULL)
-        goto fail14;
+        goto fail3;
 
     Ring->Shared = MmGetSystemAddressForMdlSafe(Ring->Mdl, NormalPagePriority);
     ASSERT(Ring->Shared != NULL);
@@ -3675,14 +3738,14 @@ __TransmitterRingConnect(
                            FALSE,
                            &Ring->Entry);
     if (!NT_SUCCESS(status))
-        goto fail15;
+        goto fail4;
 
     status = RtlStringCbPrintfA(Name,
                                 sizeof (Name),
                                 __MODULE__ "|TRANSMITTER[%u]",
                                 Ring->Index);
     if (!NT_SUCCESS(status))
-        goto fail16;
+        goto fail5;
 
     ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
 
@@ -3697,7 +3760,7 @@ __TransmitterRingConnect(
 
         status = STATUS_UNSUCCESSFUL;
         if (Ring->Channel == NULL)
-            goto fail17;
+            goto fail6;
 
         status = KeGetProcessorNumberFromIndex(Ring->Index, &ProcNumber);
         ASSERT(NT_SUCCESS(status));
@@ -3724,14 +3787,14 @@ __TransmitterRingConnect(
                           Ring,
                           &Ring->DebugCallback);
     if (!NT_SUCCESS(status))
-        goto fail18;
+        goto fail7;
 
     Ring->Connected = TRUE;
 
     return STATUS_SUCCESS;
 
-fail18:
-    Error("fail18\n");
+fail7:
+    Error("fail7\n");
 
     XENBUS_EVTCHN(Close,
                   &Transmitter->EvtchnInterface,
@@ -3740,11 +3803,11 @@ fail18:
 
     Ring->Events = 0;
 
-fail17:
-    Error("fail17\n");
+fail6:
+    Error("fail6\n");
 
-fail16:
-    Error("fail16\n");
+fail5:
+    Error("fail5\n");
 
     (VOID) XENBUS_GNTTAB(RevokeForeignAccess,
                          &Transmitter->GnttabInterface,
@@ -3753,8 +3816,8 @@ fail16:
                          Ring->Entry);
     Ring->Entry = NULL;
 
-fail15:
-    Error("fail15\n");
+fail4:
+    Error("fail4\n");
 
     RtlZeroMemory(&Ring->Front, sizeof (netif_tx_front_ring_t));
     RtlZeroMemory(Ring->Shared, PAGE_SIZE);
@@ -3763,78 +3826,14 @@ fail15:
     __FreePage(Ring->Mdl);
     Ring->Mdl = NULL;
 
-fail14:
-    Error("fail14\n");
+fail3:
+    Error("fail3\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");
 
@@ -4073,37 +4072,6 @@ __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
@@ -4141,6 +4109,37 @@ __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));
 
@@ -4497,13 +4496,21 @@ 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;
+
     MaxQueues = FrontendGetMaxQueues(Frontend);
     (*Transmitter)->Ring = __TransmitterAllocate(sizeof 
(PXENVIF_TRANSMITTER_RING) *
                                                  MaxQueues);
 
     status = STATUS_NO_MEMORY;
     if ((*Transmitter)->Ring == NULL)
-        goto fail2;
+        goto fail4;
 
     Index = 0;
     while (Index < MaxQueues) {
@@ -4511,7 +4518,7 @@ TransmitterInitialize(
 
         status = __TransmitterRingInitialize(*Transmitter, Index, &Ring);
         if (!NT_SUCCESS(status))
-            goto fail3;
+            goto fail5;
 
         (*Transmitter)->Ring[Index] = Ring;
         Index++;
@@ -4519,8 +4526,8 @@ TransmitterInitialize(
 
     return STATUS_SUCCESS;
 
-fail3:
-    Error("fail3\n");
+fail5:
+    Error("fail5\n");
 
     while (--Index > 0) {
         PXENVIF_TRANSMITTER_RING    Ring = (*Transmitter)->Ring[Index];
@@ -4532,6 +4539,16 @@ fail3:
     __TransmitterFree((*Transmitter)->Ring);
     (*Transmitter)->Ring = NULL;
 
+fail4:
+    Error("fail4\n");
+
+    XENBUS_CACHE(Release, &(*Transmitter)->CacheInterface);
+
+fail3:
+    Error("fail3\n");
+
+    XENBUS_RANGE_SET(Release, &(*Transmitter)->RangeSetInterface);
+
 fail2:
     Error("fail2\n");
 
@@ -4596,24 +4613,16 @@ TransmitterConnect(
     if (!NT_SUCCESS(status))
         goto fail3;
 
-    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;
+        goto fail4;
 
     status = RtlStringCbPrintfA(Name,
                                 sizeof (Name),
                                 "%s_transmitter_packet",
                                 FrontendGetPath(Frontend));
     if (!NT_SUCCESS(status))
-        goto fail7;
+        goto fail5;
 
     for (Index = 0; Name[Index] != '\0'; Index++)
         if (Name[Index] == '/')
@@ -4631,7 +4640,7 @@ TransmitterConnect(
                           Transmitter,
                           &Transmitter->PacketCache);
     if (!NT_SUCCESS(status))
-        goto fail8;
+        goto fail6;
 
     status = XENBUS_STORE(Read,
                           &Transmitter->StoreInterface,
@@ -4655,7 +4664,7 @@ TransmitterConnect(
 
         status = __TransmitterRingConnect(Ring);
         if (!NT_SUCCESS(status))
-            goto fail9;
+            goto fail7;
 
         Index++;
     }    
@@ -4667,18 +4676,18 @@ TransmitterConnect(
                           Transmitter,
                           &Transmitter->DebugCallback);
     if (!NT_SUCCESS(status))
-        goto fail10;
+        goto fail8;
 
     Trace("<====\n");
     return STATUS_SUCCESS;
 
-fail10:
-    Error("fail10\n");
+fail8:
+    Error("fail8\n");
 
     Index = FrontendGetNumQueues(Frontend);
 
-fail9:
-    Error("fail9\n");
+fail7:
+    Error("fail7\n");
 
     while (--Index >= 0) {
         PXENVIF_TRANSMITTER_RING    Ring;
@@ -4695,23 +4704,13 @@ fail9:
                  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_RANGE_SET(Release, &Transmitter->RangeSetInterface);
+    XENBUS_GNTTAB(Release, &Transmitter->GnttabInterface);
 
 fail4:
     Error("fail4\n");
@@ -4909,10 +4908,6 @@ 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);
@@ -4946,6 +4941,10 @@ TransmitterTeardown(
     __TransmitterFree(Transmitter->Ring);
     Transmitter->Ring = NULL;
 
+    XENBUS_CACHE(Release, &Transmitter->CacheInterface);
+
+    XENBUS_RANGE_SET(Release, &Transmitter->RangeSetInterface);
+
     Transmitter->Frontend = NULL;
 
     RtlZeroMemory(&Transmitter->Lock,
-- 
2.5.3


_______________________________________________
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®.