Skip to content

Commit

Permalink
datapath-windows: Refactor CreateQueue function to handle vport pid.
Browse files Browse the repository at this point in the history
Refactored CreateQueue function so that packets are enqueued to correct corresponding queue.

Signed-off-by: Ankur Sharma <[email protected]>
Acked-by: Eitan Eliahu <[email protected]>
Acked-by: Alin Gabriel Serdean <[email protected]>
Signed-off-by: Ben Pfaff <[email protected]>
  • Loading branch information
ankursh authored and blp committed Oct 24, 2014
1 parent d0ce116 commit 4a3c9b7
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 44 deletions.
4 changes: 2 additions & 2 deletions datapath-windows/ovsext/Actions.c
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion datapath-windows/ovsext/PacketIO.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ OvsStartNBLIngress(POVS_SWITCH_CONTEXT switchContext,
}

/* Queue the missed packets. */
OvsQueuePackets(OVS_DEFAULT_PACKET_QUEUE, &missedPackets, num);
OvsQueuePackets(&missedPackets, num);
OvsFinalizeCompletionList(&completionList);
}

Expand Down
2 changes: 2 additions & 0 deletions datapath-windows/ovsext/Switch.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down
1 change: 1 addition & 0 deletions datapath-windows/ovsext/Switch.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion datapath-windows/ovsext/Tunnel.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
108 changes: 70 additions & 38 deletions datapath-windows/ovsext/User.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand All @@ -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 */
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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 --
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions datapath-windows/ovsext/User.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 4a3c9b7

Please sign in to comment.