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

[win-pv-devel] [PATCH] Update VIF interface to version 5



Unfortunately VIF interface version 4 suffers from a shutdown race with
the TransmitterQueuePacket method. If a call to this races with the Disable
method then a NULL callback function pointer can be invoked.
This patch fixes the race by having TransmitterQueuePacket return a status
code to indicate whether a packet has been queued (rather than invoking the
completion callback if it has not), but this necessitates a interface change
so the VIF interface version is also updated to 5 and a new PDO revision is
added.

Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
---
 include/revision.h      |  3 +-
 include/vif_interface.h | 48 ++++++++++++++++++++++++++--
 src/xenvif/vif.c        | 83 ++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 129 insertions(+), 5 deletions(-)

diff --git a/include/revision.h b/include/revision.h
index eda8871..78de3a1 100644
--- a/include/revision.h
+++ b/include/revision.h
@@ -43,7 +43,8 @@
     DEFINE_REVISION(0x08000002,  1,  2,  0,  0),    \
     DEFINE_REVISION(0x08000003,  1,  3,  0,  0),    \
     DEFINE_REVISION(0x08000004,  1,  3,  2,  1),    \
-    DEFINE_REVISION(0x08000006,  1,  4,  2,  1)
+    DEFINE_REVISION(0x08000006,  1,  4,  2,  1),    \
+    DEFINE_REVISION(0x08000007,  1,  5,  2,  1)
 
 // Revision 0x08000005 is already in use in the staging-8.1 branch.
 
diff --git a/include/vif_interface.h b/include/vif_interface.h
index 27c5d2d..5a064fd 100644
--- a/include/vif_interface.h
+++ b/include/vif_interface.h
@@ -460,6 +460,19 @@ typedef NTSTATUS
     IN  PLIST_ENTRY List
     );
 
+typedef VOID
+(*XENVIF_VIF_TRANSMITTER_QUEUE_PACKET_V4)(
+    IN  PINTERFACE                  Interface,
+    IN  PMDL                        Mdl,
+    IN  ULONG                       Offset,
+    IN  ULONG                       Length,
+    IN  XENVIF_VIF_OFFLOAD_OPTIONS  OffloadOptions,
+    IN  USHORT                      MaximumSegmentSize,
+    IN  USHORT                      TagControlInformation,
+    IN  PXENVIF_PACKET_HASH         Hash,
+    IN  PVOID                       Cookie
+    );
+
 /*! \typedef XENVIF_VIF_TRANSMITTER_QUEUE_PACKET
     \brief Queue a packet at the provider's transmit side
 
@@ -473,7 +486,7 @@ typedef NTSTATUS
     \param Hash Hash information for the packet
     \param Cookie A cookie specified by the caller that will be passed to the 
XENVIF_TRANSMITTER_RETURN_PACKET callback
 */
-typedef VOID
+typedef NTSTATUS
 (*XENVIF_VIF_TRANSMITTER_QUEUE_PACKET)(
     IN  PINTERFACE                  Interface,
     IN  PMDL                        Mdl,
@@ -766,6 +779,35 @@ struct _XENVIF_VIF_INTERFACE_V4 {
     XENVIF_VIF_RECEIVER_SET_OFFLOAD_OPTIONS         ReceiverSetOffloadOptions;
     XENVIF_VIF_RECEIVER_SET_BACKFILL_SIZE           ReceiverSetBackfillSize;
     XENVIF_VIF_RECEIVER_QUERY_RING_SIZE             ReceiverQueryRingSize;
+    XENVIF_VIF_TRANSMITTER_QUEUE_PACKET_V4          
TransmitterQueuePacketVersion4;
+    XENVIF_VIF_TRANSMITTER_QUERY_OFFLOAD_OPTIONS    
TransmitterQueryOffloadOptions;
+    XENVIF_VIF_TRANSMITTER_QUERY_LARGE_PACKET_SIZE  
TransmitterQueryLargePacketSize;
+    XENVIF_VIF_TRANSMITTER_QUERY_RING_SIZE          TransmitterQueryRingSize;
+    XENVIF_VIF_MAC_QUERY_STATE                      MacQueryState;
+    XENVIF_VIF_MAC_QUERY_MAXIMUM_FRAME_SIZE         MacQueryMaximumFrameSize;
+    XENVIF_VIF_MAC_QUERY_PERMANENT_ADDRESS          MacQueryPermanentAddress;
+    XENVIF_VIF_MAC_QUERY_CURRENT_ADDRESS            MacQueryCurrentAddress;
+    XENVIF_VIF_MAC_QUERY_MULTICAST_ADDRESSES        MacQueryMulticastAddresses;
+    XENVIF_VIF_MAC_SET_MULTICAST_ADDRESSES          MacSetMulticastAddresses;
+    XENVIF_VIF_MAC_SET_FILTER_LEVEL                 MacSetFilterLevel;
+    XENVIF_VIF_MAC_QUERY_FILTER_LEVEL               MacQueryFilterLevel;
+};
+
+/*! \struct _XENVIF_VIF_INTERFACE_V5
+    \brief VIF interface version 5
+    \ingroup interfaces
+*/
+struct _XENVIF_VIF_INTERFACE_V5 {
+    INTERFACE                                       Interface;
+    XENVIF_VIF_ACQUIRE                              Acquire;
+    XENVIF_VIF_RELEASE                              Release;
+    XENVIF_VIF_ENABLE                               Enable;
+    XENVIF_VIF_DISABLE                              Disable;
+    XENVIF_VIF_QUERY_STATISTIC                      QueryStatistic;
+    XENVIF_VIF_RECEIVER_RETURN_PACKET               ReceiverReturnPacket;
+    XENVIF_VIF_RECEIVER_SET_OFFLOAD_OPTIONS         ReceiverSetOffloadOptions;
+    XENVIF_VIF_RECEIVER_SET_BACKFILL_SIZE           ReceiverSetBackfillSize;
+    XENVIF_VIF_RECEIVER_QUERY_RING_SIZE             ReceiverQueryRingSize;
     XENVIF_VIF_TRANSMITTER_QUEUE_PACKET             TransmitterQueuePacket;
     XENVIF_VIF_TRANSMITTER_QUERY_OFFLOAD_OPTIONS    
TransmitterQueryOffloadOptions;
     XENVIF_VIF_TRANSMITTER_QUERY_LARGE_PACKET_SIZE  
TransmitterQueryLargePacketSize;
@@ -780,7 +822,7 @@ struct _XENVIF_VIF_INTERFACE_V4 {
     XENVIF_VIF_MAC_QUERY_FILTER_LEVEL               MacQueryFilterLevel;
 };
 
-typedef struct _XENVIF_VIF_INTERFACE_V4 XENVIF_VIF_INTERFACE, 
*PXENVIF_VIF_INTERFACE;
+typedef struct _XENVIF_VIF_INTERFACE_V5 XENVIF_VIF_INTERFACE, 
*PXENVIF_VIF_INTERFACE;
 
 /*! \def XENVIF_VIF
     \brief Macro at assist in method invocation
@@ -791,6 +833,6 @@ typedef struct _XENVIF_VIF_INTERFACE_V4 
XENVIF_VIF_INTERFACE, *PXENVIF_VIF_INTER
 #endif  // _WINDLL
 
 #define XENVIF_VIF_INTERFACE_VERSION_MIN    2
-#define XENVIF_VIF_INTERFACE_VERSION_MAX    4
+#define XENVIF_VIF_INTERFACE_VERSION_MAX    5
 
 #endif  // _XENVIF_INTERFACE_H
diff --git a/src/xenvif/vif.c b/src/xenvif/vif.c
index cd8aafc..3d40ad0 100644
--- a/src/xenvif/vif.c
+++ b/src/xenvif/vif.c
@@ -396,7 +396,7 @@ done:
 }
 
 static VOID
-VifTransmitterQueuePacket(
+VifTransmitterQueuePacketVersion4(
     IN  PINTERFACE                  Interface,
     IN  PMDL                        Mdl,
     IN  ULONG                       Offset,
@@ -444,6 +444,45 @@ done:
     }
 }
 
+static NTSTATUS
+VifTransmitterQueuePacket(
+    IN  PINTERFACE                  Interface,
+    IN  PMDL                        Mdl,
+    IN  ULONG                       Offset,
+    IN  ULONG                       Length,
+    IN  XENVIF_VIF_OFFLOAD_OPTIONS  OffloadOptions,
+    IN  USHORT                      MaximumSegmentSize,
+    IN  USHORT                      TagControlInformation,
+    IN  PXENVIF_PACKET_HASH         Hash,
+    IN  PVOID                       Cookie
+    )
+{
+    PXENVIF_VIF_CONTEXT             Context = Interface->Context;
+    NTSTATUS                        status;
+
+    AcquireMrswLockShared(&Context->Lock);
+
+    status = STATUS_UNSUCCESSFUL;
+    if (Context->Enabled == FALSE)
+        goto done;
+
+    ASSERT3U(VifGetVersion(Context), >=, 5);
+    status = TransmitterQueuePacket(FrontendGetTransmitter(Context->Frontend),
+                                    Mdl,
+                                    Offset,
+                                    Length,
+                                    OffloadOptions,
+                                    MaximumSegmentSize,
+                                    TagControlInformation,
+                                    Hash,
+                                    Cookie);
+
+done:
+    ReleaseMrswLockShared(&Context->Lock);
+
+    return status;
+}
+
 static VOID
 VifTransmitterQueryOffloadOptions(
     IN  PINTERFACE                  Interface,
@@ -809,6 +848,31 @@ static struct _XENVIF_VIF_INTERFACE_V4 
VifInterfaceVersion4 = {
     VifReceiverSetOffloadOptions,
     VifReceiverSetBackfillSize,
     VifReceiverQueryRingSize,
+    VifTransmitterQueuePacketVersion4,
+    VifTransmitterQueryOffloadOptions,
+    VifTransmitterQueryLargePacketSize,
+    VifTransmitterQueryRingSize,
+    VifMacQueryState,
+    VifMacQueryMaximumFrameSize,
+    VifMacQueryPermanentAddress,
+    VifMacQueryCurrentAddress,
+    VifMacQueryMulticastAddresses,
+    VifMacSetMulticastAddresses,
+    VifMacSetFilterLevel,
+    VifMacQueryFilterLevel
+};
+
+static struct _XENVIF_VIF_INTERFACE_V5 VifInterfaceVersion5 = {
+    { sizeof (struct _XENVIF_VIF_INTERFACE_V5), 5, NULL, NULL, NULL },
+    VifAcquire,
+    VifRelease,
+    VifEnable,
+    VifDisable,
+    VifQueryStatistic,
+    VifReceiverReturnPacket,
+    VifReceiverSetOffloadOptions,
+    VifReceiverSetBackfillSize,
+    VifReceiverQueryRingSize,
     VifTransmitterQueuePacket,
     VifTransmitterQueryOffloadOptions,
     VifTransmitterQueryLargePacketSize,
@@ -938,6 +1002,23 @@ VifGetInterface(
         status = STATUS_SUCCESS;
         break;
     }
+    case 5: {
+        struct _XENVIF_VIF_INTERFACE_V5 *VifInterface;
+
+        VifInterface = (struct _XENVIF_VIF_INTERFACE_V5 *)Interface;
+
+        status = STATUS_BUFFER_OVERFLOW;
+        if (Size < sizeof (struct _XENVIF_VIF_INTERFACE_V5))
+            break;
+
+        *VifInterface = VifInterfaceVersion5;
+
+        ASSERT3U(Interface->Version, ==, Version);
+        Interface->Context = Context;
+
+        status = STATUS_SUCCESS;
+        break;
+    }
     default:
         status = STATUS_NOT_SUPPORTED;
         break;
-- 
2.1.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®.