Refactored CreateQueue function so that packets are enqueued to correct corresponding queue.
Signed-off-by: Ankur Sharma <ankursha...@vmware.com> --- datapath-windows/ovsext/Actions.c | 4 +- datapath-windows/ovsext/PacketIO.c | 2 +- datapath-windows/ovsext/Tunnel.c | 2 +- datapath-windows/ovsext/User.c | 78 ++++++++++++++++++++++---------------- 4 files changed, 49 insertions(+), 37 deletions(-) diff --git a/datapath-windows/ovsext/Actions.c b/datapath-windows/ovsext/Actions.c index 408b9be..f5ce12e 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 493c8cb..7eb6ed8 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/Tunnel.c b/datapath-windows/ovsext/Tunnel.c index eb45454..b55a223 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 95b8652..42b251f 100644 --- a/datapath-windows/ovsext/User.c +++ b/datapath-windows/ovsext/User.c @@ -668,8 +668,7 @@ OvsAddPidInstance(POVS_SWITCH_CONTEXT switchContext, UINT32 pid, UINT32 hash = OvsJhashBytes((const VOID *)&pid, sizeof(pid), OVS_HASH_BASIS); head = &(switchContext->pidHashArray[hash & OVS_PID_MASK]); - InsertHeadList(&gOvsSwitchContext->pidHashArray[hash & OVS_PID_MASK], - &(instance->pidLink)); + InsertHeadList(head, &(instance->pidLink)); } /* @@ -689,55 +688,67 @@ 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); + + /* XXX: There is a race condition here. + * What if queue is deleted after getQueue returns and + * before we take a queue lock. 2 ways of handling it: + * a. Either have a seperate instance lock. + * b. Move the queueLock to instance level. */ + 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; + } + } + } + + NdisReleaseSpinLock(&upcallQueue->queueLock); + } + } + + 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 -- @@ -1035,6 +1046,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; -- 1.9.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev