[ovs-dev] [PATCH v3 3/3] datapath-windows: Refactor CreateQueue function to handle vport pid.

Sorin Vinturis svinturis at cloudbasesolutions.com
Fri Oct 24 09:06:41 UTC 2014


Acked-by: Sorin Vinturis <svinturis at cloudbasesolutions.com>

-----Original Message-----
From: dev [mailto:dev-bounces at openvswitch.org] On Behalf Of Ankur Sharma
Sent: Thursday, October 23, 2014 10:12 PM
To: dev at openvswitch.org
Subject: [ovs-dev] [PATCH v3 3/3] datapath-windows: Refactor CreateQueue function to handle vport pid.

Refactored CreateQueue function so that packets are enqueued to correct corresponding queue.

Signed-off-by: Ankur Sharma <ankursharma at vmware.com>
---
 datapath-windows/ovsext/Actions.c  |   4 +-
 datapath-windows/ovsext/PacketIO.c |   2 +-
 datapath-windows/ovsext/Switch.c   |   2 +
 datapath-windows/ovsext/Switch.h   |   1 +
 datapath-windows/ovsext/Tunnel.c   |   2 +-
 datapath-windows/ovsext/User.c     | 108 ++++++++++++++++++++++++-------------
 datapath-windows/ovsext/User.h     |   4 +-
 7 files changed, 79 insertions(+), 44 deletions(-)

diff --git a/datapath-windows/ovsext/Actions.c b/datapath-windows/ovsext/Actions.c
index 408b9be..f5ce12e 100644
--- a/datapath-windows/ovsext/Actions.c
+++ b/datapath-windows/ovsext/Actions.c
@@ -564,7 +564,7 @@ OvsDoFlowLookupOutput(OvsForwardingContext *ovsFwdCtx)
                           ovsFwdCtx->tunnelRxNic != NULL, &ovsFwdCtx->layers,
                           ovsFwdCtx->switchContext, &missedPackets, &num);
         if (num) {
-            OvsQueuePackets(OVS_DEFAULT_PACKET_QUEUE, &missedPackets, num);
+            OvsQueuePackets(&missedPackets, num);
         }
         if (status == NDIS_STATUS_SUCCESS) {
             /* Complete the packet since it was copied to user buffer. */ @@ -1495,7 +1495,7 @@ OvsActionsExecute(POVS_SWITCH_CONTEXT switchContext,
                 LIST_ENTRY missedPackets;
                 InitializeListHead(&missedPackets);
                 InsertTailList(&missedPackets, &elem->link);
-                OvsQueuePackets(OVS_DEFAULT_PACKET_QUEUE, &missedPackets, 1);
+                OvsQueuePackets(&missedPackets, 1);
                 dropReason = L"OVS-Completed since packet was copied to "
                              L"userspace";
             } else {
diff --git a/datapath-windows/ovsext/PacketIO.c b/datapath-windows/ovsext/PacketIO.c
index 493c8cb..7eb6ed8 100644
--- a/datapath-windows/ovsext/PacketIO.c
+++ b/datapath-windows/ovsext/PacketIO.c
@@ -314,7 +314,7 @@ dropit:
     }
 
     /* Queue the missed packets. */
-    OvsQueuePackets(OVS_DEFAULT_PACKET_QUEUE, &missedPackets, num);
+    OvsQueuePackets(&missedPackets, num);
     OvsFinalizeCompletionList(&completionList);
 }
 
diff --git a/datapath-windows/ovsext/Switch.c b/datapath-windows/ovsext/Switch.c
index 5593d43..f445500 100644
--- a/datapath-windows/ovsext/Switch.c
+++ b/datapath-windows/ovsext/Switch.c
@@ -411,6 +411,7 @@ OvsInitSwitchContext(POVS_SWITCH_CONTEXT switchContext)
         InitializeListHead(&switchContext->pidHashArray[i]);
     }
 
+    NdisAllocateSpinLock(&(switchContext->pidHashLock));
     switchContext->isActivated = FALSE;
     switchContext->isActivateFailed = FALSE;
     switchContext->dpNo = OVS_DP_NUMBER; @@ -429,6 +430,7 @@ OvsCleanupSwitchContext(POVS_SWITCH_CONTEXT switchContext)
     ASSERT(switchContext->numVports == 0);
 
     NdisFreeRWLock(switchContext->dispatchLock);
+    NdisFreeSpinLock(&(switchContext->pidHashLock));
     OvsFreeMemory(switchContext->ovsPortNameHashArray);
     OvsFreeMemory(switchContext->portIdHashArray);
     OvsFreeMemory(switchContext->portNoHashArray);
diff --git a/datapath-windows/ovsext/Switch.h b/datapath-windows/ovsext/Switch.h
index 7fdca5f..b61462b 100644
--- a/datapath-windows/ovsext/Switch.h
+++ b/datapath-windows/ovsext/Switch.h
@@ -110,6 +110,7 @@ typedef struct _OVS_SWITCH_CONTEXT
     PLIST_ENTRY             portIdHashArray;        // based on portId
     PLIST_ENTRY             portNoHashArray;        // based on ovs port number
     PLIST_ENTRY             pidHashArray;           // based on packet pids
+    NDIS_SPIN_LOCK          pidHashLock;            // Lock for pidHash table
 
     UINT32                  numPhysicalNics;
     UINT32                  numVports;     // include validation port
diff --git a/datapath-windows/ovsext/Tunnel.c b/datapath-windows/ovsext/Tunnel.c
index eb45454..b55a223 100644
--- a/datapath-windows/ovsext/Tunnel.c
+++ b/datapath-windows/ovsext/Tunnel.c
@@ -320,7 +320,7 @@ OvsInjectPacketThroughActions(PNET_BUFFER_LIST pNbl,
             if (elem) {
                 /* Complete the packet since it was copied to user buffer. */
                 InsertTailList(&missedPackets, &elem->link);
-                OvsQueuePackets(OVS_DEFAULT_PACKET_QUEUE, &missedPackets, 1);
+                OvsQueuePackets(&missedPackets, 1);
             } else {
                 status = STATUS_INSUFFICIENT_RESOURCES;
             }
diff --git a/datapath-windows/ovsext/User.c b/datapath-windows/ovsext/User.c index f6b1157..bf62459 100644
--- a/datapath-windows/ovsext/User.c
+++ b/datapath-windows/ovsext/User.c
@@ -49,6 +49,19 @@ static VOID _MapNlAttrToOvsPktExec(PNL_ATTR *nlAttrs, PNL_ATTR *keyAttrs,
                                    OvsPacketExecute  *execute);  extern NL_POLICY nlFlowKeyPolicy[];
 
+VOID
+OvsAcquirePidHashLock()
+{
+    NdisAcquireSpinLock(&(gOvsSwitchContext->pidHashLock));
+}
+
+VOID
+OvsReleasePidHashLock()
+{
+    NdisReleaseSpinLock(&(gOvsSwitchContext->pidHashLock));
+}
+
+
 static VOID
 OvsPurgePacketQueue(POVS_USER_PACKET_QUEUE queue,
                     POVS_OPEN_INSTANCE instance) @@ -147,10 +160,10 @@ OvsSubscribeDpIoctl(PVOID instanceP,
         /* unsubscribe */
         OvsCleanupPacketQueue(instance);
 
-        OvsAcquireCtrlLock();
+        OvsAcquirePidHashLock();
         /* Remove the instance from pidHashArray */
         OvsDelPidInstance(gOvsSwitchContext, pid);
-        OvsReleaseCtrlLock();
+        OvsReleasePidHashLock();
 
     } else if (instance->packetQueue == NULL && join) {
         queue = (POVS_USER_PACKET_QUEUE) OvsAllocateMemory(sizeof *queue); @@ -168,10 +181,10 @@ OvsSubscribeDpIoctl(PVOID instanceP,
         instance->packetQueue = queue;
         NdisReleaseSpinLock(&queue->queueLock);
 
-        OvsAcquireCtrlLock();
+        OvsAcquirePidHashLock();
         /* Insert the instance to pidHashArray */
         OvsAddPidInstance(gOvsSwitchContext, pid, instance);
-        OvsReleaseCtrlLock();
+        OvsReleasePidHashLock();
 
     } else {
         /* user mode should call only once for subscribe */ @@ -633,7 +646,7 @@ OvsGetQueue(UINT32 pid)
 /*
  * ---------------------------------------------------------------------------
  * Given a pid, returns the corresponding instance.
- * gOvsCtrlLock must be acquired before calling this API.
+ * pidHashLock must be acquired before calling this API.
  * ---------------------------------------------------------------------------
  */
 POVS_OPEN_INSTANCE
@@ -656,7 +669,7 @@ OvsGetPidInstance(POVS_SWITCH_CONTEXT switchContext, UINT32 pid)
 /*
  * ---------------------------------------------------------------------------
  * Given a pid and an instance. This API adds instance to pidHashArray.
- * gOvsCtrlLock must be acquired before calling this API.
+ * pidHashLock must be acquired before calling this API.
  * ---------------------------------------------------------------------------
  */
 VOID
@@ -673,7 +686,7 @@ OvsAddPidInstance(POVS_SWITCH_CONTEXT switchContext, UINT32 pid,
 /*
  * ---------------------------------------------------------------------------
  * Given a pid and an instance. This API removes instance from pidHashArray.
- * gOvsCtrlLock must be acquired before calling this API.
+ * pidHashLock must be acquired before calling this API.
  * ---------------------------------------------------------------------------
  */
 VOID
@@ -687,55 +700,71 @@ OvsDelPidInstance(POVS_SWITCH_CONTEXT switchContext, UINT32 pid)  }
 
 VOID
-OvsQueuePackets(UINT32 queueId,
-                PLIST_ENTRY packetList,
+OvsQueuePackets(PLIST_ENTRY packetList,
                 UINT32 numElems)
 {
-    POVS_USER_PACKET_QUEUE queue = OvsGetQueue(queueId);
+    POVS_USER_PACKET_QUEUE upcallQueue = NULL;
     POVS_PACKET_QUEUE_ELEM elem;
     PIRP irp = NULL;
     PLIST_ENTRY  link;
     UINT32 num = 0;
+    LIST_ENTRY dropPackets;
 
-    OVS_LOG_LOUD("Enter: queueId %u, numELems: %u",
-                  queueId, numElems);
-    if (queue == NULL) {
-        goto cleanup;
-    }
+    OVS_LOG_LOUD("Enter: numELems: %u", numElems);
 
-    NdisAcquireSpinLock(&queue->queueLock);
-    if (queue->instance == NULL) {
-        NdisReleaseSpinLock(&queue->queueLock);
-        goto cleanup;
-    } else {
-        OvsAppendList(&queue->packetList, packetList);
-        queue->numPackets += numElems;
-    }
-    if (queue->pendingIrp) {
-        PDRIVER_CANCEL cancelRoutine;
-        irp = queue->pendingIrp;
-        queue->pendingIrp = NULL;
-        cancelRoutine = IoSetCancelRoutine(irp, NULL);
-        if (cancelRoutine == NULL) {
-            irp = NULL;
-        }
-    }
-    NdisReleaseSpinLock(&queue->queueLock);
-    if (irp) {
-        OvsCompleteIrpRequest(irp, 0, STATUS_SUCCESS);
-    }
+    InitializeListHead(&dropPackets);
 
-cleanup:
     while (!IsListEmpty(packetList)) {
         link = RemoveHeadList(packetList);
         elem = CONTAINING_RECORD(link, OVS_PACKET_QUEUE_ELEM, link);
+
+        ASSERT(elem);
+
+        OvsAcquirePidHashLock();
+
+        upcallQueue = OvsGetQueue(elem->upcallPid);
+        if (!upcallQueue) {
+            /* No upcall queue found, drop this packet. */
+            InsertTailList(&dropPackets, &elem->link);
+        } else {
+            NdisAcquireSpinLock(&upcallQueue->queueLock);
+
+            if (upcallQueue->instance == NULL) {
+                InsertTailList(&dropPackets, &elem->link);
+            } else {
+                InsertTailList(&upcallQueue->packetList, &elem->link);
+                upcallQueue->numPackets++;
+                if (upcallQueue->pendingIrp) {
+                    PDRIVER_CANCEL cancelRoutine;
+                    irp = upcallQueue->pendingIrp;
+                    upcallQueue->pendingIrp = NULL;
+                    cancelRoutine = IoSetCancelRoutine(irp, NULL);
+                    if (cancelRoutine == NULL) {
+                        irp = NULL;
+                    }
+                }
+            }
+
+            if (irp) {
+                OvsCompleteIrpRequest(irp, 0, STATUS_SUCCESS);
+            }
+
+            NdisReleaseSpinLock(&upcallQueue->queueLock);
+        }
+
+        OvsReleasePidHashLock();
+    }
+
+    while (!IsListEmpty(&dropPackets)) {
+        link = RemoveHeadList(&dropPackets);
+        elem = CONTAINING_RECORD(link, OVS_PACKET_QUEUE_ELEM, link);
         OvsFreeMemory(elem);
         num++;
     }
+
     OVS_LOG_LOUD("Exit: drop %u packets", num);  }
 
-
 /*
  *----------------------------------------------------------------------------
  * OvsCreateAndAddPackets --
@@ -932,6 +961,8 @@ OvsGetPid(POVS_VPORT_ENTRY vport, PNET_BUFFER nb, UINT32 *pid)  {
     UNREFERENCED_PARAMETER(nb);
 
+    ASSERT(vport);
+
     /* XXX select a pid from an array of pids using a flow based hash */
     *pid = vport->upcallPid;
     return STATUS_SUCCESS;
@@ -1031,6 +1062,7 @@ OvsCreateQueueNlPacket(PVOID userData,
         return NULL;
     }
     elem->hdrInfo.value = hdrInfo->value;
+    elem->upcallPid = pid;
     elem->packet.totalLen = nlMsgSize;
     /* XXX remove queueid */
     elem->packet.queue = 0;
diff --git a/datapath-windows/ovsext/User.h b/datapath-windows/ovsext/User.h index 1050ae8..139b0ca 100644
--- a/datapath-windows/ovsext/User.h
+++ b/datapath-windows/ovsext/User.h
@@ -49,6 +49,7 @@ typedef struct _OVS_USER_PACKET_QUEUE {  } OVS_USER_PACKET_QUEUE, *POVS_USER_PACKET_QUEUE;
 
 typedef struct _OVS_PACKET_QUEUE_ELEM {
+    UINT32  upcallPid;
     LIST_ENTRY link;
     OVS_PACKET_HDR_INFO hdrInfo;
     OVS_PACKET_INFO packet;
@@ -78,8 +79,7 @@ POVS_PACKET_QUEUE_ELEM OvsCreateQueueNlPacket(PVOID userData,
                                               BOOLEAN isRecv,
                                               POVS_PACKET_HDR_INFO hdrInfo);
 
-VOID OvsQueuePackets(UINT32 queueId, PLIST_ENTRY packetList,
-                     UINT32 numElems);
+VOID OvsQueuePackets(PLIST_ENTRY packetList, UINT32 numElems);
 NTSTATUS OvsCreateAndAddPackets(PVOID userData,
                                 UINT32 userDataLen,
                                 UINT32 cmd,
--
1.9.1

_______________________________________________
dev mailing list
dev at openvswitch.org
http://openvswitch.org/mailman/listinfo/dev



More information about the dev mailing list