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

Signed-off-by: Sorin Vinturis <svintu...@cloudbasesolutions.com>
---
 datapath-windows/ovsext/TunnelFilter.c | 89 +++++++++++-----------------------
 1 file changed, 27 insertions(+), 62 deletions(-)

diff --git a/datapath-windows/ovsext/TunnelFilter.c 
b/datapath-windows/ovsext/TunnelFilter.c
index 231750e..caaf3f6 100644
--- a/datapath-windows/ovsext/TunnelFilter.c
+++ b/datapath-windows/ovsext/TunnelFilter.c
@@ -951,38 +951,26 @@ 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);
+        InitializeListHead(&request->entry);
+        listRequests->numEntries--;
     }
 
     NdisReleaseSpinLock(&listRequests->spinlock);
+
+    return request;
 }
 
 /*
@@ -1052,16 +1040,11 @@ 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;
+    BOOLEAN             error = FALSE;
 
-    do
-    {
+    do {
         if (!InterlockedCompareExchange(
             (LONG volatile *)&threadCtx->listRequests.numEntries, 0, 0)) {
             OVS_LOG_INFO("Nothing to do... request list is empty.");
@@ -1076,27 +1059,23 @@ 
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);
+        while (NULL != (request = OvsTunnelFilterRequestPop(
+            &threadCtx->listRequests))) {
 
             status = OvsTunnelFilterExecuteAction(threadCtx->engineSession,
                                                   request);
+
+            /* Complete the IRP last operation status. */
+            OvsTunnelFilterCompleteRequest(request->irp,
+                                           request->callback,
+                                           request->context,
+                                           status);
+            OvsFreeMemory(request);
+            request = NULL;
+
             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;
+                error = TRUE;
+                break;
             }
         }
 
@@ -1107,7 +1086,7 @@ 
OvsTunnelFilterRequestListProcess(POVS_TUNFLT_THREAD_CONTEXT threadCtx)
         }
 
         status = FwpmTransactionCommit(threadCtx->engineSession);
-        if (!NT_SUCCESS(status)){
+        if (!NT_SUCCESS(status)) {
             OVS_LOG_ERROR("Failed to commit transaction, status: %x.",
                           status);
             break;
@@ -1121,20 +1100,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;
-    }
 }
 
 /*
-- 
1.9.0.msysgit.0
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to