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

Re: [win-pv-devel] [PATCH 01/10] Rework transmitter packet code to use an internal cache of objects



> -----Original Message-----
> From: Owen Smith [mailto:owen.smith@xxxxxxxxxx]
> Sent: 12 November 2014 16:39
> To: win-pv-devel@xxxxxxxxxxxxxxxxxxxx
> Cc: Paul Durrant; Owen Smith
> Subject: [PATCH 01/10] Rework transmitter packet code to use an internal
> cache of objects
> 
> Use XENVIF_TRANSMITTER_PACKET_V2 for queueing packets, with a
> translation on entry and exit through the interface (for v1)
> Renames XENVIF_TRANSMITTER_PACKET to
> XENVIF_TRANSMITTER_PACKET_V1
> XENVIF_TRANSMITTER_PACKET_V2 is allocated from a cache and not
> included inline in the miniport reserved area of a NET_BUFFER, like
> XENVIF_TRANSMITTER_PACKET_V1.
> 
> Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx>
> ---
>  include/vif_interface.h  |  37 ++--
>  src/xenvif/transmitter.c | 477 ++++++++++++++++++++++++++++++++-----
> ----------
>  src/xenvif/transmitter.h |   6 +-
>  src/xenvif/vif.c         |  12 +-
>  src/xenvif/vif.h         |   4 +-
>  5 files changed, 368 insertions(+), 168 deletions(-)
> 
> diff --git a/include/vif_interface.h b/include/vif_interface.h
> index 498ed8f..8bde731 100644
> --- a/include/vif_interface.h
> +++ b/include/vif_interface.h
> @@ -257,7 +257,7 @@ struct _XENVIF_TRANSMITTER_PACKET_V1 {
>      };
>  };
> 
> -typedef struct _XENVIF_TRANSMITTER_PACKET_V1
> XENVIF_TRANSMITTER_PACKET, *PXENVIF_TRANSMITTER_PACKET;
> +typedef struct _XENVIF_TRANSMITTER_PACKET_V1
> XENVIF_TRANSMITTER_PACKET_V1, *PXENVIF_TRANSMITTER_PACKET_V1;
> 
>  #pragma warning(pop)
> 
> @@ -265,9 +265,24 @@ typedef struct _XENVIF_TRANSMITTER_PACKET_V1
> XENVIF_TRANSMITTER_PACKET, *PXENVIF
> 
>  C_ASSERT(sizeof (struct _XENVIF_TRANSMITTER_PACKET_V1) <= (3 * sizeof
> (PVOID)));
> 
> +/*! \struct _XENVIF_TRANSMITTER_PACKER_V2
> +    \brief Transmit-side packet structure
> +*/
> +struct _XENVIF_TRANSMITTER_PACKET_V2 {
> +    LIST_ENTRY                                  ListEntry;
> +    PMDL                                        Mdl;
> +    ULONG                                       Offset;
> +    ULONG                                       Length;
> +    PVOID                                       Cookie;
> +    XENVIF_TRANSMITTER_PACKET_SEND_INFO         Send;
> +    XENVIF_TRANSMITTER_PACKET_COMPLETION_INFO   Completion;
> +};
> +
> +typedef struct _XENVIF_TRANSMITTER_PACKET_V2
> XENVIF_TRANSMITTER_PACKET_V2, *PXENVIF_TRANSMITTER_PACKET_V2;
> +

No. The typedef should make V2 the new XENVIF_TRANSMITTER_PACKET - there should 
be no need for a suffix as a subscriber should only ever use the latest 
versions of the types anyway.

>  /*! \enum _XENVIF_TRANSMITTER_PACKET_OFFSET
>      \brief Offsets of packet metadata relative to
> -    XENVIF_TRANSMITTER_PACKET pointer
> +    XENVIF_TRANSMITTER_PACKET_V1 pointer
> 
>      Because the transmit side packet structure is limited to 3 pointer
>      types in size, not all information about the packet can be passed in
> @@ -380,10 +395,10 @@ typedef VOID
>      \param ... Additional paramaters required by \a Type
> 
>      \b XENVIF_TRANSMITTER_RETURN_PACKETS:
> -    \param Head The head of a chain of XENVIF_TRANSMITTER_PACKET
> +    \param Head The head of a chain of XENVIF_TRANSMITTER_PACKET_V1

Really? How are v2 packets returned?

> 
>      \b XENVIF_RECEIVER_QUEUE_PACKETS:
> -    \param List List of XENVIF_TRANSMITTER_PACKET
> +    \param List List of XENVIF_RECEIVER_PACKET
> 
>      \b XENVIF_MAC_STATE_CHANGE:
>      No additional arguments
> @@ -459,7 +474,7 @@ typedef VOID
> 
>  /*! \typedef XENVIF_VIF_TRANSMITTER_SET_PACKET_OFFSET
>      \brief Set byte offset of packet information relative to
> -    XENVIF_TRANSMITTER_PACKET pointer.
> +    XENVIF_TRANSMITTER_PACKET_V1 pointer.
> 
>      See \ref _XENVIF_TRANSMITTER_PACKET_OFFSET.
> 
> @@ -474,16 +489,16 @@ typedef NTSTATUS
>      IN  LONG_PTR                            Value
>      );
> 
> -/*! \typedef XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS
> +/*! \typedef XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS_V1
>      \brief Queue transmit side packets at the provider
> 
>      \param Interface The interface header
> -    \param Head The head of a chain of XENVIF_TRANSMITTER_PACKET
> +    \param Head The head of a chain of XENVIF_TRANSMITTER_PACKET_V1
>  */
>  typedef NTSTATUS
> -(*XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS)(
> -    IN  PINTERFACE                  Interface,
> -    IN  PXENVIF_TRANSMITTER_PACKET  Head
> +(*XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS_V1)(
> +    IN  PINTERFACE                      Interface,
> +    IN  PXENVIF_TRANSMITTER_PACKET_V1   Head
>      );
> 
>  /*! \typedef XENVIF_VIF_TRANSMITTER_QUERY_OFFLOAD_OPTIONS
> @@ -694,7 +709,7 @@ struct _XENVIF_VIF_INTERFACE_V1 {
>      XENVIF_VIF_RECEIVER_SET_OFFLOAD_OPTIONS
> ReceiverSetOffloadOptions;
>      XENVIF_VIF_RECEIVER_QUERY_RING_SIZE             ReceiverQueryRingSize;
>      XENVIF_VIF_TRANSMITTER_SET_PACKET_OFFSET
> TransmitterSetPacketOffset;
> -    XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS
> TransmitterQueuePackets;
> +    XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS_V1
> TransmitterQueuePackets;
>      XENVIF_VIF_TRANSMITTER_QUERY_OFFLOAD_OPTIONS
> TransmitterQueryOffloadOptions;
>      XENVIF_VIF_TRANSMITTER_QUERY_LARGE_PACKET_SIZE
> TransmitterQueryLargePacketSize;
>      XENVIF_VIF_TRANSMITTER_QUERY_RING_SIZE
> TransmitterQueryRingSize;

Where's the v2 interface?

> diff --git a/src/xenvif/transmitter.c b/src/xenvif/transmitter.c
> index 8125a5a..38e4cb2 100644
> --- a/src/xenvif/transmitter.c
> +++ b/src/xenvif/transmitter.c
> @@ -88,7 +88,7 @@ typedef struct _XENVIF_TRANSMITTER_FRAGMENT {
>  #define XENVIF_TRANSMITTER_MAXIMUM_FRAGMENT_ID  0x03FF
> 
>  typedef struct _XENVIF_TRANSMITTER_STATE {
> -    PXENVIF_TRANSMITTER_PACKET          Packet;
> +    PXENVIF_TRANSMITTER_PACKET_V2       Packet;
>      XENVIF_TRANSMITTER_PACKET_SEND_INFO Send;
>      PUCHAR                              StartVa;
>      XENVIF_PACKET_INFO                  Info;
> @@ -100,8 +100,8 @@ typedef struct _XENVIF_TRANSMITTER_STATE {
>  #define XENVIF_TRANSMITTER_RING_SIZE   (__CONST_RING_SIZE(netif_tx,
> PAGE_SIZE))
> 
>  typedef struct _XENVIF_TRANSMITTER_PACKET_LIST {
> -    PXENVIF_TRANSMITTER_PACKET  HeadPacket;
> -    PXENVIF_TRANSMITTER_PACKET  *TailPacket;
> +    PLIST_ENTRY                     HeadEntry;
> +    PLIST_ENTRY                     *TailEntry;

Why do you need a tail pointer for a doubly linked list?

>  } XENVIF_TRANSMITTER_PACKET_LIST,
> *PXENVIF_TRANSMITTER_PACKET_LIST;
> 
>  typedef struct _XENVIF_TRANSMITTER_RING {
> @@ -118,7 +118,7 @@ typedef struct _XENVIF_TRANSMITTER_RING {
>      BOOLEAN                         Connected;
>      BOOLEAN                         Enabled;
>      BOOLEAN                         Stopped;
> -    PXENVIF_TRANSMITTER_PACKET      Lock;
> +    PLIST_ENTRY                     Lock;
>      PKTHREAD                        LockThread;
>      XENVIF_TRANSMITTER_PACKET_LIST  Queued;
>      XENVIF_TRANSMITTER_STATE        State;
> @@ -133,7 +133,7 @@ typedef struct _XENVIF_TRANSMITTER_RING {
>      ULONG                           RequestsPushed;
>      ULONG                           ResponsesProcessed;
>      ULONG                           PacketsSent;
> -    XENVIF_TRANSMITTER_PACKET_LIST  Completed;
> +    LIST_ENTRY                      Completed;
>      ULONG                           PacketsCompleted;
>      PSOCKADDR_INET                  AddressTable;
>      ULONG                           AddressCount;
> @@ -146,6 +146,7 @@ struct _XENVIF_TRANSMITTER {
>      PXENVIF_FRONTEND            Frontend;
>      XENBUS_CACHE_INTERFACE      CacheInterface;
>      XENBUS_RANGE_SET_INTERFACE  RangeSetInterface;
> +    PXENBUS_CACHE               PacketCache;
>      LIST_ENTRY                  List;
>      LONG_PTR
> Offset[XENVIF_TRANSMITTER_PACKET_OFFSET_COUNT];
>      ULONG                       DisableIpVersion4Gso;
> @@ -362,7 +363,7 @@ __TransmitterGetFragment(
>                          TRUE);
>  }
> 
> -static FORCEINLINE
> +static FORCEINLINE VOID
>  __TransmitterPutFragment(
>      IN  PXENVIF_TRANSMITTER_RING        Ring,
>      IN  PXENVIF_TRANSMITTER_FRAGMENT    Fragment
> @@ -387,6 +388,67 @@ __TransmitterPutFragment(
>                   TRUE);
>  }
> 
> +static NTSTATUS
> +TransmitterPacketCtor(
> +    IN  PVOID                       Argument,
> +    IN  PVOID                       Object
> +    )
> +{
> +    UNREFERENCED_PARAMETER(Argument);
> +    RtlZeroMemory(Object, sizeof(XENVIF_TRANSMITTER_PACKET_V2));

You should not need to zero the buffer. The object cache will zero on 
allocation. You should zero before calling the cache Put.

> +    return STATUS_SUCCESS;
> +}
> +
> +static VOID
> +TransmitterPacketDtor(
> +    IN  PVOID                       Argument,
> +    IN  PVOID                       Object
> +    )
> +{
> +    UNREFERENCED_PARAMETER(Argument);
> +    UNREFERENCED_PARAMETER(Object);
> +}
> +
> +static VOID
> +TransmitterPacketLock(
> +    IN  PVOID                       Argument
> +    )
> +{
> +    UNREFERENCED_PARAMETER(Argument);
> +}
> +
> +static VOID
> +TransmitterPacketUnlock(
> +    IN  PVOID                       Argument
> +    )
> +{
> +    UNREFERENCED_PARAMETER(Argument);
> +}
> +
> +static FORCEINLINE PXENVIF_TRANSMITTER_PACKET_V2
> +__TransmitterGetPacket(
> +    IN  PXENVIF_TRANSMITTER         Transmitter
> +    )
> +{
> +    return XENBUS_CACHE(Get,
> +                        &Transmitter->CacheInterface,
> +                        Transmitter->PacketCache,
> +                        TRUE);
> +}
> +
> +static FORCEINLINE VOID
> +__TransmitterPutPacket(
> +    IN  PXENVIF_TRANSMITTER             Transmitter,
> +    IN  PXENVIF_TRANSMITTER_PACKET_V2   Packet
> +    )
> +{
> +    XENBUS_CACHE(Put,
> +                 &Transmitter->CacheInterface,
> +                 Transmitter->PacketCache,
> +                 Packet,
> +                 TRUE);
> +}
> +
>  static VOID
>  TransmitterRingDebugCallback(
>      IN  PVOID                   Argument,
> @@ -523,25 +585,25 @@ fail1:
>      return FALSE;
>  }
> 
> -#define INCREMENT_PACKET_REFERENCE(_Packet)                         \
> -        do {                                                        \
> -            PULONG_PTR Reference = (PULONG_PTR)&(_Packet)->Next;    \
> -                                                                    \
> -            ASSERT(Packet != NULL);                                 \
> -            (*Reference)++;                                         \
> +#define INCREMENT_PACKET_REFERENCE(_Packet)                                 \
> +        do {                                                                \
> +            PULONG_PTR Reference = (PULONG_PTR)&(_Packet)-
> >ListEntry.Flink; \
> +                                                                            \
> +            ASSERT(Packet != NULL);                                         \
> +            (*Reference)++;                                                 \
>          } while (FALSE)
> 
> -#define DECREMENT_PACKET_REFERENCE(_Packet)                         \
> -        do {                                                        \
> -            PULONG_PTR Reference = (PULONG_PTR)&(_Packet)->Next;    \
> -                                                                    \
> -            ASSERT(Packet != NULL);                                 \
> -            ASSERT(*Reference != 0);                                \
> -            --(*Reference);                                         \
> +#define DECREMENT_PACKET_REFERENCE(_Packet)                                 \
> +        do {                                                                \
> +            PULONG_PTR Reference = (PULONG_PTR)&(_Packet)-
> >ListEntry.Flink; \
> +                                                                            \
> +            ASSERT(Packet != NULL);                                         \
> +            ASSERT(*Reference != 0);                                        \
> +            --(*Reference);                                                 \
>          } while (FALSE)
> 
> -#define PACKET_REFERENCE(_Packet)                                   \
> -        (*(PULONG_PTR)&(_Packet)->Next)
> +#define PACKET_REFERENCE(_Packet)                                           \
> +        (*(PULONG_PTR)&(_Packet)->ListEntry.Flink)
> 
>  static FORCEINLINE NTSTATUS
>  __TransmitterRingCopyPayload(
> @@ -551,7 +613,7 @@ __TransmitterRingCopyPayload(
>      PXENVIF_TRANSMITTER             Transmitter;
>      PXENVIF_FRONTEND                Frontend;
>      PXENVIF_TRANSMITTER_STATE       State;
> -    PXENVIF_TRANSMITTER_PACKET      Packet;
> +    PXENVIF_TRANSMITTER_PACKET_V2   Packet;
>      XENVIF_PACKET_PAYLOAD           Payload;
>      PXENVIF_TRANSMITTER_FRAGMENT    Fragment;
>      PXENVIF_TRANSMITTER_BUFFER      Buffer;
> @@ -698,7 +760,7 @@ __TransmitterRingGrantPayload(
>      PXENVIF_TRANSMITTER             Transmitter;
>      PXENVIF_FRONTEND                Frontend;
>      PXENVIF_TRANSMITTER_STATE       State;
> -    PXENVIF_TRANSMITTER_PACKET      Packet;
> +    PXENVIF_TRANSMITTER_PACKET_V2   Packet;
>      PXENVIF_PACKET_PAYLOAD          Payload;
>      PMDL                            Mdl;
>      ULONG                           Offset;
> @@ -845,7 +907,7 @@ __TransmitterRingPrepareHeader(
>      PXENVIF_FRONTEND                Frontend;
>      PXENVIF_MAC                     Mac;
>      PXENVIF_TRANSMITTER_STATE       State;
> -    PXENVIF_TRANSMITTER_PACKET      Packet;
> +    PXENVIF_TRANSMITTER_PACKET_V2   Packet;
>      PXENVIF_PACKET_PAYLOAD          Payload;
>      PXENVIF_PACKET_INFO             Info;
>      PXENVIF_TRANSMITTER_FRAGMENT    Fragment;
> @@ -1122,7 +1184,7 @@ __TransmitterRingUnprepareFragments(
>      while (State->Count != 0) {
>          PLIST_ENTRY                     ListEntry;
>          PXENVIF_TRANSMITTER_FRAGMENT    Fragment;
> -        PXENVIF_TRANSMITTER_PACKET      Packet;
> +        PXENVIF_TRANSMITTER_PACKET_V2   Packet;
> 
>          --State->Count;
> 
> @@ -1178,19 +1240,10 @@ __TransmitterRingUnprepareFragments(
> 
>  static FORCEINLINE NTSTATUS
>  __TransmitterRingPreparePacket(
> -    IN  PXENVIF_TRANSMITTER_RING    Ring,
> -    IN  PXENVIF_TRANSMITTER_PACKET  Packet
> +    IN  PXENVIF_TRANSMITTER_RING        Ring,
> +    IN  PXENVIF_TRANSMITTER_PACKET_V2   Packet
>      )
>  {
> -#define OFFSET_EXISTS(_Ring, _Packet, _Type)                                 
>                        \
> -    ((_Ring)->Transmitter->Offset[XENVIF_TRANSMITTER_PACKET_ ## _Type
> ## _OFFSET] != 0)
> -
> -#define OFFSET(_Ring, _Packet, _Type)                                        
>                        \
> -        ((OFFSET_EXISTS(_Ring, _Packet, _Type)) ?                            
>                        \
> -         (PVOID)((PUCHAR)(_Packet) +                                         
>                        \
> -                 (_Ring)->Transmitter->Offset[XENVIF_TRANSMITTER_PACKET_ ##
> _Type ## _OFFSET]) :    \
> -         NULL)
> -
>      PXENVIF_TRANSMITTER             Transmitter;
>      PXENVIF_TRANSMITTER_STATE       State;
>      PXENVIF_PACKET_PAYLOAD          Payload;
> @@ -1198,7 +1251,7 @@ __TransmitterRingPreparePacket(
>      NTSTATUS                        status;
> 
>      ASSERT(IsZeroMemory(&Ring->State, sizeof
> (XENVIF_TRANSMITTER_STATE)));
> -    ASSERT3P(Packet->Next, ==, NULL);
> +    ASSERT3P(Packet->ListEntry.Flink, ==, NULL);
> 
>      Transmitter = Ring->Transmitter;
> 
> @@ -1211,16 +1264,9 @@ __TransmitterRingPreparePacket(
> 
>      Payload = &State->Payload;
> 
> -    ASSERT(OFFSET_EXISTS(Ring, Packet, MDL));
> -    Payload->Mdl = *(PMDL *)OFFSET(Ring, Packet, MDL);
> -
> -    if (OFFSET_EXISTS(Ring, Packet, OFFSET))
> -        Payload->Offset = *(PULONG)OFFSET(Ring, Packet, OFFSET);
> -    else
> -        Payload->Offset = 0;
> -
> -    ASSERT(OFFSET_EXISTS(Ring, Packet, LENGTH));
> -    Payload->Length = *(PULONG)OFFSET(Ring, Packet, LENGTH);
> +    Payload->Mdl = Packet->Mdl;
> +    Payload->Offset = Packet->Offset;
> +    Payload->Length = Packet->Length;
> 
>      InitializeListHead(&State->List);
>      ASSERT3U(State->Count, ==, 0);
> @@ -1325,18 +1371,15 @@ fail1:
>      ASSERT(IsZeroMemory(&Ring->State, sizeof
> (XENVIF_TRANSMITTER_STATE)));
> 
>      return status;
> -
> -#undef  OFFSET
> -#undef  OFFSET_EXISTS
>  }
> 
> -static FORCEINLINE PXENVIF_TRANSMITTER_PACKET
> +static FORCEINLINE PXENVIF_TRANSMITTER_PACKET_V2
>  __TransmitterRingUnpreparePacket(
>      IN  PXENVIF_TRANSMITTER_RING    Ring
>      )
>  {
>      PXENVIF_TRANSMITTER_STATE       State;
> -    PXENVIF_TRANSMITTER_PACKET      Packet;
> +    PXENVIF_TRANSMITTER_PACKET_V2   Packet;
> 
>      State = &Ring->State;
>      Packet = State->Packet;
> @@ -1695,7 +1738,7 @@ __TransmitterRingPostFragments(
>      PXENVIF_TRANSMITTER             Transmitter;
>      PXENVIF_FRONTEND                Frontend;
>      PXENVIF_TRANSMITTER_STATE       State;
> -    PXENVIF_TRANSMITTER_PACKET      Packet;
> +    PXENVIF_TRANSMITTER_PACKET_V2   Packet;
>      PXENVIF_PACKET_PAYLOAD          Payload;
>      RING_IDX                        req_prod;
>      RING_IDX                        rsp_cons;
> @@ -1920,8 +1963,8 @@ __TransmitterRingFakeResponses(
> 
>  static FORCEINLINE VOID
>  __TransmitterRingCompletePacket(
> -    IN  PXENVIF_TRANSMITTER_RING    Ring,
> -    IN  PXENVIF_TRANSMITTER_PACKET  Packet
> +    IN  PXENVIF_TRANSMITTER_RING        Ring,
> +    IN  PXENVIF_TRANSMITTER_PACKET_V2   Packet
>      )
>  {
>      PXENVIF_TRANSMITTER             Transmitter;
> @@ -1980,9 +2023,9 @@ __TransmitterRingCompletePacket(
>          }
>      }
> 
> -    *Ring->Completed.TailPacket = Packet;
> -    ASSERT3P(Packet->Next, ==, NULL);
> -    Ring->Completed.TailPacket = &Packet->Next;
> +    ASSERT3P(Packet->ListEntry.Flink, ==, NULL);
> +    ASSERT3P(Packet->ListEntry.Blink, ==, NULL);
> +    InsertTailList(&Ring->Completed, &Packet->ListEntry);
> 
>      Ring->PacketsCompleted++;
>  }
> @@ -2019,7 +2062,7 @@ TransmitterRingPoll(
>              netif_tx_response_t             *rsp;
>              uint16_t                        id;
>              PXENVIF_TRANSMITTER_FRAGMENT    Fragment;
> -            PXENVIF_TRANSMITTER_PACKET      Packet;
> +            PXENVIF_TRANSMITTER_PACKET_V2   Packet;
> 
>              rsp = RING_GET_RESPONSE(&Ring->Front, rsp_cons);
>              rsp_cons++;
> @@ -2164,30 +2207,30 @@ __TransmitterRingPushRequests(
> 
>  static FORCEINLINE ULONG
>  __TransmitterReversePacketList(
> -    IN  PXENVIF_TRANSMITTER_PACKET  *Packet
> +    IN  PLIST_ENTRY                 *Entry
>      )
>  {
> -    PXENVIF_TRANSMITTER_PACKET      HeadPacket;
> +    PLIST_ENTRY                     HeadEntry;
>      ULONG                           Count;
> 
> -    HeadPacket = NULL;
> +    HeadEntry = NULL;
>      Count = 0;
> 
> -    while (*Packet != NULL) {
> -        PXENVIF_TRANSMITTER_PACKET  Next;
> +    while (*Entry != NULL) {
> +        PLIST_ENTRY     Next;
> 
> -        ASSERT(((ULONG_PTR)*Packet & XENVIF_TRANSMITTER_LOCK_BIT) ==
> 0);
> +        ASSERT(((ULONG_PTR)*Entry & XENVIF_TRANSMITTER_LOCK_BIT) ==
> 0);
> 
> -        Next = (*Packet)->Next;
> +        Next = (*Entry)->Flink;
> 
> -        (*Packet)->Next = HeadPacket;
> -        HeadPacket = *Packet;
> +        (*Entry)->Flink = HeadEntry;
> +        HeadEntry = *Entry;
> 
> -        *Packet = Next;
> +        *Entry = Next;
>          Count++;
>      }
> 
> -    *Packet = HeadPacket;
> +    *Entry = HeadEntry;

Are packets singly linked or doubly linked on the way into this function?

> 
>      return Count;
>  }
> @@ -2199,8 +2242,8 @@ TransmitterRingSwizzle(
>  {
>      ULONG_PTR                       Old;
>      ULONG_PTR                       New;
> -    PXENVIF_TRANSMITTER_PACKET      HeadPacket;
> -    PXENVIF_TRANSMITTER_PACKET      *TailPacket;
> +    PLIST_ENTRY                     HeadEntry;
> +    PLIST_ENTRY                     *TailEntry;
>      ULONG                           Count;
> 
>      ASSERT3P(Ring->LockThread, ==, KeGetCurrentThread());
> @@ -2209,21 +2252,21 @@ TransmitterRingSwizzle(
>      Old = (ULONG_PTR)InterlockedExchangePointer(&Ring->Lock,
> (PVOID)New);
> 
>      ASSERT(Old & XENVIF_TRANSMITTER_LOCK_BIT);
> -    HeadPacket = (PVOID)(Old & ~XENVIF_TRANSMITTER_LOCK_BIT);
> +    HeadEntry = (PVOID)(Old & ~XENVIF_TRANSMITTER_LOCK_BIT);
> 
> -    if (HeadPacket == NULL)
> +    if (HeadEntry == NULL)
>          return;
> 
>      // Packets are held in the atomic packet list in reverse order
>      // so that the most recent is always head of the list. This is
>      // necessary to allow addition to the list to be done atomically.
> 
> -    TailPacket = &HeadPacket->Next;
> -    Count = __TransmitterReversePacketList(&HeadPacket);
> -    ASSERT3P(*TailPacket, ==, NULL);
> +    TailEntry = &HeadEntry->Flink;
> +    Count = __TransmitterReversePacketList(&HeadEntry);
> +    ASSERT3P(*TailEntry, ==, NULL);
> 
> -    *(Ring->Queued.TailPacket) = HeadPacket;
> -    Ring->Queued.TailPacket = TailPacket;
> +    *(Ring->Queued.TailEntry) = HeadEntry;
> +    Ring->Queued.TailEntry = TailEntry;
>      Ring->PacketsQueued += Count;

I'm confused. Why is the locked list not doubly linked?

I'll defer reviewing the rest until v2.

  Paul

>  }
> 
> @@ -2240,8 +2283,9 @@ TransmitterRingSchedule(
>      State = &Ring->State;
> 
>      for (;;) {
> -        PXENVIF_TRANSMITTER_PACKET  Packet;
> -        NTSTATUS                    status;
> +        PLIST_ENTRY                     ListEntry;
> +        PXENVIF_TRANSMITTER_PACKET_V2   Packet;
> +        NTSTATUS                        status;
> 
>          if (State->Count != 0) {
>              status = __TransmitterRingPostFragments(Ring);
> @@ -2290,19 +2334,20 @@ TransmitterRingSchedule(
>              continue;
>          }
> 
> -        Packet = Ring->Queued.HeadPacket;
> -
> -        if (Packet == NULL)
> +        ListEntry = Ring->Queued.HeadEntry;
> +        if (ListEntry == NULL)
>              break;
> 
> -        if (Packet->Next == NULL) {
> -            Ring->Queued.HeadPacket = NULL;
> -            Ring->Queued.TailPacket = &Ring->Queued.HeadPacket;
> +        if (ListEntry->Flink == NULL) {
> +            Ring->Queued.HeadEntry = NULL;
> +            Ring->Queued.TailEntry = &Ring->Queued.HeadEntry;
>          } else {
> -            Ring->Queued.HeadPacket = Packet->Next;
> -            Packet->Next = NULL;
> +            Ring->Queued.HeadEntry = ListEntry->Flink;
> +            ListEntry->Flink = NULL;
>          }
> 
> +        Packet = CONTAINING_RECORD(ListEntry,
> XENVIF_TRANSMITTER_PACKET_V2, ListEntry);
> +
>          status = __TransmitterRingPreparePacket(Ring, Packet);
>          if (!NT_SUCCESS(status)) {
>              PXENVIF_TRANSMITTER Transmitter;
> @@ -2330,11 +2375,46 @@ TransmitterRingSchedule(
>          ASSERT3U(Ring->PacketsPrepared, ==, Ring->PacketsCopied + Ring-
> >PacketsGranted + Ring->PacketsFaked);
>      }
> 
> -    ASSERT(IMPLY(Ring->Queued.HeadPacket == NULL, Ring-
> >Queued.TailPacket == &Ring->Queued.HeadPacket));
> +    ASSERT(IMPLY(Ring->Queued.HeadEntry == NULL, Ring-
> >Queued.TailEntry == &Ring->Queued.HeadEntry));
> 
>      __TransmitterRingPushRequests(Ring);
>  }
> 
> +static VOID
> +TransmitterReturnPackets(
> +    IN  PXENVIF_TRANSMITTER         Transmitter,
> +    IN  PLIST_ENTRY                 List
> +    )
> +{
> +    PXENVIF_FRONTEND                Frontend;
> +    PXENVIF_TRANSMITTER_PACKET_V1   HeadPacket;
> +    PXENVIF_TRANSMITTER_PACKET_V1   NextPacket;
> +
> +    HeadPacket = NULL;
> +    NextPacket = NULL;
> +    while (!IsListEmpty(List)) {
> +        PLIST_ENTRY                     ListEntry;
> +        PXENVIF_TRANSMITTER_PACKET_V2   Packet;
> +
> +        ListEntry = RemoveTailList(List);
> +        ASSERT3P(ListEntry, !=, List);
> +
> +        Packet = CONTAINING_RECORD(ListEntry,
> XENVIF_TRANSMITTER_PACKET_V2, ListEntry);
> +
> +        HeadPacket = Packet->Cookie;
> +        HeadPacket->Next = NextPacket;
> +        HeadPacket->Completion = Packet->Completion;
> +
> +        __TransmitterPutPacket(Transmitter, Packet);
> +        NextPacket = HeadPacket;
> +    }
> +
> +    Frontend = Transmitter->Frontend;
> +
> +
> VifTransmitterReturnPackets(PdoGetVifContext(FrontendGetPdo(Frontend
> )),
> +                                HeadPacket);
> +}
> +
>  static FORCEINLINE BOOLEAN
>  __drv_requiresIRQL(DISPATCH_LEVEL)
>  __TransmitterRingTryAcquireLock(
> @@ -2427,16 +2507,29 @@ __TransmitterRingTryReleaseLock(
>  }
> 
>  static FORCEINLINE VOID
> +__AppendTailList(
> +    IN OUT PLIST_ENTRY              List,
> +    IN OUT PLIST_ENTRY              Apendee
> +    )
> +{
> +    PLIST_ENTRY HeadEntry = Apendee->Flink;
> +
> +    if (!IsListEmpty(Apendee)) {
> +        RemoveEntryList(Apendee);
> +        InitializeListHead(Apendee);
> +        AppendTailList(List, HeadEntry);
> +    }
> +}
> +
> +static FORCEINLINE VOID
>  __drv_requiresIRQL(DISPATCH_LEVEL)
>  __TransmitterRingReleaseLock(
>      IN  PXENVIF_TRANSMITTER_RING    Ring
>      )
>  {
> -    PXENVIF_TRANSMITTER_PACKET      HeadPacket;
> -    PXENVIF_TRANSMITTER_PACKET      *TailPacket;
> -
> -    HeadPacket = NULL;
> -    TailPacket = &HeadPacket;
> +    LIST_ENTRY          List;
> +
> +    InitializeListHead(&List);
> 
>      ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
> 
> @@ -2449,22 +2542,11 @@ __TransmitterRingReleaseLock(
>          TransmitterRingSwizzle(Ring);
>          TransmitterRingSchedule(Ring);
> 
> -        *TailPacket = Ring->Completed.HeadPacket;
> -        TailPacket = Ring->Completed.TailPacket;
> -
> -        Ring->Completed.HeadPacket = NULL;
> -        Ring->Completed.TailPacket = &Ring->Completed.HeadPacket;
> +        __AppendTailList(&List, &Ring->Completed);
>      } while (!__TransmitterRingTryReleaseLock(Ring));
> 
> -    if (HeadPacket != NULL) {
> -        PXENVIF_TRANSMITTER Transmitter;
> -        PXENVIF_FRONTEND    Frontend;
> -
> -        Transmitter = Ring->Transmitter;
> -        Frontend = Transmitter->Frontend;
> -
> -
> VifTransmitterReturnPackets(PdoGetVifContext(FrontendGetPdo(Frontend
> )),
> -                                    HeadPacket);
> +    if (!IsListEmpty(&List)) {
> +        TransmitterReturnPackets(Ring->Transmitter, &List);
>      }
>  }
> 
> @@ -2624,8 +2706,8 @@ __TransmitterRingInitialize(
> 
>      (*Ring)->Transmitter = Transmitter;
>      (*Ring)->Index = Index;
> -    (*Ring)->Queued.TailPacket = &(*Ring)->Queued.HeadPacket;
> -    (*Ring)->Completed.TailPacket = &(*Ring)->Completed.HeadPacket;
> +    (*Ring)->Queued.TailEntry = &(*Ring)->Queued.HeadEntry;
> +    InitializeListHead(&(*Ring)->Completed);
> 
>      status = RtlStringCbPrintfA(Name,
>                                  sizeof (Name),
> @@ -2756,8 +2838,8 @@ fail3:
>  fail2:
>      Error("fail2\n");
> 
> -    (*Ring)->Queued.TailPacket = NULL;
> -    (*Ring)->Completed.TailPacket = NULL;
> +    (*Ring)->Queued.TailEntry = NULL;
> +    RtlZeroMemory(&(*Ring)->Completed, sizeof(LIST_ENTRY));
>      (*Ring)->Index = 0;
>      (*Ring)->Transmitter = NULL;
> 
> @@ -2910,7 +2992,7 @@ __TransmitterRingDisable(
>  {
>      PXENVIF_TRANSMITTER             Transmitter;
>      PXENVIF_FRONTEND                Frontend;
> -    PXENVIF_TRANSMITTER_PACKET      Packet;
> +    PXENVIF_TRANSMITTER_PACKET_V2   Packet;
>      PCHAR                           Buffer;
>      XenbusState                     State;
>      ULONG                           Attempt;
> @@ -2929,14 +3011,15 @@ __TransmitterRingDisable(
> 
>      // Put any packet back on the head of the queue
>      if (Packet != NULL) {
> -        ASSERT3P(Packet->Next, ==, NULL);
> +        ASSERT3P(Packet->ListEntry.Flink, ==, NULL);
> +        ASSERT3P(Packet->ListEntry.Blink, ==, NULL);
> 
> -        Packet->Next = Ring->Queued.HeadPacket;
> +        Packet->ListEntry.Flink = Ring->Queued.HeadEntry;
> 
> -        if (Ring->Queued.TailPacket == &Ring->Queued.HeadPacket)
> -            Ring->Queued.TailPacket = &Packet->Next;
> +        if (Ring->Queued.TailEntry == &Ring->Queued.HeadEntry)
> +            Ring->Queued.TailEntry = &Packet->ListEntry.Flink;
> 
> -        Ring->Queued.HeadPacket = Packet;
> +        Ring->Queued.HeadEntry = &Packet->ListEntry;
>      }
> 
>      Ring->AddressIndex = 0;
> @@ -3076,11 +3159,11 @@ __TransmitterRingTeardown(
>                   Ring->BufferCache);
>      Ring->BufferCache = NULL;
> 
> -    ASSERT3P(Ring->Queued.TailPacket, ==, &Ring->Queued.HeadPacket);
> -    Ring->Queued.TailPacket = NULL;
> +    ASSERT3P(Ring->Queued.TailEntry, ==, &Ring->Queued.HeadEntry);
> +    Ring->Queued.TailEntry = NULL;
> 
> -    ASSERT3P(Ring->Completed.TailPacket, ==, &Ring-
> >Completed.HeadPacket);
> -    Ring->Completed.TailPacket = NULL;
> +    ASSERT(IsListEmpty(&Ring->Completed));
> +    RtlZeroMemory(&Ring->Completed, sizeof(LIST_ENTRY));
> 
>      Ring->Index = 0;
>      Ring->Transmitter = NULL;
> @@ -3092,24 +3175,40 @@ __TransmitterRingTeardown(
>  static FORCEINLINE VOID
>  __TransmitterRingQueuePackets(
>      IN  PXENVIF_TRANSMITTER_RING    Ring,
> -    IN  PXENVIF_TRANSMITTER_PACKET  HeadPacket
> +    IN  PLIST_ENTRY                 List
>      )
>  {
> -    PXENVIF_TRANSMITTER_PACKET      *TailPacket;
> +    PLIST_ENTRY                     ListEntry;
> +    PLIST_ENTRY                     HeadEntry;
> +    PLIST_ENTRY                     *TailEntry;
>      ULONG_PTR                       Old;
>      ULONG_PTR                       LockBit;
>      ULONG_PTR                       New;
> 
> -    TailPacket = &HeadPacket->Next;
> -    (VOID) __TransmitterReversePacketList(&HeadPacket);
> -    ASSERT3P(*TailPacket, ==, NULL);
> +    ListEntry = RemoveTailList(List);
> +    ASSERT3P(ListEntry, !=, List);
> +
> +    ListEntry->Flink = NULL;
> +    ListEntry->Blink = NULL;
> +    HeadEntry = ListEntry;
> +
> +    TailEntry = &ListEntry->Flink;
> +    while (!IsListEmpty(List)) {
> +        ListEntry = RemoveTailList(List);
> +        ASSERT3P(ListEntry, !=, List);
> +
> +        ListEntry->Flink = HeadEntry;
> +        ListEntry->Blink = NULL;
> +        HeadEntry = ListEntry;
> +    }
> +    ASSERT3P(*TailEntry, ==, NULL);
> 
>      do {
>          Old = (ULONG_PTR)Ring->Lock;
>          LockBit = Old & XENVIF_TRANSMITTER_LOCK_BIT;
> 
> -        *TailPacket = (PVOID)(Old & ~XENVIF_TRANSMITTER_LOCK_BIT);
> -        New = (ULONG_PTR)HeadPacket;
> +        *TailEntry = (PVOID)(Old & ~XENVIF_TRANSMITTER_LOCK_BIT);
> +        New = (ULONG_PTR)HeadEntry;
>          ASSERT((New & XENVIF_TRANSMITTER_LOCK_BIT) == 0);
>          New |= LockBit;
>      } while ((ULONG_PTR)InterlockedCompareExchangePointer(&Ring->Lock,
> (PVOID)New, (PVOID)Old) != Old);
> @@ -3128,33 +3227,35 @@ __TransmitterRingAbortPackets(
>      IN  PXENVIF_TRANSMITTER_RING    Ring
>      )
>  {
> -    PXENVIF_TRANSMITTER_PACKET      Packet;
> +    PLIST_ENTRY                     ListEntry;
> 
>      __TransmitterRingAcquireLock(Ring);
> 
>      TransmitterRingSwizzle(Ring);
> 
> -    Packet = Ring->Queued.HeadPacket;
> +    ListEntry = Ring->Queued.HeadEntry;
> 
> -    Ring->Queued.HeadPacket = NULL;
> -    Ring->Queued.TailPacket = &Ring->Queued.HeadPacket;
> +    Ring->Queued.HeadEntry = NULL;
> +    Ring->Queued.TailEntry = &Ring->Queued.HeadEntry;
> 
> -    while (Packet != NULL) {
> -        PXENVIF_TRANSMITTER_PACKET  Next;
> +    while (ListEntry != NULL) {
> +        PLIST_ENTRY                     Next;
> +        PXENVIF_TRANSMITTER_PACKET_V2   Packet;
> 
> -        Next = Packet->Next;
> -        Packet->Next = NULL;
> +        Next = ListEntry->Flink;
> +        ListEntry->Flink = NULL;
> 
>          // Fake that we prapared and sent this packet
>          Ring->PacketsPrepared++;
>          Ring->PacketsSent++;
>          Ring->PacketsFaked++;
> 
> +        Packet = CONTAINING_RECORD(ListEntry,
> XENVIF_TRANSMITTER_PACKET_V2, ListEntry);
>          Packet->Completion.Status =
> XENVIF_TRANSMITTER_PACKET_DROPPED;
> 
>          __TransmitterRingCompletePacket(Ring, Packet);
> 
> -        Packet = Next;
> +        ListEntry = Next;
>      }
> 
>      ASSERT3U(Ring->PacketsSent, ==, Ring->PacketsPrepared - Ring-
> >PacketsUnprepared);
> @@ -3264,13 +3365,27 @@ TransmitterInitialize(
>      if (!NT_SUCCESS(status))
>          goto fail3;
> 
> +    status = XENBUS_CACHE(Create,
> +                          &(*Transmitter)->CacheInterface,
> +                          "packet_cache",
> +                          sizeof(XENVIF_TRANSMITTER_PACKET_V2),
> +                          0,
> +                          TransmitterPacketCtor,
> +                          TransmitterPacketDtor,
> +                          TransmitterPacketLock,
> +                          TransmitterPacketUnlock,
> +                          *Transmitter,
> +                          &(*Transmitter)->PacketCache);
> +    if (!NT_SUCCESS(status))
> +        goto fail4;
> +
>      Index = 0;
>      while (Index < Count) {
>          PXENVIF_TRANSMITTER_RING    Ring;
> 
>          status = __TransmitterRingInitialize(*Transmitter, Index, &Ring);
>          if (!NT_SUCCESS(status))
> -            goto fail4;
> +            goto fail5;
> 
>          InsertTailList(&(*Transmitter)->List, &Ring->ListEntry);
>          Index++;
> @@ -3278,8 +3393,8 @@ TransmitterInitialize(
> 
>      return STATUS_SUCCESS;
> 
> -fail4:
> -    Error("fail4\n");
> +fail5:
> +    Error("fail5\n");
> 
>      while (!IsListEmpty(&(*Transmitter)->List)) {
>          PLIST_ENTRY                 ListEntry;
> @@ -3297,6 +3412,14 @@ fail4:
>      }
>      ASSERT3U(Index, ==, 0);
> 
> +    XENBUS_CACHE(Destroy,
> +                 &(*Transmitter)->CacheInterface,
> +                 (*Transmitter)->PacketCache);
> +    (*Transmitter)->PacketCache = NULL;
> +
> +fail4:
> +    Error("fail4\n");
> +
>      XENBUS_CACHE(Release, &(*Transmitter)->CacheInterface);
> 
>  fail3:
> @@ -3530,6 +3653,11 @@ TransmitterTeardown(
>          __TransmitterRingTeardown(Ring);
>      }
> 
> +    XENBUS_CACHE(Destroy,
> +                 &Transmitter->CacheInterface,
> +                 Transmitter->PacketCache);
> +    Transmitter->PacketCache = NULL;
> +
>      XENBUS_CACHE(Release, &Transmitter->CacheInterface);
> 
>      XENBUS_RANGE_SET(Release, &Transmitter->RangeSetInterface);
> @@ -3620,20 +3748,77 @@ fail1:
>  }
> 
>  VOID
> -TransmitterQueuePackets(
> -    IN  PXENVIF_TRANSMITTER         Transmitter,
> -    IN  PXENVIF_TRANSMITTER_PACKET  HeadPacket
> +TransmitterQueuePacketsV1(
> +    IN  PXENVIF_TRANSMITTER             Transmitter,
> +    IN  PXENVIF_TRANSMITTER_PACKET_V1   HeadPacket
>      )
>  {
> +#define OFFSET_EXISTS(_Transmitter, _Packet, _Type)
> \
> +    ((_Transmitter)->Offset[XENVIF_TRANSMITTER_PACKET_ ## _Type ##
> _OFFSET] != 0)
> +
> +#define OFFSET(_Transmitter, _Packet, _Type)                                 
>                        \
> +        ((OFFSET_EXISTS(_Transmitter, _Packet, _Type)) ?
> \
> +         (PVOID)((PUCHAR)(_Packet) +                                         
>                        \
> +                 (_Transmitter)->Offset[XENVIF_TRANSMITTER_PACKET_ ## _Type
> ## _OFFSET]) :          \
> +         NULL)
> +
> +    LIST_ENTRY                      List;
>      PLIST_ENTRY                     ListEntry;
>      PXENVIF_TRANSMITTER_RING        Ring;
> 
> +    InitializeListHead(&List);
> +    while (HeadPacket != NULL) {
> +        PXENVIF_TRANSMITTER_PACKET_V2   Packet;
> +
> +        Packet = __TransmitterGetPacket(Transmitter);
> +        if (Packet == NULL) {
> +            Warning("Out-of-cached-packets\n");
> +            break;
> +        }
> +
> +        Packet->Cookie = HeadPacket;
> +        RtlCopyMemory(&Packet->Send, &HeadPacket->Send, sizeof(Packet-
> >Send));
> +        RtlZeroMemory(&Packet->Completion, sizeof(Packet->Completion));
> +
> +        ASSERT(OFFSET_EXISTS(Transmitter, HeadPacket, MDL));
> +        Packet->Mdl = *(PMDL *)OFFSET(Transmitter, HeadPacket, MDL);
> +        if (OFFSET_EXISTS(Transmitter, HeadPacket, OFFSET))
> +            Packet->Offset = *(PULONG)OFFSET(Transmitter, HeadPacket,
> OFFSET);
> +        else
> +            Packet->Offset = 0;
> +        ASSERT(OFFSET_EXISTS(Transmitter, HeadPacket, LENGTH));
> +        Packet->Length = *(PULONG)OFFSET(Transmitter, HeadPacket,
> LENGTH);
> +
> +        InsertTailList(&List, &Packet->ListEntry);
> +        HeadPacket = HeadPacket->Next;
> +    }
> +
>      // We need to hash for a ring eventually. Since there is only a
>      // single ring for now, we just use that.
>      ListEntry = Transmitter->List.Flink;
>      Ring = CONTAINING_RECORD(ListEntry, XENVIF_TRANSMITTER_RING,
> ListEntry);
> 
> -    __TransmitterRingQueuePackets(Ring, HeadPacket);
> +    __TransmitterRingQueuePackets(Ring, &List);
> +
> +    // if HeadPacket != NULL, errors occured and need returning
> +    if (HeadPacket != NULL) {
> +        PXENVIF_TRANSMITTER_PACKET_V1   Packet;
> +        PXENVIF_FRONTEND                Frontend;
> +
> +        Frontend = Transmitter->Frontend;
> +
> +        Packet = HeadPacket;
> +        while (Packet != NULL) {
> +            Packet->Completion.Status =
> XENVIF_TRANSMITTER_PACKET_DROPPED;
> +            Packet = Packet->Next;
> +        }
> +
> +
> VifTransmitterReturnPackets(PdoGetVifContext(FrontendGetPdo(Frontend
> )),
> +                                    HeadPacket);
> +    }
> +
> +#undef OFFSET
> +#undef OFFSET_EXISTS
>  }
> 
>  VOID
> diff --git a/src/xenvif/transmitter.h b/src/xenvif/transmitter.h
> index 5ffb590..661eeae 100644
> --- a/src/xenvif/transmitter.h
> +++ b/src/xenvif/transmitter.h
> @@ -107,9 +107,9 @@ TransmitterAdvertiseAddresses(
>      );
> 
>  extern VOID
> -TransmitterQueuePackets(
> -    IN  PXENVIF_TRANSMITTER         Transmitter,
> -    IN  PXENVIF_TRANSMITTER_PACKET  HeadPacket
> +TransmitterQueuePacketsV1(
> +    IN  PXENVIF_TRANSMITTER             Transmitter,
> +    IN  PXENVIF_TRANSMITTER_PACKET_V1   HeadPacket
>      );
> 
>  extern VOID
> diff --git a/src/xenvif/vif.c b/src/xenvif/vif.c
> index 97ce84a..d6da258 100644
> --- a/src/xenvif/vif.c
> +++ b/src/xenvif/vif.c
> @@ -276,8 +276,8 @@ VifReceiverReturnPackets(
> 
>  static NTSTATUS
>  VifTransmitterQueuePackets(
> -    IN  PINTERFACE                  Interface,
> -    IN  PXENVIF_TRANSMITTER_PACKET  Head
> +    IN  PINTERFACE                      Interface,
> +    IN  PXENVIF_TRANSMITTER_PACKET_V1   Head
>      )
>  {
>      PXENVIF_VIF_CONTEXT             Context = Interface->Context;
> @@ -289,8 +289,8 @@ VifTransmitterQueuePackets(
>      if (Context->Enabled == FALSE)
>          goto fail1;
> 
> -    TransmitterQueuePackets(FrontendGetTransmitter(Context->Frontend),
> -                            Head);
> +    TransmitterQueuePacketsV1(FrontendGetTransmitter(Context-
> >Frontend),
> +                              Head);
> 
>      ReleaseMrswLockShared(&Context->Lock);
> 
> @@ -784,8 +784,8 @@ VifReceiverQueuePackets(
> 
>  VOID
>  VifTransmitterReturnPackets(
> -    IN  PXENVIF_VIF_CONTEXT         Context,
> -    IN  PXENVIF_TRANSMITTER_PACKET  Head
> +    IN  PXENVIF_VIF_CONTEXT             Context,
> +    IN  PXENVIF_TRANSMITTER_PACKET_V1   Head
>      )
>  {
>      Context->Callback(Context->Argument,
> diff --git a/src/xenvif/vif.h b/src/xenvif/vif.h
> index 17a04db..0ef6687 100644
> --- a/src/xenvif/vif.h
> +++ b/src/xenvif/vif.h
> @@ -70,8 +70,8 @@ VifReceiverQueuePackets(
> 
>  extern VOID
>  VifTransmitterReturnPackets(
> -    IN  PXENVIF_VIF_CONTEXT         Context,
> -    IN  PXENVIF_TRANSMITTER_PACKET  Head
> +    IN  PXENVIF_VIF_CONTEXT             Context,
> +    IN  PXENVIF_TRANSMITTER_PACKET_V1   Head
>      );
> 
>  extern PXENVIF_THREAD
> --
> 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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.