[ovs-dev] [PATCH v2 1/2] datapath-windows: Process tunnel filter requests iteratively
Sorin Vinturis
svinturis at cloudbasesolutions.com
Mon Jul 20 19:00:44 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 | 107 +++++++++------------------------
1 file changed, 30 insertions(+), 77 deletions(-)
diff --git a/datapath-windows/ovsext/TunnelFilter.c b/datapath-windows/ovsext/TunnelFilter.c
index d736c19..b6c60c3 100644
--- a/datapath-windows/ovsext/TunnelFilter.c
+++ b/datapath-windows/ovsext/TunnelFilter.c
@@ -951,38 +951,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;
}
/*
@@ -1030,21 +1017,20 @@ OvsTunnelFilterThreadPush(POVS_TUNFLT_REQUEST request)
}
VOID
-OvsTunnelFilterCompleteRequest(PIRP irp,
- PFNTunnelVportPendingOp callback,
- PVOID context,
+OvsTunnelFilterCompleteRequest(POVS_TUNFLT_REQUEST request,
NTSTATUS status)
{
+ PFNTunnelVportPendingOp callback = request->callback;
UINT32 replyLen = 0;
if (callback) {
- callback(context, status, &replyLen);
+ callback(request->context, status, &replyLen);
/* Release the context passed to the callback function. */
- OvsFreeMemory(context);
+ OvsFreeMemory(request->context);
}
- if (irp) {
- OvsCompleteIrpRequest(irp, (ULONG_PTR)replyLen, status);
+ if (request->irp) {
+ OvsCompleteIrpRequest(request->irp, (ULONG_PTR)replyLen, status);
}
}
@@ -1052,16 +1038,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.");
@@ -1076,38 +1056,25 @@ 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 with the last operation status. */
+ OvsTunnelFilterCompleteRequest(request, 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;
+ break;
}
}
- if (error) {
- /* No successful requests were made, so there is no point to commit
- * the transaction. */
- break;
- }
-
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 +1088,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;
- }
}
/*
@@ -1190,7 +1143,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;
@@ -1419,7 +1372,7 @@ OvsTunnelFilterQueueRequest(PIRP irp,
} while (error);
if (error) {
- OvsTunnelFilterCompleteRequest(irp, callback, tunnelContext, status);
+ OvsTunnelFilterCompleteRequest(request, status);
if (request) {
OvsFreeMemory(request);
request = NULL;
--
1.9.0.msysgit.0
More information about the dev
mailing list