[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 |