[ovs-dev] [PATCH v3 1/2] datapath-windows: Process tunnel filter requests iteratively

Sorin Vinturis svinturis at cloudbasesolutions.com
Mon Aug 31 17:46:36 UTC 2015


In order to support IRP cancelling mechanism for pending IRPs, all
tunnel filter requests, VXLAN create/delete tunnel, need to be
processed iteratively.

Signed-off-by: Sorin Vinturis <svinturis at cloudbasesolutions.com>
---
 datapath-windows/ovsext/TunnelFilter.c | 103 ++++++++++-----------------------
 1 file changed, 30 insertions(+), 73 deletions(-)

diff --git a/datapath-windows/ovsext/TunnelFilter.c b/datapath-windows/ovsext/TunnelFilter.c
index 00e57c3..6cf9a94 100644
--- a/datapath-windows/ovsext/TunnelFilter.c
+++ b/datapath-windows/ovsext/TunnelFilter.c
@@ -955,38 +955,25 @@ OvsTunnelFilterExecuteAction(HANDLE engineSession,
 
 /*
  * --------------------------------------------------------------------------
- * This function pops the whole request entries from the queue and returns the
- * number of entries through the 'count' parameter. The operation is
- * synchronized using request list spinlock.
+ * This function pops the head item from the requests list while holding
+ * the list's spinlock.
  * --------------------------------------------------------------------------
  */
-VOID
-OvsTunnelFilterRequestPopList(POVS_TUNFLT_REQUEST_LIST listRequests,
-                              PLIST_ENTRY head,
-                              UINT32 *count)
+POVS_TUNFLT_REQUEST
+OvsTunnelFilterRequestPop(POVS_TUNFLT_REQUEST_LIST listRequests)
 {
+    POVS_TUNFLT_REQUEST request = NULL;
+
     NdisAcquireSpinLock(&listRequests->spinlock);
 
     if (!IsListEmpty(&listRequests->head)) {
-        PLIST_ENTRY PrevEntry;
-        PLIST_ENTRY NextEntry;
-
-        NextEntry = listRequests->head.Flink;
-        PrevEntry = listRequests->head.Blink;
-
-        head->Flink = NextEntry;
-        NextEntry->Blink = head;
-
-        head->Blink = PrevEntry;
-        PrevEntry->Flink = head;
-
-        *count = listRequests->numEntries;
-
-        InitializeListHead(&listRequests->head);
-        listRequests->numEntries = 0;
+        request = (POVS_TUNFLT_REQUEST)RemoveHeadList(&listRequests->head);
+        listRequests->numEntries--;
     }
 
     NdisReleaseSpinLock(&listRequests->spinlock);
+
+    return request;
 }
 
 /*
@@ -1056,16 +1043,10 @@ VOID
 OvsTunnelFilterRequestListProcess(POVS_TUNFLT_THREAD_CONTEXT threadCtx)
 {
     POVS_TUNFLT_REQUEST request = NULL;
-    PLIST_ENTRY         link = NULL;
-    PLIST_ENTRY         next = NULL;
-    LIST_ENTRY          head;
     NTSTATUS            status = STATUS_SUCCESS;
-    UINT32              count = 0;
     BOOLEAN             inTransaction = FALSE;
-    BOOLEAN             error = TRUE;
 
-    do
-    {
+    do {
         if (!InterlockedCompareExchange(
             (LONG volatile *)&threadCtx->listRequests.numEntries, 0, 0)) {
             OVS_LOG_INFO("Nothing to do... request list is empty.");
@@ -1080,38 +1061,24 @@ OvsTunnelFilterRequestListProcess(POVS_TUNFLT_THREAD_CONTEXT threadCtx)
         }
         inTransaction = TRUE;
 
-        InitializeListHead(&head);
-        OvsTunnelFilterRequestPopList(&threadCtx->listRequests, &head, &count);
-
-        LIST_FORALL_SAFE(&head, link, next) {
-            request = CONTAINING_RECORD(link, OVS_TUNFLT_REQUEST, entry);
-
-            status = OvsTunnelFilterExecuteAction(threadCtx->engineSession,
-                                                  request);
-            if (!NT_SUCCESS(status)) {
-                RemoveEntryList(&request->entry);
-                count--;
-
-                /* Complete the IRP with the failure status. */
-                OvsTunnelFilterCompleteRequest(request->irp,
-                                               request->callback,
-                                               request->context,
-                                               status);
-                OvsFreeMemory(request);
-                request = NULL;
-            } else {
-                error = FALSE;
-            }
-        }
+        while (NULL !=
+            (request = OvsTunnelFilterRequestPop(&threadCtx->listRequests))) {
 
-        if (error) {
-            /* No successful requests were made, so there is no point to commit
-             * the transaction. */
-            break;
+            OvsTunnelFilterExecuteAction(threadCtx->engineSession,
+                                         request);
+
+            /* Complete the IRP with the last operation status. */
+            OvsTunnelFilterCompleteRequest(request->irp,
+                                           request->callback,
+                                           request->context,
+                                           status);
+
+            OvsFreeMemory(request);
+            request = NULL;
         }
 
         status = FwpmTransactionCommit(threadCtx->engineSession);
-        if (!NT_SUCCESS(status)){
+        if (!NT_SUCCESS(status)) {
             OVS_LOG_ERROR("Failed to commit transaction, status: %x.",
                           status);
             break;
@@ -1125,20 +1092,6 @@ OvsTunnelFilterRequestListProcess(POVS_TUNFLT_THREAD_CONTEXT threadCtx)
         OVS_LOG_ERROR("Failed to execute request, status: %x.\
                        Transaction aborted.", status);
     }
-
-    /* Complete the requests successfully executed with the transaction commit
-     * status. */
-    while (count) {
-        request = (POVS_TUNFLT_REQUEST)RemoveHeadList(&head);
-        count--;
-
-        OvsTunnelFilterCompleteRequest(request->irp,
-                                       request->callback,
-                                       request->context,
-                                       status);
-        OvsFreeMemory(request);
-        request = NULL;
-    }
 }
 
 /*
@@ -1194,7 +1147,7 @@ OvsTunnelFilterThreadProc(PVOID context)
                     OvsTunnelFilterRequestListProcess(threadCtx);
                     break;
                 default:
-                    /* Finish processing the received requests and exit. */
+                    /* Finish processing the remaining requests and exit. */
                     OvsTunnelFilterRequestListProcess(threadCtx);
                     exit = TRUE;
                     break;
@@ -1423,6 +1376,10 @@ OvsTunnelFilterQueueRequest(PIRP irp,
     } while (error);
 
     if (error) {
+        OvsTunnelFilterCompleteRequest(irp,
+                                       callback,
+                                       tunnelContext,
+                                       status);
         if (request) {
             OvsFreeMemory(request);
             request = NULL;
-- 
1.9.0.msysgit.0



More information about the dev mailing list