diff mbox

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

Message ID 1441054394-4996-1-git-send-email-svinturis@cloudbasesolutions.com
State Accepted
Headers show

Commit Message

Sorin Vinturis Aug. 31, 2015, 8:53 p.m. UTC
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@cloudbasesolutions.com>
---
 datapath-windows/ovsext/TunnelFilter.c | 103 ++++++++++-----------------------
 1 file changed, 30 insertions(+), 73 deletions(-)

Comments

Nithin Raju Aug. 31, 2015, 9:11 p.m. UTC | #1
> On Aug 31, 2015, at 1:53 PM, Sorin Vinturis <svinturis@cloudbasesolutions.com> wrote:
> 
> 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@cloudbasesolutions.com>

Acked-by: Nithin Raju <nithin@vmware.com>
Ben Pfaff Aug. 31, 2015, 9:20 p.m. UTC | #2
On Mon, Aug 31, 2015 at 09:11:05PM +0000, Nithin Raju wrote:
> > On Aug 31, 2015, at 1:53 PM, Sorin Vinturis <svinturis@cloudbasesolutions.com> wrote:
> > 
> > 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@cloudbasesolutions.com>
> 
> Acked-by: Nithin Raju <nithin@vmware.com>

Thanks Sorin and Nithin, applied to master and branch-2.4.
diff mbox

Patch

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;
+            status = 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;