summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--datapath-windows/ovsext/BufferMgmt.c9
-rw-r--r--datapath-windows/ovsext/BufferMgmt.h2
-rw-r--r--datapath-windows/ovsext/PacketIO.c10
3 files changed, 20 insertions, 1 deletions
diff --git a/datapath-windows/ovsext/BufferMgmt.c b/datapath-windows/ovsext/BufferMgmt.c
index 47d872df2..6627acf25 100644
--- a/datapath-windows/ovsext/BufferMgmt.c
+++ b/datapath-windows/ovsext/BufferMgmt.c
@@ -81,6 +81,7 @@
#include "Flow.h"
#include "Offload.h"
#include "NetProto.h"
+#include "PacketIO.h"
#include "PacketParser.h"
#include "Switch.h"
#include "Vport.h"
@@ -267,6 +268,7 @@ OvsInitNBLContext(POVS_BUFFER_CONTEXT ctx,
ctx->srcPortNo = srcPortNo;
ctx->origDataLength = origDataLength;
ctx->mru = 0;
+ ctx->pendingSend = 0;
}
@@ -1746,8 +1748,13 @@ OvsCompleteNBL(PVOID switch_ctx,
if (parent != NULL) {
ctx = (POVS_BUFFER_CONTEXT)NET_BUFFER_LIST_CONTEXT_DATA_START(parent);
ASSERT(ctx && ctx->magic == OVS_CTX_MAGIC);
+ UINT16 pendingSend = 1, exchange = 0;
value = InterlockedDecrement((LONG volatile *)&ctx->refCount);
- if (value == 0) {
+ InterlockedCompareExchange16((SHORT volatile *)&pendingSend, exchange, (SHORT)ctx->pendingSend);
+ if (value == 1 && pendingSend == exchange) {
+ InterlockedExchange16((SHORT volatile *)&ctx->pendingSend, 0);
+ OvsSendNBLIngress(context, parent, ctx->sendFlags);
+ } else if (value == 0){
return OvsCompleteNBL(context, parent, FALSE);
}
}
diff --git a/datapath-windows/ovsext/BufferMgmt.h b/datapath-windows/ovsext/BufferMgmt.h
index 2a74988b8..2ae32723e 100644
--- a/datapath-windows/ovsext/BufferMgmt.h
+++ b/datapath-windows/ovsext/BufferMgmt.h
@@ -55,7 +55,9 @@ typedef union _OVS_BUFFER_CONTEXT {
UINT32 origDataLength;
UINT32 dataOffsetDelta;
};
+ ULONG sendFlags;
UINT16 mru;
+ UINT16 pendingSend; /* Indicates packet can be sent or not. */
};
CHAR value[MEM_ALIGN_SIZE(sizeof(struct dummy))];
diff --git a/datapath-windows/ovsext/PacketIO.c b/datapath-windows/ovsext/PacketIO.c
index 57c583ccf..cc0840704 100644
--- a/datapath-windows/ovsext/PacketIO.c
+++ b/datapath-windows/ovsext/PacketIO.c
@@ -161,6 +161,16 @@ OvsSendNBLIngress(POVS_SWITCH_CONTEXT switchContext,
ASSERT(switchContext->dataFlowState == OvsSwitchRunning);
+ POVS_BUFFER_CONTEXT ctx = (POVS_BUFFER_CONTEXT)NET_BUFFER_LIST_CONTEXT_DATA_START(netBufferLists);
+ LONG refCount = 1, exchange = 0;
+ InterlockedCompareExchange((LONG volatile *)&refCount, exchange, (LONG)ctx->refCount);
+ if (refCount != exchange) {
+ InterlockedExchange((LONG volatile *)&ctx->sendFlags, sendFlags);
+ InterlockedExchange16((SHORT volatile *)&ctx->pendingSend, 1);
+ return;
+ }
+
+ InterlockedExchange16((SHORT volatile *)&ctx->pendingSend, 0);
NdisFSendNetBufferLists(switchContext->NdisFilterHandle, netBufferLists,
NDIS_DEFAULT_PORT_NUMBER, sendFlags);
}