|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |