diff options
author | Ankur Sharma <ankursharma@vmware.com> | 2014-10-23 14:24:28 -0700 |
---|---|---|
committer | Ben Pfaff <blp@nicira.com> | 2014-10-24 08:47:35 -0700 |
commit | 4a3c9b7048fe7f7af444954b36f7bb104d6d6389 (patch) | |
tree | 59a1e293cbde7ef6c19e293f6c038bce44fe5336 /datapath-windows | |
parent | d0ce116055ad4bc2f59803f55ac4de34f47d45f8 (diff) | |
download | openvswitch-4a3c9b7048fe7f7af444954b36f7bb104d6d6389.tar.gz |
datapath-windows: Refactor CreateQueue function to handle vport pid.
Refactored CreateQueue function so that packets are enqueued to correct corresponding queue.
Signed-off-by: Ankur Sharma <ankursharma@vmware.com>
Acked-by: Eitan Eliahu <eliahue@vmware.com>
Acked-by: Alin Gabriel Serdean <aserdean@cloudbasesolutions.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
Diffstat (limited to 'datapath-windows')
-rw-r--r-- | datapath-windows/ovsext/Actions.c | 4 | ||||
-rw-r--r-- | datapath-windows/ovsext/PacketIO.c | 2 | ||||
-rw-r--r-- | datapath-windows/ovsext/Switch.c | 2 | ||||
-rw-r--r-- | datapath-windows/ovsext/Switch.h | 1 | ||||
-rw-r--r-- | datapath-windows/ovsext/Tunnel.c | 2 | ||||
-rw-r--r-- | datapath-windows/ovsext/User.c | 108 | ||||
-rw-r--r-- | datapath-windows/ovsext/User.h | 4 |
7 files changed, 79 insertions, 44 deletions
diff --git a/datapath-windows/ovsext/Actions.c b/datapath-windows/ovsext/Actions.c index 408b9be2a..f5ce12e90 100644 --- a/datapath-windows/ovsext/Actions.c +++ b/datapath-windows/ovsext/Actions.c @@ -564,7 +564,7 @@ OvsDoFlowLookupOutput(OvsForwardingContext *ovsFwdCtx) ovsFwdCtx->tunnelRxNic != NULL, &ovsFwdCtx->layers, ovsFwdCtx->switchContext, &missedPackets, &num); if (num) { - OvsQueuePackets(OVS_DEFAULT_PACKET_QUEUE, &missedPackets, num); + OvsQueuePackets(&missedPackets, num); } if (status == NDIS_STATUS_SUCCESS) { /* Complete the packet since it was copied to user buffer. */ @@ -1495,7 +1495,7 @@ OvsActionsExecute(POVS_SWITCH_CONTEXT switchContext, LIST_ENTRY missedPackets; InitializeListHead(&missedPackets); InsertTailList(&missedPackets, &elem->link); - OvsQueuePackets(OVS_DEFAULT_PACKET_QUEUE, &missedPackets, 1); + OvsQueuePackets(&missedPackets, 1); dropReason = L"OVS-Completed since packet was copied to " L"userspace"; } else { diff --git a/datapath-windows/ovsext/PacketIO.c b/datapath-windows/ovsext/PacketIO.c index 493c8cb90..7eb6ed837 100644 --- a/datapath-windows/ovsext/PacketIO.c +++ b/datapath-windows/ovsext/PacketIO.c @@ -314,7 +314,7 @@ dropit: } /* Queue the missed packets. */ - OvsQueuePackets(OVS_DEFAULT_PACKET_QUEUE, &missedPackets, num); + OvsQueuePackets(&missedPackets, num); OvsFinalizeCompletionList(&completionList); } diff --git a/datapath-windows/ovsext/Switch.c b/datapath-windows/ovsext/Switch.c index 5593d43c4..f44550078 100644 --- a/datapath-windows/ovsext/Switch.c +++ b/datapath-windows/ovsext/Switch.c @@ -411,6 +411,7 @@ OvsInitSwitchContext(POVS_SWITCH_CONTEXT switchContext) InitializeListHead(&switchContext->pidHashArray[i]); } + NdisAllocateSpinLock(&(switchContext->pidHashLock)); switchContext->isActivated = FALSE; switchContext->isActivateFailed = FALSE; switchContext->dpNo = OVS_DP_NUMBER; @@ -429,6 +430,7 @@ OvsCleanupSwitchContext(POVS_SWITCH_CONTEXT switchContext) ASSERT(switchContext->numVports == 0); NdisFreeRWLock(switchContext->dispatchLock); + NdisFreeSpinLock(&(switchContext->pidHashLock)); OvsFreeMemory(switchContext->ovsPortNameHashArray); OvsFreeMemory(switchContext->portIdHashArray); OvsFreeMemory(switchContext->portNoHashArray); diff --git a/datapath-windows/ovsext/Switch.h b/datapath-windows/ovsext/Switch.h index 7fdca5f3a..b61462b43 100644 --- a/datapath-windows/ovsext/Switch.h +++ b/datapath-windows/ovsext/Switch.h @@ -110,6 +110,7 @@ typedef struct _OVS_SWITCH_CONTEXT PLIST_ENTRY portIdHashArray; // based on portId PLIST_ENTRY portNoHashArray; // based on ovs port number PLIST_ENTRY pidHashArray; // based on packet pids + NDIS_SPIN_LOCK pidHashLock; // Lock for pidHash table UINT32 numPhysicalNics; UINT32 numVports; // include validation port diff --git a/datapath-windows/ovsext/Tunnel.c b/datapath-windows/ovsext/Tunnel.c index eb45454de..b55a223c6 100644 --- a/datapath-windows/ovsext/Tunnel.c +++ b/datapath-windows/ovsext/Tunnel.c @@ -320,7 +320,7 @@ OvsInjectPacketThroughActions(PNET_BUFFER_LIST pNbl, if (elem) { /* Complete the packet since it was copied to user buffer. */ InsertTailList(&missedPackets, &elem->link); - OvsQueuePackets(OVS_DEFAULT_PACKET_QUEUE, &missedPackets, 1); + OvsQueuePackets(&missedPackets, 1); } else { status = STATUS_INSUFFICIENT_RESOURCES; } diff --git a/datapath-windows/ovsext/User.c b/datapath-windows/ovsext/User.c index f6b11571e..501dc12c4 100644 --- a/datapath-windows/ovsext/User.c +++ b/datapath-windows/ovsext/User.c @@ -49,6 +49,19 @@ static VOID _MapNlAttrToOvsPktExec(PNL_ATTR *nlAttrs, PNL_ATTR *keyAttrs, OvsPacketExecute *execute); extern NL_POLICY nlFlowKeyPolicy[]; +static __inline VOID +OvsAcquirePidHashLock() +{ + NdisAcquireSpinLock(&(gOvsSwitchContext->pidHashLock)); +} + +static __inline VOID +OvsReleasePidHashLock() +{ + NdisReleaseSpinLock(&(gOvsSwitchContext->pidHashLock)); +} + + static VOID OvsPurgePacketQueue(POVS_USER_PACKET_QUEUE queue, POVS_OPEN_INSTANCE instance) @@ -147,10 +160,10 @@ OvsSubscribeDpIoctl(PVOID instanceP, /* unsubscribe */ OvsCleanupPacketQueue(instance); - OvsAcquireCtrlLock(); + OvsAcquirePidHashLock(); /* Remove the instance from pidHashArray */ OvsDelPidInstance(gOvsSwitchContext, pid); - OvsReleaseCtrlLock(); + OvsReleasePidHashLock(); } else if (instance->packetQueue == NULL && join) { queue = (POVS_USER_PACKET_QUEUE) OvsAllocateMemory(sizeof *queue); @@ -168,10 +181,10 @@ OvsSubscribeDpIoctl(PVOID instanceP, instance->packetQueue = queue; NdisReleaseSpinLock(&queue->queueLock); - OvsAcquireCtrlLock(); + OvsAcquirePidHashLock(); /* Insert the instance to pidHashArray */ OvsAddPidInstance(gOvsSwitchContext, pid, instance); - OvsReleaseCtrlLock(); + OvsReleasePidHashLock(); } else { /* user mode should call only once for subscribe */ @@ -633,7 +646,7 @@ OvsGetQueue(UINT32 pid) /* * --------------------------------------------------------------------------- * Given a pid, returns the corresponding instance. - * gOvsCtrlLock must be acquired before calling this API. + * pidHashLock must be acquired before calling this API. * --------------------------------------------------------------------------- */ POVS_OPEN_INSTANCE @@ -656,7 +669,7 @@ OvsGetPidInstance(POVS_SWITCH_CONTEXT switchContext, UINT32 pid) /* * --------------------------------------------------------------------------- * Given a pid and an instance. This API adds instance to pidHashArray. - * gOvsCtrlLock must be acquired before calling this API. + * pidHashLock must be acquired before calling this API. * --------------------------------------------------------------------------- */ VOID @@ -673,7 +686,7 @@ OvsAddPidInstance(POVS_SWITCH_CONTEXT switchContext, UINT32 pid, /* * --------------------------------------------------------------------------- * Given a pid and an instance. This API removes instance from pidHashArray. - * gOvsCtrlLock must be acquired before calling this API. + * pidHashLock must be acquired before calling this API. * --------------------------------------------------------------------------- */ VOID @@ -687,55 +700,71 @@ OvsDelPidInstance(POVS_SWITCH_CONTEXT switchContext, UINT32 pid) } VOID -OvsQueuePackets(UINT32 queueId, - PLIST_ENTRY packetList, +OvsQueuePackets(PLIST_ENTRY packetList, UINT32 numElems) { - POVS_USER_PACKET_QUEUE queue = OvsGetQueue(queueId); + POVS_USER_PACKET_QUEUE upcallQueue = NULL; POVS_PACKET_QUEUE_ELEM elem; PIRP irp = NULL; PLIST_ENTRY link; UINT32 num = 0; + LIST_ENTRY dropPackets; - OVS_LOG_LOUD("Enter: queueId %u, numELems: %u", - queueId, numElems); - if (queue == NULL) { - goto cleanup; - } + OVS_LOG_LOUD("Enter: numELems: %u", numElems); - NdisAcquireSpinLock(&queue->queueLock); - if (queue->instance == NULL) { - NdisReleaseSpinLock(&queue->queueLock); - goto cleanup; - } else { - OvsAppendList(&queue->packetList, packetList); - queue->numPackets += numElems; - } - if (queue->pendingIrp) { - PDRIVER_CANCEL cancelRoutine; - irp = queue->pendingIrp; - queue->pendingIrp = NULL; - cancelRoutine = IoSetCancelRoutine(irp, NULL); - if (cancelRoutine == NULL) { - irp = NULL; - } - } - NdisReleaseSpinLock(&queue->queueLock); - if (irp) { - OvsCompleteIrpRequest(irp, 0, STATUS_SUCCESS); - } + InitializeListHead(&dropPackets); -cleanup: while (!IsListEmpty(packetList)) { link = RemoveHeadList(packetList); elem = CONTAINING_RECORD(link, OVS_PACKET_QUEUE_ELEM, link); + + ASSERT(elem); + + OvsAcquirePidHashLock(); + + upcallQueue = OvsGetQueue(elem->upcallPid); + if (!upcallQueue) { + /* No upcall queue found, drop this packet. */ + InsertTailList(&dropPackets, &elem->link); + } else { + NdisAcquireSpinLock(&upcallQueue->queueLock); + + if (upcallQueue->instance == NULL) { + InsertTailList(&dropPackets, &elem->link); + } else { + InsertTailList(&upcallQueue->packetList, &elem->link); + upcallQueue->numPackets++; + if (upcallQueue->pendingIrp) { + PDRIVER_CANCEL cancelRoutine; + irp = upcallQueue->pendingIrp; + upcallQueue->pendingIrp = NULL; + cancelRoutine = IoSetCancelRoutine(irp, NULL); + if (cancelRoutine == NULL) { + irp = NULL; + } + } + } + + if (irp) { + OvsCompleteIrpRequest(irp, 0, STATUS_SUCCESS); + } + + NdisReleaseSpinLock(&upcallQueue->queueLock); + } + + OvsReleasePidHashLock(); + } + + while (!IsListEmpty(&dropPackets)) { + link = RemoveHeadList(&dropPackets); + elem = CONTAINING_RECORD(link, OVS_PACKET_QUEUE_ELEM, link); OvsFreeMemory(elem); num++; } + OVS_LOG_LOUD("Exit: drop %u packets", num); } - /* *---------------------------------------------------------------------------- * OvsCreateAndAddPackets -- @@ -932,6 +961,8 @@ OvsGetPid(POVS_VPORT_ENTRY vport, PNET_BUFFER nb, UINT32 *pid) { UNREFERENCED_PARAMETER(nb); + ASSERT(vport); + /* XXX select a pid from an array of pids using a flow based hash */ *pid = vport->upcallPid; return STATUS_SUCCESS; @@ -1031,6 +1062,7 @@ OvsCreateQueueNlPacket(PVOID userData, return NULL; } elem->hdrInfo.value = hdrInfo->value; + elem->upcallPid = pid; elem->packet.totalLen = nlMsgSize; /* XXX remove queueid */ elem->packet.queue = 0; diff --git a/datapath-windows/ovsext/User.h b/datapath-windows/ovsext/User.h index 1050ae88b..139b0ca47 100644 --- a/datapath-windows/ovsext/User.h +++ b/datapath-windows/ovsext/User.h @@ -49,6 +49,7 @@ typedef struct _OVS_USER_PACKET_QUEUE { } OVS_USER_PACKET_QUEUE, *POVS_USER_PACKET_QUEUE; typedef struct _OVS_PACKET_QUEUE_ELEM { + UINT32 upcallPid; LIST_ENTRY link; OVS_PACKET_HDR_INFO hdrInfo; OVS_PACKET_INFO packet; @@ -78,8 +79,7 @@ POVS_PACKET_QUEUE_ELEM OvsCreateQueueNlPacket(PVOID userData, BOOLEAN isRecv, POVS_PACKET_HDR_INFO hdrInfo); -VOID OvsQueuePackets(UINT32 queueId, PLIST_ENTRY packetList, - UINT32 numElems); +VOID OvsQueuePackets(PLIST_ENTRY packetList, UINT32 numElems); NTSTATUS OvsCreateAndAddPackets(PVOID userData, UINT32 userDataLen, UINT32 cmd, |