[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH 4/7] Remove notifier object
Fold event channels into transmitter/receiver ring objects. Receiver ring object takes over single event channel case and passes notifications to transmitter object, tagged with ring index (so that only the specified ring is executed). Split notifications are handled independently by each ring object. Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx> --- src/xenvif/frontend.c | 75 ++--- src/xenvif/frontend.h | 7 - src/xenvif/notifier.c | 684 ------------------------------------------- src/xenvif/notifier.h | 99 ------- src/xenvif/receiver.c | 376 +++++++++++++++++++++--- src/xenvif/receiver.h | 17 +- src/xenvif/transmitter.c | 352 +++++++++++++++++++--- src/xenvif/transmitter.h | 5 +- vs2012/xenvif/xenvif.vcxproj | 1 - vs2013/xenvif/xenvif.vcxproj | 1 - 10 files changed, 678 insertions(+), 939 deletions(-) delete mode 100644 src/xenvif/notifier.c delete mode 100644 src/xenvif/notifier.h diff --git a/src/xenvif/frontend.c b/src/xenvif/frontend.c index 305faaf..268bab9 100644 --- a/src/xenvif/frontend.c +++ b/src/xenvif/frontend.c @@ -44,7 +44,6 @@ #include "frontend.h" #include "names.h" #include "granter.h" -#include "notifier.h" #include "mac.h" #include "tcpip.h" #include "receiver.h" @@ -66,7 +65,6 @@ struct _XENVIF_FRONTEND { USHORT BackendDomain; PXENVIF_GRANTER Granter; - PXENVIF_NOTIFIER Notifier; PXENVIF_MAC Mac; PXENVIF_RECEIVER Receiver; PXENVIF_TRANSMITTER Transmitter; @@ -221,7 +219,6 @@ FrontendGet ## _Function( \ } DEFINE_FRONTEND_GET_FUNCTION(Granter, PXENVIF_GRANTER) -DEFINE_FRONTEND_GET_FUNCTION(Notifier, PXENVIF_NOTIFIER) DEFINE_FRONTEND_GET_FUNCTION(Mac, PXENVIF_MAC) DEFINE_FRONTEND_GET_FUNCTION(Transmitter, PXENVIF_TRANSMITTER) DEFINE_FRONTEND_GET_FUNCTION(Receiver, PXENVIF_RECEIVER) @@ -1318,10 +1315,6 @@ __FrontendConnect( if (!NT_SUCCESS(status)) goto fail6; - status = NotifierConnect(__FrontendGetNotifier(Frontend)); - if (!NT_SUCCESS(status)) - goto fail7; - Attempt = 0; do { PXENBUS_STORE_TRANSACTION Transaction; @@ -1332,11 +1325,6 @@ __FrontendConnect( if (!NT_SUCCESS(status)) break; - status = NotifierStoreWrite(__FrontendGetNotifier(Frontend), - Transaction); - if (!NT_SUCCESS(status)) - goto abort; - status = ReceiverStoreWrite(__FrontendGetReceiver(Frontend), Transaction); if (!NT_SUCCESS(status)) @@ -1365,7 +1353,7 @@ abort: } while (status == STATUS_RETRY); if (!NT_SUCCESS(status)) - goto fail8; + goto fail7; status = XENBUS_STORE(Printf, &Frontend->StoreInterface, @@ -1375,25 +1363,22 @@ abort: "%u", XenbusStateConnected); if (!NT_SUCCESS(status)) - goto fail9; + goto fail8; State = XenbusStateInitWait; status = __FrontendWaitForStateChange(Frontend, Path, &State); if (!NT_SUCCESS(status)) - goto fail10; + goto fail9; status = STATUS_UNSUCCESSFUL; if (State != XenbusStateConnected) - goto fail11; + goto fail10; ThreadWake(Frontend->MibThread); Trace("<====\n"); return STATUS_SUCCESS; -fail11: - Error("fail11\n"); - fail10: Error("fail10\n"); @@ -1403,8 +1388,6 @@ fail9: fail8: Error("fail8\n"); - NotifierDisconnect(__FrontendGetNotifier(Frontend)); - fail7: Error("fail7\n"); @@ -1452,7 +1435,6 @@ __FrontendDisconnect( { Trace("====>\n"); - NotifierDisconnect(__FrontendGetNotifier(Frontend)); TransmitterDisconnect(__FrontendGetTransmitter(Frontend)); ReceiverDisconnect(__FrontendGetReceiver(Frontend)); MacDisconnect(__FrontendGetMac(Frontend)); @@ -1495,18 +1477,9 @@ __FrontendEnable( if (!NT_SUCCESS(status)) goto fail4; - status = NotifierEnable(__FrontendGetNotifier(Frontend)); - if (!NT_SUCCESS(status)) - goto fail5; - Trace("<====\n"); return STATUS_SUCCESS; -fail5: - Error("fail5\n"); - - TransmitterDisable(__FrontendGetTransmitter(Frontend)); - fail4: Error("fail4\n"); @@ -1535,7 +1508,6 @@ __FrontendDisable( { Trace("====>\n"); - NotifierDisable(__FrontendGetNotifier(Frontend)); TransmitterDisable(__FrontendGetTransmitter(Frontend)); ReceiverDisable(__FrontendGetReceiver(Frontend)); MacDisable(__FrontendGetMac(Frontend)); @@ -1894,64 +1866,54 @@ FrontendInitialize( if (!NT_SUCCESS(status)) goto fail6; - status = NotifierInitialize(*Frontend, &(*Frontend)->Notifier); - if (!NT_SUCCESS(status)) - goto fail7; - status = MacInitialize(*Frontend, &(*Frontend)->Mac); if (!NT_SUCCESS(status)) - goto fail8; + goto fail7; status = ReceiverInitialize(*Frontend, 1, &(*Frontend)->Receiver); if (!NT_SUCCESS(status)) - goto fail9; + goto fail8; status = TransmitterInitialize(*Frontend, 1, &(*Frontend)->Transmitter); if (!NT_SUCCESS(status)) - goto fail10; + goto fail9; status = ThreadCreate(FrontendEject, *Frontend, &(*Frontend)->EjectThread); if (!NT_SUCCESS(status)) - goto fail11; + goto fail10; status = ThreadCreate(FrontendMib, *Frontend, &(*Frontend)->MibThread); if (!NT_SUCCESS(status)) - goto fail12; + goto fail11; Trace("<====\n"); return STATUS_SUCCESS; -fail12: - Error("fail12\n"); +fail11: + Error("fail11\n"); ThreadAlert((*Frontend)->EjectThread); ThreadJoin((*Frontend)->EjectThread); (*Frontend)->EjectThread = NULL; -fail11: - Error("fail11\n"); - - TransmitterTeardown(__FrontendGetTransmitter(*Frontend)); - (*Frontend)->Transmitter = NULL; - fail10: Error("fail10\n"); - ReceiverTeardown(__FrontendGetReceiver(*Frontend)); - (*Frontend)->Receiver = NULL; + TransmitterTeardown(__FrontendGetTransmitter(*Frontend)); + (*Frontend)->Transmitter = NULL; fail9: Error("fail9\n"); - MacTeardown(__FrontendGetMac(*Frontend)); - (*Frontend)->Mac = NULL; + ReceiverTeardown(__FrontendGetReceiver(*Frontend)); + (*Frontend)->Receiver = NULL; fail8: Error("fail8\n"); - NotifierTeardown(__FrontendGetNotifier(*Frontend)); - (*Frontend)->Notifier = NULL; + MacTeardown(__FrontendGetMac(*Frontend)); + (*Frontend)->Mac = NULL; fail7: Error("fail7\n"); @@ -2043,9 +2005,6 @@ FrontendTeardown( MacTeardown(__FrontendGetMac(Frontend)); Frontend->Mac = NULL; - NotifierTeardown(__FrontendGetNotifier(Frontend)); - Frontend->Notifier = NULL; - GranterTeardown(__FrontendGetGranter(Frontend)); Frontend->Granter = NULL; diff --git a/src/xenvif/frontend.h b/src/xenvif/frontend.h index 60c085a..67696d6 100644 --- a/src/xenvif/frontend.h +++ b/src/xenvif/frontend.h @@ -119,13 +119,6 @@ FrontendGetGranter( IN PXENVIF_FRONTEND Frontend ); -#include "notifier.h" - -extern PXENVIF_NOTIFIER -FrontendGetNotifier( - IN PXENVIF_FRONTEND Frontend - ); - #include "mac.h" extern PXENVIF_MAC diff --git a/src/xenvif/notifier.c b/src/xenvif/notifier.c deleted file mode 100644 index fc6725a..0000000 --- a/src/xenvif/notifier.c +++ /dev/null @@ -1,684 +0,0 @@ -/* Copyright (c) Citrix Systems Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, - * with or without modification, are permitted provided - * that the following conditions are met: - * - * * Redistributions of source code must retain the above - * copyright notice, this list of conditions and the - * following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <ntddk.h> -#include <ntstrsafe.h> -#include <stdlib.h> -#include <util.h> - -#include "pdo.h" -#include "frontend.h" -#include "notifier.h" -#include "receiver.h" -#include "transmitter.h" -#include "dbg_print.h" -#include "assert.h" - -typedef enum _XENVIF_NOTIFIER_EVTCHN { - XENVIF_NOTIFIER_EVTCHN_COMBINED = 0, - XENVIF_NOTIFIER_EVTCHN_RX, - XENVIF_NOTIFIER_EVTCHN_TX, - XENVIF_NOTIFIER_EVTCHN_COUNT -} XENVIF_NOTIFIER_EVTCHN, *PXENVIF_NOTIFIER_EVTCHN; - -struct _XENVIF_NOTIFIER { - PXENVIF_FRONTEND Frontend; - XENBUS_EVTCHN_INTERFACE EvtchnInterface; - PXENBUS_EVTCHN_CHANNEL Channel[XENVIF_NOTIFIER_EVTCHN_COUNT]; - KDPC Dpc[XENVIF_NOTIFIER_EVTCHN_COUNT]; - ULONG Dpcs[XENVIF_NOTIFIER_EVTCHN_COUNT]; - ULONG Events[XENVIF_NOTIFIER_EVTCHN_COUNT]; - BOOLEAN Connected; - KSPIN_LOCK Lock; - BOOLEAN Split; - BOOLEAN Enabled; - XENBUS_STORE_INTERFACE StoreInterface; - XENBUS_DEBUG_INTERFACE DebugInterface; - PXENBUS_DEBUG_CALLBACK DebugCallback; -}; - -#define XENVIF_NOTIFIER_TAG 'ITON' - -static FORCEINLINE PVOID -__NotifierAllocate( - IN ULONG Length - ) -{ - return __AllocateNonPagedPoolWithTag(Length, XENVIF_NOTIFIER_TAG); -} - -static FORCEINLINE VOID -__NotifierFree( - IN PVOID Buffer - ) -{ - __FreePoolWithTag(Buffer, XENVIF_NOTIFIER_TAG); -} - -static FORCEINLINE BOOLEAN -__NotifierUnmask( - IN PXENVIF_NOTIFIER Notifier, - IN XENVIF_NOTIFIER_EVTCHN Index - ) -{ - PXENVIF_FRONTEND Frontend; - BOOLEAN Pending; - - Frontend = Notifier->Frontend; - - KeAcquireSpinLockAtDpcLevel(&Notifier->Lock); - - Pending = (Notifier->Connected) ? - XENBUS_EVTCHN(Unmask, - &Notifier->EvtchnInterface, - Notifier->Channel[Index], - FALSE) : - FALSE; - - KeReleaseSpinLockFromDpcLevel(&Notifier->Lock); - - return Pending; -} - -__drv_functionClass(KDEFERRED_ROUTINE) -__drv_maxIRQL(DISPATCH_LEVEL) -__drv_minIRQL(DISPATCH_LEVEL) -__drv_requiresIRQL(DISPATCH_LEVEL) -__drv_sameIRQL -static VOID -NotifierDpc( - IN PKDPC Dpc, - IN PVOID Context, - IN PVOID Argument1, - IN PVOID Argument2 - ) -{ - PXENVIF_NOTIFIER Notifier = Context; - XENVIF_NOTIFIER_EVTCHN Index = (ULONG_PTR)Argument1; - PXENVIF_FRONTEND Frontend; - BOOLEAN Pending; - - UNREFERENCED_PARAMETER(Dpc); - UNREFERENCED_PARAMETER(Argument2); - - ASSERT(Notifier != NULL); - - Frontend = Notifier->Frontend; - - do { - if (Notifier->Enabled) { - switch (Index) { - case XENVIF_NOTIFIER_EVTCHN_TX: - TransmitterNotify(FrontendGetTransmitter(Frontend)); - break; - - case XENVIF_NOTIFIER_EVTCHN_RX: - ReceiverNotify(FrontendGetReceiver(Frontend)); - break; - - case XENVIF_NOTIFIER_EVTCHN_COMBINED: - TransmitterNotify(FrontendGetTransmitter(Frontend)); - ReceiverNotify(FrontendGetReceiver(Frontend)); - break; - - default: - ASSERT(FALSE); - break; - } - } - - Pending = __NotifierUnmask(Notifier, Index); - } while (Pending); -} - -static FORCEINLINE BOOLEAN -__NotifierEvtchnCallback( - IN PXENVIF_NOTIFIER Notifier, - IN XENVIF_NOTIFIER_EVTCHN Index - ) -{ - Notifier->Events[Index]++; - - if (KeInsertQueueDpc(&Notifier->Dpc[Index], - (PVOID)(ULONG_PTR)Index, - NULL)) - Notifier->Dpcs[Index]++; - - return TRUE; -} - -#define DEFINE_XENVIF_NOTIFIER_EVTCHN_CALLBACK(_Type) \ - \ -KSERVICE_ROUTINE Notifier ## _Type ## EvtchnCallback; \ - \ -BOOLEAN \ -Notifier ## _Type ## EvtchnCallback( \ - IN PKINTERRUPT InterruptObject, \ - IN PVOID Argument \ - ) \ -{ \ - PXENVIF_NOTIFIER Notifier = Argument; \ - \ - UNREFERENCED_PARAMETER(InterruptObject); \ - \ - ASSERT(Notifier != NULL); \ - return __NotifierEvtchnCallback(Notifier, \ - XENVIF_NOTIFIER_EVTCHN_ ## _Type); \ -} - -DEFINE_XENVIF_NOTIFIER_EVTCHN_CALLBACK(COMBINED) -DEFINE_XENVIF_NOTIFIER_EVTCHN_CALLBACK(RX) -DEFINE_XENVIF_NOTIFIER_EVTCHN_CALLBACK(TX) - -#undef DEFINE_XENVIF_NOTIFIER_EVTCHN_CALLBACK - -#define DEFINE_XENVIF_NOTIFIER_EVTCHN_CALLBACK(_Type) \ - Notifier ## _Type ## EvtchnCallback, - -PKSERVICE_ROUTINE NotifierEvtchnCallback[] = { - DEFINE_XENVIF_NOTIFIER_EVTCHN_CALLBACK(COMBINED) - DEFINE_XENVIF_NOTIFIER_EVTCHN_CALLBACK(RX) - DEFINE_XENVIF_NOTIFIER_EVTCHN_CALLBACK(TX) -}; - -#undef DEFINE_XENVIF_NOTIFIER_EVTCHN_CALLBACK - -C_ASSERT(ARRAYSIZE(NotifierEvtchnCallback) == XENVIF_NOTIFIER_EVTCHN_COUNT); - -static VOID -NotifierDebugCallback( - IN PVOID Argument, - IN BOOLEAN Crashing - ) -{ - PXENVIF_NOTIFIER Notifier = Argument; - PXENVIF_FRONTEND Frontend; - ULONG Index; - - UNREFERENCED_PARAMETER(Crashing); - - Frontend = Notifier->Frontend; - - for (Index = 0; Index < XENVIF_NOTIFIER_EVTCHN_COUNT; Index++) - XENBUS_DEBUG(Printf, - &Notifier->DebugInterface, - "[%s]: Events = %lu Dpcs = %lu\n", - ((Index == XENVIF_NOTIFIER_EVTCHN_COMBINED) ? "COMBINED" : - ((Index == XENVIF_NOTIFIER_EVTCHN_RX) ? "RX" : - ((Index == XENVIF_NOTIFIER_EVTCHN_TX) ? "TX" : - "UNKNOWN"))), - Notifier->Events[Index], - Notifier->Dpcs[Index]); -} - -NTSTATUS -NotifierInitialize( - IN PXENVIF_FRONTEND Frontend, - OUT PXENVIF_NOTIFIER *Notifier - ) -{ - ULONG Index; - NTSTATUS status; - - *Notifier = __NotifierAllocate(sizeof (XENVIF_NOTIFIER)); - - status = STATUS_NO_MEMORY; - if (*Notifier == NULL) - goto fail1; - - FdoGetEvtchnInterface(PdoGetFdo(FrontendGetPdo(Frontend)), - &(*Notifier)->EvtchnInterface); - - FdoGetDebugInterface(PdoGetFdo(FrontendGetPdo(Frontend)), - &(*Notifier)->DebugInterface); - - FdoGetStoreInterface(PdoGetFdo(FrontendGetPdo(Frontend)), - &(*Notifier)->StoreInterface); - - (*Notifier)->Frontend = Frontend; - - KeInitializeSpinLock(&(*Notifier)->Lock); - for (Index = 0; Index < XENVIF_NOTIFIER_EVTCHN_COUNT; Index++) - KeInitializeDpc(&(*Notifier)->Dpc[Index], - NotifierDpc, - *Notifier); - - return STATUS_SUCCESS; - -fail1: - Error("fail1 (%08x)\n", status); - - return status; -} - -NTSTATUS -NotifierConnect( - IN PXENVIF_NOTIFIER Notifier - ) -{ - PXENVIF_FRONTEND Frontend; - LONG Index; - PCHAR Buffer; - NTSTATUS status; - - Frontend = Notifier->Frontend; - - ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL); - KeAcquireSpinLockAtDpcLevel(&Notifier->Lock); - - ASSERT(!Notifier->Connected); - - status = XENBUS_EVTCHN(Acquire, &Notifier->EvtchnInterface); - if (!NT_SUCCESS(status)) - goto fail1; - - status = XENBUS_DEBUG(Acquire, &Notifier->DebugInterface); - if (!NT_SUCCESS(status)) - goto fail2; - - status = XENBUS_STORE(Acquire, &Notifier->StoreInterface); - if (!NT_SUCCESS(status)) - goto fail3; - - for (Index = 0; Index < XENVIF_NOTIFIER_EVTCHN_COUNT; Index++) { - PKSERVICE_ROUTINE Callback = NotifierEvtchnCallback[Index]; - BOOLEAN Pending; - - Notifier->Channel[Index] = XENBUS_EVTCHN(Open, - &Notifier->EvtchnInterface, - XENBUS_EVTCHN_TYPE_UNBOUND, - Callback, - Notifier, - FrontendGetBackendDomain(Frontend), - TRUE); - - status = STATUS_UNSUCCESSFUL; - if (Notifier->Channel[Index] == NULL) - goto fail4; - - Pending = XENBUS_EVTCHN(Unmask, - &Notifier->EvtchnInterface, - Notifier->Channel[Index], - FALSE); - if (Pending) - XENBUS_EVTCHN(Trigger, - &Notifier->EvtchnInterface, - Notifier->Channel[Index]); - } - - status = XENBUS_DEBUG(Register, - &Notifier->DebugInterface, - __MODULE__ "|NOTIFIER", - NotifierDebugCallback, - Notifier, - &Notifier->DebugCallback); - if (!NT_SUCCESS(status)) - goto fail5; - - status = XENBUS_STORE(Read, - &Notifier->StoreInterface, - NULL, - FrontendGetBackendPath(Frontend), - "feature-split-event-channels", - &Buffer); - if (!NT_SUCCESS(status)) { - Notifier->Split = FALSE; - } else { - Notifier->Split = (BOOLEAN)strtol(Buffer, NULL, 2); - - XENBUS_STORE(Free, - &Notifier->StoreInterface, - Buffer); - } - - Notifier->Connected = TRUE; - KeReleaseSpinLockFromDpcLevel(&Notifier->Lock); - - return STATUS_SUCCESS; - -fail5: - Error("fail5\n"); - - Index = XENVIF_NOTIFIER_EVTCHN_COUNT; - -fail4: - Error("fail4\n"); - - while (--Index >= 0) { - XENBUS_EVTCHN(Close, - &Notifier->EvtchnInterface, - Notifier->Channel[Index]); - Notifier->Channel[Index] = NULL; - - Notifier->Events[Index] = 0; - } - - XENBUS_STORE(Release, &Notifier->StoreInterface); - -fail3: - Error("fail3\n"); - - XENBUS_DEBUG(Release, &Notifier->DebugInterface); - -fail2: - Error("fail2\n"); - - XENBUS_EVTCHN(Release, &Notifier->EvtchnInterface); - -fail1: - Error("fail1 (%08x)\n", status); - - KeReleaseSpinLockFromDpcLevel(&Notifier->Lock); - - return status; -} - -NTSTATUS -NotifierStoreWrite( - IN PXENVIF_NOTIFIER Notifier, - IN PXENBUS_STORE_TRANSACTION Transaction - ) -{ - PXENVIF_FRONTEND Frontend = Notifier->Frontend; - ULONG Index; - NTSTATUS status; - - for (Index = 0; Index < XENVIF_NOTIFIER_EVTCHN_COUNT; Index++) { - PCHAR Node; - ULONG Port; - - switch (Index) { - case XENVIF_NOTIFIER_EVTCHN_COMBINED: - if (Notifier->Split) - continue; - - Node = "event-channel"; - break; - - case XENVIF_NOTIFIER_EVTCHN_RX: - if (!Notifier->Split) - continue; - - Node = "event-channel-rx"; - break; - - case XENVIF_NOTIFIER_EVTCHN_TX: - if (!Notifier->Split) - continue; - - Node = "event-channel-tx"; - break; - - default: - ASSERT(FALSE); - - Node = ""; - break; - } - - Port = XENBUS_EVTCHN(GetPort, - &Notifier->EvtchnInterface, - Notifier->Channel[Index]); - - status = XENBUS_STORE(Printf, - &Notifier->StoreInterface, - Transaction, - FrontendGetPath(Frontend), - Node, - "%u", - Port); - - if (!NT_SUCCESS(status)) - goto fail1; - } - - return STATUS_SUCCESS; - -fail1: - Error("fail1 (%08x)\n", status); - - return status; -} - -NTSTATUS -NotifierEnable( - IN PXENVIF_NOTIFIER Notifier - ) -{ - ULONG Index; - - ASSERT(!Notifier->Enabled); - Notifier->Enabled = TRUE; - - for (Index = 0; Index < XENVIF_NOTIFIER_EVTCHN_COUNT; Index++) { - switch (Index) { - case XENVIF_NOTIFIER_EVTCHN_COMBINED: - if (Notifier->Split) - continue; - - break; - - case XENVIF_NOTIFIER_EVTCHN_RX: - if (!Notifier->Split) - continue; - - break; - - case XENVIF_NOTIFIER_EVTCHN_TX: - if (!Notifier->Split) - continue; - - break; - - default: - ASSERT(FALSE); - - break; - } - - if (KeInsertQueueDpc(&Notifier->Dpc[Index], - (PVOID)(ULONG_PTR)Index, - NULL)) - Notifier->Dpcs[Index]++; - } - - return STATUS_SUCCESS; -} - -VOID -NotifierDisable( - IN PXENVIF_NOTIFIER Notifier - ) -{ - ASSERT(Notifier->Enabled); - Notifier->Enabled = FALSE; -} - -VOID -NotifierDisconnect( - IN PXENVIF_NOTIFIER Notifier - ) -{ - PXENVIF_FRONTEND Frontend; - LONG Index; - - Frontend = Notifier->Frontend; - - KeAcquireSpinLockAtDpcLevel(&Notifier->Lock); - - ASSERT(Notifier->Connected); - Notifier->Connected = FALSE; - - Notifier->Split = FALSE; - - XENBUS_DEBUG(Deregister, - &Notifier->DebugInterface, - Notifier->DebugCallback); - Notifier->DebugCallback = NULL; - - Index = XENVIF_NOTIFIER_EVTCHN_COUNT; - while (--Index >= 0) { - XENBUS_EVTCHN(Close, - &Notifier->EvtchnInterface, - Notifier->Channel[Index]); - Notifier->Channel[Index] = NULL; - - Notifier->Events[Index] = 0; - } - - XENBUS_STORE(Release, &Notifier->StoreInterface); - - XENBUS_DEBUG(Release, &Notifier->DebugInterface); - - XENBUS_EVTCHN(Release, &Notifier->EvtchnInterface); - - KeReleaseSpinLockFromDpcLevel(&Notifier->Lock); -} - -VOID -NotifierTeardown( - IN PXENVIF_NOTIFIER Notifier - ) -{ - LONG Index; - - ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL); - KeFlushQueuedDpcs(); - - Index = XENVIF_NOTIFIER_EVTCHN_COUNT; - while (--Index >= 0) { - Notifier->Dpcs[Index] = 0; - RtlZeroMemory(&Notifier->Dpc[Index], sizeof (KDPC)); - } - - Notifier->Frontend = NULL; - - RtlZeroMemory(&Notifier->StoreInterface, - sizeof (XENBUS_STORE_INTERFACE)); - - RtlZeroMemory(&Notifier->DebugInterface, - sizeof (XENBUS_DEBUG_INTERFACE)); - - RtlZeroMemory(&Notifier->EvtchnInterface, - sizeof (XENBUS_EVTCHN_INTERFACE)); - - RtlZeroMemory(&Notifier->Lock, sizeof (KSPIN_LOCK)); - - ASSERT(IsZeroMemory(Notifier, sizeof (XENVIF_NOTIFIER))); - - __NotifierFree(Notifier); -} - -static FORCEINLINE VOID -__NotifierSend( - IN PXENVIF_NOTIFIER Notifier, - IN ULONG Index - ) -{ - PXENVIF_FRONTEND Frontend; - KIRQL Irql; - - Frontend = Notifier->Frontend; - - KeAcquireSpinLock(&Notifier->Lock, &Irql); - - if (Notifier->Connected) - (VOID) XENBUS_EVTCHN(Send, - &Notifier->EvtchnInterface, - Notifier->Channel[Index]); - - KeReleaseSpinLock(&Notifier->Lock, Irql); -} - -VOID -NotifierSendTx( - IN PXENVIF_NOTIFIER Notifier - ) -{ - if (Notifier->Split) - __NotifierSend(Notifier, XENVIF_NOTIFIER_EVTCHN_TX); - else - __NotifierSend(Notifier, XENVIF_NOTIFIER_EVTCHN_COMBINED); -} - -VOID -NotifierSendRx( - IN PXENVIF_NOTIFIER Notifier - ) -{ - if (Notifier->Split) - __NotifierSend(Notifier, XENVIF_NOTIFIER_EVTCHN_RX); - else - __NotifierSend(Notifier, XENVIF_NOTIFIER_EVTCHN_COMBINED); -} - -static FORCEINLINE VOID -__NotifierTrigger( - IN PXENVIF_NOTIFIER Notifier, - IN ULONG Index - ) -{ - PXENVIF_FRONTEND Frontend; - KIRQL Irql; - - Frontend = Notifier->Frontend; - - KeAcquireSpinLock(&Notifier->Lock, &Irql); - - if (Notifier->Connected) - (VOID) XENBUS_EVTCHN(Trigger, - &Notifier->EvtchnInterface, - Notifier->Channel[Index]); - - KeReleaseSpinLock(&Notifier->Lock, Irql); -} - -VOID -NotifierTriggerTx( - IN PXENVIF_NOTIFIER Notifier - ) -{ - if (Notifier->Split) - __NotifierTrigger(Notifier, XENVIF_NOTIFIER_EVTCHN_TX); - else - __NotifierTrigger(Notifier, XENVIF_NOTIFIER_EVTCHN_COMBINED); -} - -VOID -NotifierTriggerRx( - IN PXENVIF_NOTIFIER Notifier - ) -{ - if (Notifier->Split) - __NotifierTrigger(Notifier, XENVIF_NOTIFIER_EVTCHN_RX); - else - __NotifierTrigger(Notifier, XENVIF_NOTIFIER_EVTCHN_COMBINED); -} diff --git a/src/xenvif/notifier.h b/src/xenvif/notifier.h deleted file mode 100644 index 2f06a6f..0000000 --- a/src/xenvif/notifier.h +++ /dev/null @@ -1,99 +0,0 @@ -/* Copyright (c) Citrix Systems Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, - * with or without modification, are permitted provided - * that the following conditions are met: - * - * * Redistributions of source code must retain the above - * copyright notice, this list of conditions and the - * following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _XENVIF_NOTIFIER_H -#define _XENVIF_NOTIFIER_H - -#include <ntddk.h> -#include <store_interface.h> - -#include "frontend.h" - -typedef struct _XENVIF_NOTIFIER XENVIF_NOTIFIER, *PXENVIF_NOTIFIER; - -extern NTSTATUS -NotifierInitialize( - IN PXENVIF_FRONTEND Frontend, - OUT PXENVIF_NOTIFIER *Notifier - ); - -extern NTSTATUS -NotifierConnect( - IN PXENVIF_NOTIFIER Notifier - ); - -extern NTSTATUS -NotifierStoreWrite( - IN PXENVIF_NOTIFIER Notifier, - IN PXENBUS_STORE_TRANSACTION Transaction - ); - -extern NTSTATUS -NotifierEnable( - IN PXENVIF_NOTIFIER Notifier - ); - -extern VOID -NotifierDisable( - IN PXENVIF_NOTIFIER Notifier - ); - -extern VOID -NotifierDisconnect( - IN PXENVIF_NOTIFIER Notifier - ); - -extern VOID -NotifierTeardown( - IN PXENVIF_NOTIFIER Notifier - ); - -extern VOID -NotifierSendTx( - IN PXENVIF_NOTIFIER Notifier - ); - -extern VOID -NotifierSendRx( - IN PXENVIF_NOTIFIER Notifier - ); - -extern VOID -NotifierTriggerTx( - IN PXENVIF_NOTIFIER Notifier - ); - -extern VOID -NotifierTriggerRx( - IN PXENVIF_NOTIFIER Notifier - ); - -#endif // _XENVIF_NOTIFIER_H diff --git a/src/xenvif/receiver.c b/src/xenvif/receiver.c index 1b81b73..a11d91e 100644 --- a/src/xenvif/receiver.c +++ b/src/xenvif/receiver.c @@ -37,6 +37,7 @@ #include <debug_interface.h> #include <store_interface.h> #include <cache_interface.h> +#include <evtchn_interface.h> // This should be in public/io/netif.h #define _NETRXF_gso_prefix (4) @@ -50,8 +51,8 @@ #include "checksum.h" #include "parse.h" #include "granter.h" -#include "notifier.h" #include "mac.h" +#include "transmitter.h" #include "vif.h" #include "receiver.h" #include "thread.h" @@ -82,10 +83,16 @@ typedef struct _XENVIF_RECEIVER_RING { netif_rx_front_ring_t Front; netif_rx_sring_t *Shared; XENVIF_GRANTER_HANDLE Handle; + PXENBUS_EVTCHN_CHANNEL Channel; + KDPC Dpc; + ULONG Dpcs; + ULONG Events; + KSPIN_LOCK EvtchnLock; PXENVIF_RECEIVER_FRAGMENT Pending[XENVIF_RECEIVER_MAXIMUM_FRAGMENT_ID + 1]; ULONG RequestsPosted; ULONG RequestsPushed; ULONG ResponsesProcessed; + BOOLEAN Connected; BOOLEAN Enabled; BOOLEAN Stopped; XENVIF_VIF_OFFLOAD_OPTIONS OffloadOptions; @@ -97,7 +104,9 @@ typedef struct _XENVIF_RECEIVER_RING { struct _XENVIF_RECEIVER { PXENVIF_FRONTEND Frontend; XENBUS_CACHE_INTERFACE CacheInterface; + XENBUS_EVTCHN_INTERFACE EvtchnInterface; PXENVIF_RECEIVER_RING Rings[MAXIMUM_PROCESSORS]; + BOOLEAN Split; LONG Loaned; LONG Returned; KEVENT Event; @@ -1352,6 +1361,46 @@ __ReceiverRingIsStopped( } static FORCEINLINE VOID +__ReceiverRingTrigger( + IN PXENVIF_RECEIVER_RING Ring + ) +{ + KIRQL Irql; + PXENVIF_RECEIVER Receiver; + + Receiver = Ring->Receiver; + + KeAcquireSpinLock(&Ring->EvtchnLock, &Irql); + + if (Ring->Connected) + (VOID) XENBUS_EVTCHN(Trigger, + &Receiver->EvtchnInterface, + Ring->Channel); + + KeReleaseSpinLock(&Ring->EvtchnLock, Irql); +} + +static FORCEINLINE VOID +__ReceiverRingSend( + IN PXENVIF_RECEIVER_RING Ring + ) +{ + KIRQL Irql; + PXENVIF_RECEIVER Receiver; + + Receiver = Ring->Receiver; + + KeAcquireSpinLock(&Ring->EvtchnLock, &Irql); + + if (Ring->Connected) + (VOID) XENBUS_EVTCHN(Send, + &Receiver->EvtchnInterface, + Ring->Channel); + + KeReleaseSpinLock(&Ring->EvtchnLock, Irql); +} + +static FORCEINLINE VOID __ReceiverRingReturnPacket( IN PXENVIF_RECEIVER_RING Ring, IN PXENVIF_RECEIVER_PACKET Packet, @@ -1382,15 +1431,8 @@ __ReceiverRingReturnPacket( __ReceiverRingAcquireLock(Ring); if (__ReceiverRingIsStopped(Ring)) { - PXENVIF_RECEIVER Receiver; - PXENVIF_FRONTEND Frontend; - __ReceiverRingStart(Ring); - - Receiver = Ring->Receiver; - Frontend = Receiver->Frontend; - - NotifierTriggerRx(FrontendGetNotifier(Frontend)); + __ReceiverRingTrigger(Ring); } if (!Locked) @@ -1464,13 +1506,7 @@ __ReceiverRingPushRequests( #pragma warning (pop) if (Notify) { - PXENVIF_RECEIVER Receiver; - PXENVIF_FRONTEND Frontend; - - Receiver = Ring->Receiver; - Frontend = Receiver->Frontend; - - NotifierSendRx(FrontendGetNotifier(Frontend)); + __ReceiverRingSend(Ring); } Ring->RequestsPushed = Ring->RequestsPosted; @@ -1599,8 +1635,9 @@ ReceiverRingDebugCallback( XENBUS_DEBUG(Printf, &Receiver->DebugInterface, - "0x%p [%s][%s]\n", + "0x%p [%u] [%s][%s]\n", Ring, + Ring->Index, (Ring->Enabled) ? "ENABLED" : "DISABLED", (__ReceiverRingIsStopped(Ring)) ? "STOPPED" : "RUNNING"); @@ -1628,6 +1665,14 @@ ReceiverRingDebugCallback( Ring->RequestsPosted, Ring->RequestsPushed, Ring->ResponsesProcessed); + + // Dump event channel + XENBUS_DEBUG(Printf, + &Receiver->DebugInterface, + "[%s]: Events = %lu Dpcs = %lu\n", + Receiver->Split ? "RX" : "COMBINED", + Ring->Events, + Ring->Dpcs); } static DECLSPEC_NOINLINE VOID @@ -1801,6 +1846,104 @@ ReceiverRingPoll( #undef XENVIF_RECEIVER_BATCH } +static FORCEINLINE VOID +__ReceiverRingNotify( + IN PXENVIF_RECEIVER_RING Ring + ) +{ + __ReceiverRingAcquireLock(Ring); + ReceiverRingPoll(Ring); + __ReceiverRingReleaseLock(Ring); +} + +static FORCEINLINE BOOLEAN +__ReceiverRingUnmask( + IN PXENVIF_RECEIVER_RING Ring + ) +{ + PXENVIF_RECEIVER Receiver; + BOOLEAN Pending; + + Receiver = Ring->Receiver; + + KeAcquireSpinLockAtDpcLevel(&Ring->EvtchnLock); + + Pending = (Ring->Connected) ? + XENBUS_EVTCHN(Unmask, + &Receiver->EvtchnInterface, + Ring->Channel, + FALSE) : + FALSE; + + KeReleaseSpinLockFromDpcLevel(&Ring->EvtchnLock); + + return Pending; +} + +__drv_functionClass(KDEFERRED_ROUTINE) +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_minIRQL(DISPATCH_LEVEL) +__drv_requiresIRQL(DISPATCH_LEVEL) +__drv_sameIRQL +static VOID +ReceiverRingDpc( + IN PKDPC Dpc, + IN PVOID Context, + IN PVOID Argument1, + IN PVOID Argument2 + ) +{ + PXENVIF_RECEIVER_RING Ring = Context; + PXENVIF_RECEIVER Receiver; + PXENVIF_FRONTEND Frontend; + BOOLEAN Pending; + + UNREFERENCED_PARAMETER(Dpc); + UNREFERENCED_PARAMETER(Argument1); + UNREFERENCED_PARAMETER(Argument2); + + ASSERT(Ring != NULL); + + Receiver = Ring->Receiver; + Frontend = Receiver->Frontend; + + do { + if (Ring->Enabled) { + if (Receiver->Split) { + __ReceiverRingNotify(Ring); + } else { + TransmitterRingNotify(FrontendGetTransmitter(Frontend), + Ring->Index); + __ReceiverRingNotify(Ring); + } + } + + Pending = __ReceiverRingUnmask(Ring); + } while (Pending); +} + +KSERVICE_ROUTINE ReceiverRingEvtchnCallback; + +BOOLEAN +ReceiverRingEvtchnCallback( + IN PKINTERRUPT InterruptObject, + IN PVOID Argument + ) +{ + PXENVIF_RECEIVER_RING Ring = Argument; + + UNREFERENCED_PARAMETER(InterruptObject); + + ASSERT(Ring != NULL); + + Ring->Events++; + + if (KeInsertQueueDpc(&Ring->Dpc, NULL, NULL)) + Ring->Dpcs++; + + return TRUE; +} + #define TIME_US(_us) ((_us) * 10) #define TIME_MS(_ms) (TIME_US((_ms) * 1000)) #define TIME_S(_s) (TIME_MS((_s) * 1000)) @@ -1851,10 +1994,8 @@ ReceiverRingWatchdog( if (Ring->Shared->rsp_prod != rsp_prod && Ring->Front.rsp_cons == rsp_cons) { PXENVIF_RECEIVER Receiver; - PXENVIF_FRONTEND Frontend; Receiver = Ring->Receiver; - Frontend = Receiver->Frontend; XENBUS_DEBUG(Trigger, &Receiver->DebugInterface, @@ -1862,7 +2003,7 @@ ReceiverRingWatchdog( // Try to move things along ReceiverRingPoll(Ring); - NotifierSendRx(FrontendGetNotifier(Frontend)); + __ReceiverRingSend(Ring); } KeMemoryBarrier(); @@ -1905,6 +2046,9 @@ __ReceiverRingInitialize( (*Ring)->Index = Index; InitializeListHead(&(*Ring)->PacketList); + + KeInitializeSpinLock(&(*Ring)->EvtchnLock); + KeInitializeDpc(&(*Ring)->Dpc, ReceiverRingDpc, *Ring); status = RtlStringCbPrintfA(Name, sizeof (Name), @@ -1989,6 +2133,9 @@ fail3: fail2: Error("fail2\n"); + RtlZeroMemory(&(*Ring)->EvtchnLock, sizeof (KSPIN_LOCK)); + RtlZeroMemory(&(*Ring)->Dpc, sizeof (KDPC)); + RtlZeroMemory(&(*Ring)->PacketList, sizeof (LIST_ENTRY)); (*Ring)->Index = 0; @@ -2014,6 +2161,7 @@ __ReceiverRingConnect( PXENVIF_RECEIVER Receiver; PXENVIF_FRONTEND Frontend; PFN_NUMBER Pfn; + BOOLEAN Pending; CHAR Name[MAXNAMELEN]; NTSTATUS status; @@ -2049,6 +2197,38 @@ __ReceiverRingConnect( if (!NT_SUCCESS(status)) goto fail3; + ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL); + KeAcquireSpinLockAtDpcLevel(&Ring->EvtchnLock); + + ASSERT(!Ring->Connected); + + Ring->Channel = XENBUS_EVTCHN(Open, + &Receiver->EvtchnInterface, + XENBUS_EVTCHN_TYPE_UNBOUND, + ReceiverRingEvtchnCallback, + Ring, + FrontendGetBackendDomain(Frontend), + TRUE); + + status = STATUS_UNSUCCESSFUL; + if (Ring->Channel == NULL) { + KeReleaseSpinLockFromDpcLevel(&Ring->EvtchnLock); + goto fail4; + } + + Pending = XENBUS_EVTCHN(Unmask, + &Receiver->EvtchnInterface, + Ring->Channel, + FALSE); + + if (Pending) + XENBUS_EVTCHN(Trigger, + &Receiver->EvtchnInterface, + Ring->Channel); + + Ring->Connected = TRUE; + KeReleaseSpinLockFromDpcLevel(&Ring->EvtchnLock); + status = XENBUS_DEBUG(Register, &Receiver->DebugInterface, Name, @@ -2056,10 +2236,22 @@ __ReceiverRingConnect( Ring, &Ring->DebugCallback); if (!NT_SUCCESS(status)) - goto fail4; + goto fail5; return STATUS_SUCCESS; +fail5: + Error("fail5\n"); + + Ring->Connected = FALSE; + + XENBUS_EVTCHN(Close, + &Receiver->EvtchnInterface, + Ring->Channel); + Ring->Channel = NULL; + + Ring->Events = 0; + fail4: Error("fail4\n"); @@ -2094,6 +2286,7 @@ __ReceiverRingStoreWrite( { PXENVIF_RECEIVER Receiver; PXENVIF_FRONTEND Frontend; + ULONG Port; NTSTATUS status; Receiver = Ring->Receiver; @@ -2111,8 +2304,25 @@ __ReceiverRingStoreWrite( if (!NT_SUCCESS(status)) goto fail1; + Port = XENBUS_EVTCHN(GetPort, + &Receiver->EvtchnInterface, + Ring->Channel); + + status = XENBUS_STORE(Printf, + &Receiver->StoreInterface, + Transaction, + FrontendGetPath(Frontend), + Receiver->Split ? "event-channel-rx" : "event-channel", + "%u", + Port); + if (!NT_SUCCESS(status)) + goto fail2; + return STATUS_SUCCESS; +fail2: + Error("fail2\n"); + fail1: Error("fail1 (%08x)\n", status); @@ -2143,6 +2353,9 @@ __ReceiverRingEnable( Ring->Enabled = TRUE; + if (KeInsertQueueDpc(&Ring->Dpc, NULL, NULL)) + Ring->Dpcs++; + __ReceiverRingReleaseLock(Ring); return STATUS_SUCCESS; @@ -2183,6 +2396,20 @@ __ReceiverRingDisconnect( __ReceiverRingEmpty(Ring); + KeAcquireSpinLockAtDpcLevel(&Ring->EvtchnLock); + + ASSERT(Ring->Connected); + Ring->Connected = FALSE; + + XENBUS_EVTCHN(Close, + &Receiver->EvtchnInterface, + Ring->Channel); + Ring->Channel = NULL; + + Ring->Events = 0; + + KeReleaseSpinLockFromDpcLevel(&Ring->EvtchnLock); + ASSERT3U(Ring->ResponsesProcessed, ==, Ring->RequestsPushed); ASSERT3U(Ring->RequestsPushed, ==, Ring->RequestsPosted); @@ -2216,6 +2443,10 @@ __ReceiverRingTeardown( Receiver = Ring->Receiver; + Ring->Dpcs = 0; + RtlZeroMemory(&Ring->Dpc, sizeof (KDPC)); + RtlZeroMemory(&Ring->EvtchnLock, sizeof (KSPIN_LOCK)); + Ring->OffloadOptions.Value = 0; ThreadAlert(Ring->WatchdogThread); @@ -2245,16 +2476,6 @@ __ReceiverRingTeardown( } static FORCEINLINE VOID -__ReceiverRingNotify( - IN PXENVIF_RECEIVER_RING Ring - ) -{ - __ReceiverRingAcquireLock(Ring); - ReceiverRingPoll(Ring); - __ReceiverRingReleaseLock(Ring); -} - -static FORCEINLINE VOID __ReceiverRingSetOffloadOptions( IN PXENVIF_RECEIVER_RING Ring, IN XENVIF_VIF_OFFLOAD_OPTIONS Options @@ -2313,6 +2534,7 @@ ReceiverInitialize( (*Receiver)->DisableIpVersion6Gso = 0; (*Receiver)->IpAlignOffset = 0; (*Receiver)->AlwaysPullup = 0; + (*Receiver)->Split = FALSE; if (ParametersKey != NULL) { ULONG ReceiverCalculateChecksums; @@ -2370,6 +2592,9 @@ ReceiverInitialize( FdoGetCacheInterface(PdoGetFdo(FrontendGetPdo(Frontend)), &(*Receiver)->CacheInterface); + FdoGetEvtchnInterface(PdoGetFdo(FrontendGetPdo(Frontend)), + &(*Receiver)->EvtchnInterface); + (*Receiver)->Frontend = Frontend; status = XENBUS_CACHE(Acquire, &(*Receiver)->CacheInterface); @@ -2411,6 +2636,9 @@ fail2: (*Receiver)->Frontend = NULL; + RtlZeroMemory(&(*Receiver)->EvtchnInterface, + sizeof (XENBUS_EVTCHN_INTERFACE)); + RtlZeroMemory(&(*Receiver)->CacheInterface, sizeof (XENBUS_CACHE_INTERFACE)); @@ -2428,6 +2656,7 @@ fail2: (*Receiver)->DisableIpVersion6Gso = 0; (*Receiver)->IpAlignOffset = 0; (*Receiver)->AlwaysPullup = 0; + (*Receiver)->Split = FALSE; ASSERT(IsZeroMemory(*Receiver, sizeof (XENVIF_RECEIVER))); __ReceiverFree(*Receiver); @@ -2445,6 +2674,7 @@ ReceiverConnect( { PXENVIF_FRONTEND Frontend; ULONG Index; + PCHAR Buffer; NTSTATUS status; Frontend = Receiver->Frontend; @@ -2457,6 +2687,26 @@ ReceiverConnect( if (!NT_SUCCESS(status)) goto fail2; + status = XENBUS_EVTCHN(Acquire, &Receiver->EvtchnInterface); + if (!NT_SUCCESS(status)) + goto fail3; + + status = XENBUS_STORE(Read, + &Receiver->StoreInterface, + NULL, + FrontendGetBackendPath(Frontend), + "feature-split-event-channels", + &Buffer); + if (!NT_SUCCESS(status)) { + Receiver->Split = FALSE; + } else { + Receiver->Split = (BOOLEAN)strtol(Buffer, NULL, 2); + + XENBUS_STORE(Free, + &Receiver->StoreInterface, + Buffer); + } + for (Index = 0; Index < MAXIMUM_PROCESSORS; ++Index) { PXENVIF_RECEIVER_RING Ring; @@ -2466,7 +2716,7 @@ ReceiverConnect( status = __ReceiverRingConnect(Ring); if (!NT_SUCCESS(status)) - goto fail3; + goto fail4; } status = XENBUS_DEBUG(Register, @@ -2476,16 +2726,16 @@ ReceiverConnect( Receiver, &Receiver->DebugCallback); if (!NT_SUCCESS(status)) - goto fail4; + goto fail5; return STATUS_SUCCESS; +fail5: + Error("fail5\n"); + fail4: Error("fail4\n"); -fail3: - Error("fail3\n"); - for (Index = 0; Index < MAXIMUM_PROCESSORS; ++Index) { PXENVIF_RECEIVER_RING Ring; @@ -2496,6 +2746,11 @@ fail3: __ReceiverRingDisconnect(Ring); } + XENBUS_EVTCHN(Release, &Receiver->EvtchnInterface); + +fail3: + Error("fail3\n"); + XENBUS_STORE(Release, &Receiver->StoreInterface); fail2: @@ -2747,6 +3002,8 @@ ReceiverDisconnect( Frontend = Receiver->Frontend; + Receiver->Split = FALSE; + XENBUS_DEBUG(Deregister, &Receiver->DebugInterface, Receiver->DebugCallback); @@ -2765,6 +3022,8 @@ ReceiverDisconnect( XENBUS_STORE(Release, &Receiver->StoreInterface); XENBUS_DEBUG(Release, &Receiver->DebugInterface); + + XENBUS_EVTCHN(Release, &Receiver->EvtchnInterface); } VOID @@ -2774,6 +3033,9 @@ ReceiverTeardown( { ULONG Index; + ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL); + KeFlushQueuedDpcs(); + ASSERT3U(Receiver->Returned, ==, Receiver->Loaned); Receiver->Loaned = 0; Receiver->Returned = 0; @@ -2793,6 +3055,10 @@ ReceiverTeardown( XENBUS_CACHE(Release, &Receiver->CacheInterface); Receiver->Frontend = NULL; + Receiver->Split = FALSE; + + RtlZeroMemory(&Receiver->EvtchnInterface, + sizeof (XENBUS_EVTCHN_INTERFACE)); RtlZeroMemory(&Receiver->CacheInterface, sizeof (XENBUS_CACHE_INTERFACE)); @@ -2921,19 +3187,37 @@ ReceiverWaitForPackets( } VOID -ReceiverNotify( - IN PXENVIF_RECEIVER Receiver +ReceiverRingTrigger( + IN PXENVIF_RECEIVER Receiver, + IN ULONG Index ) { - ULONG Index; + PXENVIF_RECEIVER_RING Ring; - for (Index = 0; Index < MAXIMUM_PROCESSORS; ++Index) { - PXENVIF_RECEIVER_RING Ring; + if (Index >= MAXIMUM_PROCESSORS) + return; - Ring = Receiver->Rings[Index]; - if (Ring == NULL) - break; + Ring = Receiver->Rings[Index]; + if (Ring == NULL) + return; - __ReceiverRingNotify(Ring); - } + __ReceiverRingTrigger(Ring); +} + +VOID +ReceiverRingSend( + IN PXENVIF_RECEIVER Receiver, + IN ULONG Index + ) +{ + PXENVIF_RECEIVER_RING Ring; + + if (Index >= MAXIMUM_PROCESSORS) + return; + + Ring = Receiver->Rings[Index]; + if (Ring == NULL) + return; + + __ReceiverRingSend(Ring); } diff --git a/src/xenvif/receiver.h b/src/xenvif/receiver.h index 0497c5b..f926500 100644 --- a/src/xenvif/receiver.h +++ b/src/xenvif/receiver.h @@ -79,11 +79,6 @@ ReceiverTeardown( ); extern VOID -ReceiverNotify( - IN PXENVIF_RECEIVER Receiver - ); - -extern VOID ReceiverWaitForPackets( IN PXENVIF_RECEIVER Receiver ); @@ -106,4 +101,16 @@ ReceiverReturnPackets( IN PLIST_ENTRY List ); +extern VOID +ReceiverRingTrigger( + IN PXENVIF_RECEIVER Receiver, + IN ULONG Index + ); + +extern VOID +ReceiverRingSend( + IN PXENVIF_RECEIVER Receiver, + IN ULONG Index + ); + #endif // _XENVIF_RECEIVER_H diff --git a/src/xenvif/transmitter.c b/src/xenvif/transmitter.c index 645872b..e482392 100644 --- a/src/xenvif/transmitter.c +++ b/src/xenvif/transmitter.c @@ -40,6 +40,7 @@ #include <cache_interface.h> #include <gnttab_interface.h> #include <range_set_interface.h> +#include <evtchn_interface.h> #include "ethernet.h" #include "tcpip.h" @@ -114,6 +115,11 @@ typedef struct _XENVIF_TRANSMITTER_RING { netif_tx_front_ring_t Front; netif_tx_sring_t *Shared; XENVIF_GRANTER_HANDLE Handle; + PXENBUS_EVTCHN_CHANNEL Channel; + KDPC Dpc; + ULONG Dpcs; + ULONG Events; + KSPIN_LOCK EvtchnLock; BOOLEAN Connected; BOOLEAN Enabled; BOOLEAN Stopped; @@ -145,8 +151,10 @@ struct _XENVIF_TRANSMITTER { PXENVIF_FRONTEND Frontend; XENBUS_CACHE_INTERFACE CacheInterface; XENBUS_RANGE_SET_INTERFACE RangeSetInterface; + XENBUS_EVTCHN_INTERFACE EvtchnInterface; PXENVIF_TRANSMITTER_RING Rings[MAXIMUM_PROCESSORS]; LONG_PTR Offset[XENVIF_TRANSMITTER_PACKET_OFFSET_COUNT]; + BOOLEAN Split; ULONG DisableIpVersion4Gso; ULONG DisableIpVersion6Gso; ULONG AlwaysCopy; @@ -2127,6 +2135,72 @@ TransmitterRingPoll( } static FORCEINLINE VOID +__TransmitterRingTrigger( + IN PXENVIF_TRANSMITTER_RING Ring + ) +{ + KIRQL Irql; + PXENVIF_TRANSMITTER Transmitter; + + Transmitter = Ring->Transmitter; + + KeAcquireSpinLock(&Ring->EvtchnLock, &Irql); + + if (Ring->Connected) { + if (Transmitter->Split) { + ASSERT(Ring->Channel != NULL); + + (VOID) XENBUS_EVTCHN(Trigger, + &Transmitter->EvtchnInterface, + Ring->Channel); + } else { + PXENVIF_FRONTEND Frontend; + + ASSERT(Ring->Channel == NULL); + Frontend = Transmitter->Frontend; + + ReceiverRingTrigger(FrontendGetReceiver(Frontend), + Ring->Index); + } + } + + KeReleaseSpinLock(&Ring->EvtchnLock, Irql); +} + +static FORCEINLINE VOID +__TransmitterRingSend( + IN PXENVIF_TRANSMITTER_RING Ring + ) +{ + KIRQL Irql; + PXENVIF_TRANSMITTER Transmitter; + + Transmitter = Ring->Transmitter; + + KeAcquireSpinLock(&Ring->EvtchnLock, &Irql); + + if (Ring->Connected) { + if (Transmitter->Split) { + ASSERT(Ring->Channel != NULL); + + (VOID) XENBUS_EVTCHN(Send, + &Transmitter->EvtchnInterface, + Ring->Channel); + } else { + PXENVIF_FRONTEND Frontend; + + ASSERT(Ring->Channel == NULL); + Frontend = Transmitter->Frontend; + + ReceiverRingSend(FrontendGetReceiver(Frontend), + Ring->Index); + } + } + + KeReleaseSpinLock(&Ring->EvtchnLock, Irql); +} + +static FORCEINLINE VOID __TransmitterRingPushRequests( IN PXENVIF_TRANSMITTER_RING Ring ) @@ -2145,13 +2219,7 @@ __TransmitterRingPushRequests( #pragma warning (pop) if (Notify) { - PXENVIF_TRANSMITTER Transmitter; - PXENVIF_FRONTEND Frontend; - - Transmitter = Ring->Transmitter; - Frontend = Transmitter->Frontend; - - NotifierSendTx(FrontendGetNotifier(Frontend)); + __TransmitterRingSend(Ring); } Ring->RequestsPushed = Ring->RequestsPosted; @@ -2475,6 +2543,97 @@ TransmitterRingReleaseLock( __TransmitterRingReleaseLock(Ring); } +static FORCEINLINE VOID +__TransmitterRingNotify( + IN PXENVIF_TRANSMITTER_RING Ring + ) +{ + __TransmitterRingAcquireLock(Ring); + TransmitterRingPoll(Ring); + __TransmitterRingReleaseLock(Ring); +} + +static FORCEINLINE BOOLEAN +__TransmitterRingUnmask( + IN PXENVIF_TRANSMITTER_RING Ring + ) +{ + PXENVIF_TRANSMITTER Transmitter; + BOOLEAN Pending; + + Transmitter = Ring->Transmitter; + + KeAcquireSpinLockAtDpcLevel(&Ring->EvtchnLock); + + Pending = (Ring->Connected) ? + XENBUS_EVTCHN(Unmask, + &Transmitter->EvtchnInterface, + Ring->Channel, + FALSE) : + FALSE; + + KeReleaseSpinLockFromDpcLevel(&Ring->EvtchnLock); + + return Pending; +} + +__drv_functionClass(KDEFERRED_ROUTINE) +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_minIRQL(DISPATCH_LEVEL) +__drv_requiresIRQL(DISPATCH_LEVEL) +__drv_sameIRQL +static VOID +TransmitterRingDpc( + IN PKDPC Dpc, + IN PVOID Context, + IN PVOID Argument1, + IN PVOID Argument2 + ) +{ + PXENVIF_TRANSMITTER_RING Ring = Context; + PXENVIF_TRANSMITTER Transmitter; + BOOLEAN Pending; + + UNREFERENCED_PARAMETER(Dpc); + UNREFERENCED_PARAMETER(Argument1); + UNREFERENCED_PARAMETER(Argument2); + + ASSERT(Ring != NULL); + + Transmitter = Ring->Transmitter; + + do { + if (Ring->Enabled) { + ASSERT(Transmitter->Split); + __TransmitterRingNotify(Ring); + } + + Pending = __TransmitterRingUnmask(Ring); + } while (Pending); +} + +KSERVICE_ROUTINE TransmitterRingEvtchnCallback; + +BOOLEAN +TransmitterRingEvtchnCallback( + IN PKINTERRUPT InterruptObject, + IN PVOID Argument + ) +{ + PXENVIF_TRANSMITTER_RING Ring = Argument; + + UNREFERENCED_PARAMETER(InterruptObject); + + ASSERT(Ring != NULL); + + Ring->Events++; + + if (KeInsertQueueDpc(&Ring->Dpc, NULL, NULL)) + Ring->Dpcs++; + + return TRUE; +} + #define TIME_US(_us) ((_us) * 10) #define TIME_MS(_ms) (TIME_US((_ms) * 1000)) #define TIME_S(_s) (TIME_MS((_s) * 1000)) @@ -2520,17 +2679,15 @@ TransmitterRingWatchdog( if (Ring->PacketsQueued == PacketsQueued && Ring->PacketsCompleted != PacketsQueued) { PXENVIF_TRANSMITTER Transmitter; - PXENVIF_FRONTEND Frontend; Transmitter = Ring->Transmitter; - Frontend = Transmitter->Frontend; XENBUS_DEBUG(Trigger, &Transmitter->DebugInterface, Ring->DebugCallback); // Try to move things along - NotifierSendTx(FrontendGetNotifier(Frontend)); + __TransmitterRingSend(Ring); TransmitterRingPoll(Ring); } @@ -2625,6 +2782,8 @@ __TransmitterRingInitialize( (*Ring)->Index = Index; (*Ring)->Queued.TailPacket = &(*Ring)->Queued.HeadPacket; (*Ring)->Completed.TailPacket = &(*Ring)->Completed.HeadPacket; + KeInitializeSpinLock(&(*Ring)->EvtchnLock); + KeInitializeDpc(&(*Ring)->Dpc, TransmitterRingDpc, *Ring); status = RtlStringCbPrintfA(Name, sizeof (Name), @@ -2755,6 +2914,9 @@ fail3: fail2: Error("fail2\n"); + RtlZeroMemory(&(*Ring)->Dpc, sizeof (KDPC)); + RtlZeroMemory(&(*Ring)->EvtchnLock, sizeof (KSPIN_LOCK)); + (*Ring)->Queued.TailPacket = NULL; (*Ring)->Completed.TailPacket = NULL; (*Ring)->Index = 0; @@ -2778,6 +2940,7 @@ __TransmitterRingConnect( PXENVIF_TRANSMITTER Transmitter; PXENVIF_FRONTEND Frontend; PFN_NUMBER Pfn; + BOOLEAN Pending; CHAR Name[MAXNAMELEN]; NTSTATUS status; @@ -2815,6 +2978,38 @@ __TransmitterRingConnect( if (!NT_SUCCESS(status)) goto fail3; + ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL); + KeAcquireSpinLockAtDpcLevel(&Ring->EvtchnLock); + + if (Transmitter->Split) { + Ring->Channel = XENBUS_EVTCHN(Open, + &Transmitter->EvtchnInterface, + XENBUS_EVTCHN_TYPE_UNBOUND, + TransmitterRingEvtchnCallback, + Ring, + FrontendGetBackendDomain(Frontend), + TRUE); + + status = STATUS_UNSUCCESSFUL; + if (Ring->Channel == NULL) { + KeReleaseSpinLockFromDpcLevel(&Ring->EvtchnLock); + goto fail4; + } + + Pending = XENBUS_EVTCHN(Unmask, + &Transmitter->EvtchnInterface, + Ring->Channel, + FALSE); + + if (Pending) + XENBUS_EVTCHN(Trigger, + &Transmitter->EvtchnInterface, + Ring->Channel); + } + + KeReleaseSpinLockFromDpcLevel(&Ring->EvtchnLock); + + status = XENBUS_DEBUG(Register, &Transmitter->DebugInterface, Name, @@ -2822,12 +3017,22 @@ __TransmitterRingConnect( Ring, &Ring->DebugCallback); if (!NT_SUCCESS(status)) - goto fail4; + goto fail5; Ring->Connected = TRUE; return STATUS_SUCCESS; +fail5: + Error("fail5\n"); + + XENBUS_EVTCHN(Close, + &Transmitter->EvtchnInterface, + Ring->Channel); + Ring->Channel = NULL; + + Ring->Events = 0; + fail4: Error("fail4\n"); @@ -2862,6 +3067,7 @@ __TransmitterRingStoreWrite( { PXENVIF_TRANSMITTER Transmitter; PXENVIF_FRONTEND Frontend; + ULONG Port; NTSTATUS status; Transmitter = Ring->Transmitter; @@ -2879,8 +3085,29 @@ __TransmitterRingStoreWrite( if (!NT_SUCCESS(status)) goto fail1; + if (!Transmitter->Split) + goto done; + + Port = XENBUS_EVTCHN(GetPort, + &Transmitter->EvtchnInterface, + Ring->Channel); + + status = XENBUS_STORE(Printf, + &Transmitter->StoreInterface, + Transaction, + FrontendGetPath(Frontend), + "event-channel-tx", + "%u", + Port); + if (!NT_SUCCESS(status)) + goto fail2; + +done: return STATUS_SUCCESS; +fail2: + Error("fail2\n"); + fail1: Error("fail1 (%08x)\n", status); @@ -2897,6 +3124,9 @@ __TransmitterRingEnable( ASSERT(!Ring->Enabled); Ring->Enabled = TRUE; + if (KeInsertQueueDpc(&Ring->Dpc, NULL, NULL)) + Ring->Dpcs++; + __TransmitterRingReleaseLock(Ring); return STATUS_SUCCESS; @@ -2992,6 +3222,21 @@ __TransmitterRingDisconnect( Transmitter = Ring->Transmitter; Frontend = Transmitter->Frontend; + KeAcquireSpinLockAtDpcLevel(&Ring->EvtchnLock); + + Transmitter->Split = FALSE; + + if (Ring->Channel != NULL) { + XENBUS_EVTCHN(Close, + &Transmitter->EvtchnInterface, + Ring->Channel); + Ring->Channel = NULL; + + Ring->Events = 0; + } + + KeReleaseSpinLockFromDpcLevel(&Ring->EvtchnLock); + ASSERT3U(Ring->ResponsesProcessed, ==, Ring->RequestsPushed); ASSERT3U(Ring->RequestsPushed, ==, Ring->RequestsPosted); @@ -3028,6 +3273,10 @@ __TransmitterRingTeardown( Transmitter = Ring->Transmitter; Frontend = Transmitter->Frontend; + Ring->Dpcs = 0; + RtlZeroMemory(&Ring->Dpc, sizeof (KDPC)); + RtlZeroMemory(&Ring->EvtchnLock, sizeof (KSPIN_LOCK)); + ASSERT3U(Ring->PacketsCompleted, ==, Ring->PacketsSent); ASSERT3U(Ring->PacketsSent, ==, Ring->PacketsPrepared - Ring->PacketsUnprepared); ASSERT3U(Ring->PacketsPrepared, ==, Ring->PacketsCopied + Ring->PacketsGranted + Ring->PacketsFaked); @@ -3164,16 +3413,6 @@ __TransmitterRingAbortPackets( __TransmitterRingReleaseLock(Ring); } -static FORCEINLINE VOID -__TransmitterRingNotify( - IN PXENVIF_TRANSMITTER_RING Ring - ) -{ - __TransmitterRingAcquireLock(Ring); - TransmitterRingPoll(Ring); - __TransmitterRingReleaseLock(Ring); -} - static VOID TransmitterDebugCallback( IN PVOID Argument, @@ -3214,6 +3453,7 @@ TransmitterInitialize( (*Transmitter)->DisableIpVersion4Gso = 0; (*Transmitter)->DisableIpVersion6Gso = 0; (*Transmitter)->AlwaysCopy = 0; + (*Transmitter)->Split = FALSE; if (ParametersKey != NULL) { ULONG TransmitterDisableIpVersion4Gso; @@ -3251,6 +3491,9 @@ TransmitterInitialize( FdoGetCacheInterface(PdoGetFdo(FrontendGetPdo(Frontend)), &(*Transmitter)->CacheInterface); + FdoGetEvtchnInterface(PdoGetFdo(FrontendGetPdo(Frontend)), + &(*Transmitter)->EvtchnInterface); + (*Transmitter)->Frontend = Frontend; status = XENBUS_RANGE_SET(Acquire, &(*Transmitter)->RangeSetInterface); @@ -3332,6 +3575,7 @@ TransmitterConnect( ) { PXENVIF_FRONTEND Frontend; + PCHAR Buffer; ULONG Index; NTSTATUS status; @@ -3345,6 +3589,26 @@ TransmitterConnect( if (!NT_SUCCESS(status)) goto fail2; + status = XENBUS_EVTCHN(Acquire, &Transmitter->EvtchnInterface); + if (!NT_SUCCESS(status)) + goto fail3; + + status = XENBUS_STORE(Read, + &Transmitter->StoreInterface, + NULL, + FrontendGetBackendPath(Frontend), + "feature-split-event-channels", + &Buffer); + if (!NT_SUCCESS(status)) { + Transmitter->Split = FALSE; + } else { + Transmitter->Split = (BOOLEAN)strtol(Buffer, NULL, 2); + + XENBUS_STORE(Free, + &Transmitter->StoreInterface, + Buffer); + } + for (Index = 0; Index < MAXIMUM_PROCESSORS; ++Index) { PXENVIF_TRANSMITTER_RING Ring; @@ -3354,7 +3618,7 @@ TransmitterConnect( status = __TransmitterRingConnect(Ring); if (!NT_SUCCESS(status)) - goto fail3; + goto fail4; } status = XENBUS_DEBUG(Register, @@ -3364,16 +3628,16 @@ TransmitterConnect( Transmitter, &Transmitter->DebugCallback); if (!NT_SUCCESS(status)) - goto fail4; + goto fail5; return STATUS_SUCCESS; +fail5: + Error("fail5\n"); + fail4: Error("fail4\n"); -fail3: - Error("fail3\n"); - for (Index = 0; Index < MAXIMUM_PROCESSORS; ++Index) { PXENVIF_TRANSMITTER_RING Ring; @@ -3384,6 +3648,11 @@ fail3: __TransmitterRingDisconnect(Ring); } + XENBUS_EVTCHN(Release, &Transmitter->EvtchnInterface); + +fail3: + Error("fail3\n"); + XENBUS_STORE(Release, &Transmitter->StoreInterface); fail2: @@ -3474,6 +3743,8 @@ TransmitterDisconnect( Frontend = Transmitter->Frontend; + Transmitter->Split = FALSE; + XENBUS_DEBUG(Deregister, &Transmitter->DebugInterface, Transmitter->DebugCallback); @@ -3492,6 +3763,8 @@ TransmitterDisconnect( XENBUS_STORE(Release, &Transmitter->StoreInterface); XENBUS_DEBUG(Release, &Transmitter->DebugInterface); + + XENBUS_EVTCHN(Release, &Transmitter->EvtchnInterface); } VOID @@ -3501,6 +3774,9 @@ TransmitterTeardown( { ULONG Index; + ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL); + KeFlushQueuedDpcs(); + RtlZeroMemory(Transmitter->Offset, sizeof (LONG_PTR) * XENVIF_TRANSMITTER_PACKET_OFFSET_COUNT); @@ -3521,6 +3797,7 @@ TransmitterTeardown( XENBUS_RANGE_SET(Release, &Transmitter->RangeSetInterface); Transmitter->Frontend = NULL; + Transmitter->Split = FALSE; RtlZeroMemory(&Transmitter->CacheInterface, sizeof (XENBUS_CACHE_INTERFACE)); @@ -3534,6 +3811,9 @@ TransmitterTeardown( RtlZeroMemory(&Transmitter->DebugInterface, sizeof (XENBUS_DEBUG_INTERFACE)); + RtlZeroMemory(&Transmitter->EvtchnInterface, + sizeof (XENBUS_EVTCHN_INTERFACE)); + Transmitter->DisableIpVersion4Gso = 0; Transmitter->DisableIpVersion6Gso = 0; Transmitter->AlwaysCopy = 0; @@ -3652,21 +3932,21 @@ TransmitterQueryRingSize( } VOID -TransmitterNotify( - IN PXENVIF_TRANSMITTER Transmitter +TransmitterRingNotify( + IN PXENVIF_TRANSMITTER Transmitter, + IN ULONG Index ) { - ULONG Index; + PXENVIF_TRANSMITTER_RING Ring; - for (Index = 0; Index < MAXIMUM_PROCESSORS; ++Index) { - PXENVIF_TRANSMITTER_RING Ring; + if (Index >= MAXIMUM_PROCESSORS) + return; - Ring = Transmitter->Rings[Index]; - if (Ring == NULL) - break; + Ring = Transmitter->Rings[Index]; + if (Ring == NULL) + return; - __TransmitterRingNotify(Ring); - } + __TransmitterRingNotify(Ring); } VOID diff --git a/src/xenvif/transmitter.h b/src/xenvif/transmitter.h index 5ffb590..9c3bfaa 100644 --- a/src/xenvif/transmitter.h +++ b/src/xenvif/transmitter.h @@ -79,8 +79,9 @@ TransmitterTeardown( ); extern VOID -TransmitterNotify( - IN PXENVIF_TRANSMITTER Transmitter +TransmitterRingNotify( + IN PXENVIF_TRANSMITTER Transmitter, + IN ULONG Index ); extern VOID diff --git a/vs2012/xenvif/xenvif.vcxproj b/vs2012/xenvif/xenvif.vcxproj index a86acff..edd71ea 100644 --- a/vs2012/xenvif/xenvif.vcxproj +++ b/vs2012/xenvif/xenvif.vcxproj @@ -96,7 +96,6 @@ <ClCompile Include="../../src/xenvif/granter.c" /> <ClCompile Include="../../src/xenvif/link.c" /> <ClCompile Include="../../src/xenvif/mac.c" /> - <ClCompile Include="../../src/xenvif/notifier.c" /> <ClCompile Include="../../src/xenvif/parse.c" /> <ClCompile Include="../../src/xenvif/pdo.c" /> <ClCompile Include="../../src/xenvif/receiver.c" /> diff --git a/vs2013/xenvif/xenvif.vcxproj b/vs2013/xenvif/xenvif.vcxproj index 69cf86a..32a3033 100644 --- a/vs2013/xenvif/xenvif.vcxproj +++ b/vs2013/xenvif/xenvif.vcxproj @@ -127,7 +127,6 @@ <ClCompile Include="../../src/xenvif/granter.c" /> <ClCompile Include="../../src/xenvif/link.c" /> <ClCompile Include="../../src/xenvif/mac.c" /> - <ClCompile Include="../../src/xenvif/notifier.c" /> <ClCompile Include="../../src/xenvif/parse.c" /> <ClCompile Include="../../src/xenvif/pdo.c" /> <ClCompile Include="../../src/xenvif/receiver.c" /> -- 1.9.4.msysgit.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 |