summaryrefslogtreecommitdiff
path: root/datapath-windows/ovsext/Event.c
diff options
context:
space:
mode:
authorNithin Raju <nithin@vmware.com>2015-11-25 12:00:55 -0800
committerGurucharan Shetty <gshetty@nicira.com>2015-11-25 13:54:28 -0800
commit9be4a8373394c3afcf80a4b02a12a914e7fc1eb9 (patch)
treecda8c971bd6c75490d4c0b4c0d6cd29a0fb7f786 /datapath-windows/ovsext/Event.c
parent958227c655d41821843e8d5d2b636f586b0cb5b4 (diff)
downloadopenvswitch-9be4a8373394c3afcf80a4b02a12a914e7fc1eb9.tar.gz
datapath-windows: cleanup events code
Turns out that we don't need to generate an event is practically useful only in case of a port disconnect to let userspace know. Hence, this event is being posted from HvDisconnectNic(). In case of a new port appearing, it seems that userspace is not interested in a new port unless it was added by userspace itself. In my tests, userspce would end up deleting the port when it got a new port notification, despite the port existing in OVSDB. The reasoning seems simple enough: - On Linux, OVS is integrated with the hypervisor (libvirt for eg) and a port (ie. netdev) gets created in the Linux kernel and then get added to OVSDB. When vswitchd picks up the port addition in OVSDB, it adds the port in the OVS kernel DP. - If the kernel netdev does not exist while OVS userspace tries to create the port in OVS kernel DP, port addition fails. Moreover, the only way to re-add the port is to trigger userspace to re-add the port by deleting the port in OVSDB and re-adding it. With this patch, I have verified that if a VIF gets disconnected on the Hyper-V switch, it disappears from the OVS kernel DP as well. Signed-off-by: Nithin Raju <nithin@vmware.com> Acked-by: Sairam Venugopal <vsairam@vmware.com> Acked-by: Alin Gabriel Serdean <aserdean@cloudbasesolutions.com> Signed-off-by: Gurucharan Shetty <guru@ovn.org>
Diffstat (limited to 'datapath-windows/ovsext/Event.c')
-rw-r--r--datapath-windows/ovsext/Event.c97
1 files changed, 36 insertions, 61 deletions
diff --git a/datapath-windows/ovsext/Event.c b/datapath-windows/ovsext/Event.c
index cca9575b7..c210da35c 100644
--- a/datapath-windows/ovsext/Event.c
+++ b/datapath-windows/ovsext/Event.c
@@ -31,7 +31,6 @@
LIST_ENTRY ovsEventQueue;
static NDIS_SPIN_LOCK eventQueueLock;
UINT32 ovsNumEventQueue;
-UINT32 ovsNumPollAll;
NTSTATUS
OvsInitEventQueue()
@@ -112,57 +111,37 @@ OvsCleanupEvent(POVS_OPEN_INSTANCE instance)
* --------------------------------------------------------------------------
*/
VOID
-OvsPostEvent(UINT32 portNo,
- UINT32 status)
+OvsPostEvent(POVS_EVENT_ENTRY event)
{
POVS_EVENT_QUEUE_ELEM elem;
POVS_EVENT_QUEUE queue;
PLIST_ENTRY link;
- BOOLEAN triggerPollAll = FALSE;
LIST_ENTRY list;
- PLIST_ENTRY entry;
+ PLIST_ENTRY entry;
PIRP irp;
InitializeListHead(&list);
- OVS_LOG_TRACE("Enter: portNo: %#x, status: %#x", portNo, status);
+ OVS_LOG_TRACE("Enter: portNo: %#x, status: %#x", event->portNo,
+ event->type);
OvsAcquireEventQueueLock();
LIST_FORALL(&ovsEventQueue, link) {
queue = CONTAINING_RECORD(link, OVS_EVENT_QUEUE, queueLink);
- if ((status & queue->mask) == 0 ||
- queue->pollAll) {
+ if ((event->type & queue->mask) == 0) {
continue;
}
- if (queue->numElems > (OVS_MAX_VPORT_ARRAY_SIZE >> 1) ||
- portNo == OVS_DEFAULT_PORT_NO) {
- queue->pollAll = TRUE;
- } else {
- elem = (POVS_EVENT_QUEUE_ELEM)OvsAllocateMemoryWithTag(
- sizeof(*elem), OVS_EVENT_POOL_TAG);
- if (elem == NULL) {
- queue->pollAll = TRUE;
- } else {
- elem->portNo = portNo;
- elem->status = (status & queue->mask);
- InsertTailList(&queue->elemList, &elem->link);
- queue->numElems++;
- OVS_LOG_INFO("Queue: %p, numElems: %d",
- queue, queue->numElems);
- }
- }
- if (queue->pollAll) {
- PLIST_ENTRY curr, next;
- triggerPollAll = TRUE;
- ovsNumPollAll++;
- LIST_FORALL_SAFE(&queue->elemList, curr, next) {
- RemoveEntryList(curr);
- elem = CONTAINING_RECORD(curr, OVS_EVENT_QUEUE_ELEM, link);
- OvsFreeMemoryWithTag(elem, OVS_EVENT_POOL_TAG);
- }
- queue->numElems = 0;
- }
+ event->type &= queue->mask;
+
+ elem = (POVS_EVENT_QUEUE_ELEM)OvsAllocateMemoryWithTag(
+ sizeof(*elem), OVS_EVENT_POOL_TAG);
+ RtlCopyMemory(&elem->event, event, sizeof elem->event);
+ InsertTailList(&queue->elemList, &elem->link);
+ queue->numElems++;
+ OVS_LOG_INFO("Queue: %p, numElems: %d",
+ queue, queue->numElems);
+
if (queue->pendingIrp != NULL) {
PDRIVER_CANCEL cancelRoutine;
irp = queue->pendingIrp;
@@ -180,8 +159,6 @@ OvsPostEvent(UINT32 portNo,
OVS_LOG_INFO("Wakeup thread with IRP: %p", irp);
OvsCompleteIrpRequest(irp, 0, STATUS_SUCCESS);
}
- OVS_LOG_TRACE("Exit: triggered pollAll: %s",
- (triggerPollAll ? "TRUE" : "FALSE"));
}
@@ -255,7 +232,6 @@ OvsSubscribeEventIoctl(PFILE_OBJECT fileObject,
queue->mask = request->mask;
queue->pendingIrp = NULL;
queue->numElems = 0;
- queue->pollAll = TRUE; /* always poll all in the begining */
InsertHeadList(&ovsEventQueue, &queue->queueLink);
ovsNumEventQueue++;
instance->eventQueue = queue;
@@ -360,11 +336,13 @@ OvsWaitEventIoctl(PIRP irp,
PVOID inputBuffer,
UINT32 inputLength)
{
- NTSTATUS status;
+ NTSTATUS status = STATUS_SUCCESS;
POVS_EVENT_POLL poll;
POVS_EVENT_QUEUE queue;
POVS_OPEN_INSTANCE instance;
BOOLEAN cancelled = FALSE;
+ PDRIVER_CANCEL cancelRoutine;
+
OVS_LOG_TRACE("Enter: inputLength: %u", inputLength);
if (inputLength < sizeof (OVS_EVENT_POLL)) {
@@ -377,38 +355,36 @@ OvsWaitEventIoctl(PIRP irp,
instance = OvsGetOpenInstance(fileObject, poll->dpNo);
if (instance == NULL) {
- OvsReleaseEventQueueLock();
- OVS_LOG_TRACE("Exit: Can not find open instance, dpNo: %d", poll->dpNo);
+ OVS_LOG_TRACE("Exit: Can not find open instance, dpNo: %d",
+ poll->dpNo);
return STATUS_INVALID_PARAMETER;
}
queue = (POVS_EVENT_QUEUE)instance->eventQueue;
if (queue == NULL) {
- OvsReleaseEventQueueLock();
OVS_LOG_TRACE("Exit: Event queue does not exist");
- return STATUS_INVALID_PARAMETER;
+ status = STATUS_INVALID_PARAMETER;
+ goto unlock;
}
if (queue->pendingIrp) {
- OvsReleaseEventQueueLock();
OVS_LOG_TRACE("Exit: Event queue already in pending state");
- return STATUS_DEVICE_BUSY;
+ status = STATUS_DEVICE_BUSY;
+ goto unlock;
}
- status = (queue->numElems != 0 || queue->pollAll) ?
- STATUS_SUCCESS : STATUS_PENDING;
- if (status == STATUS_PENDING) {
- PDRIVER_CANCEL cancelRoutine;
- IoMarkIrpPending(irp);
- IoSetCancelRoutine(irp, OvsCancelIrp);
- if (irp->Cancel) {
- cancelRoutine = IoSetCancelRoutine(irp, NULL);
- if (cancelRoutine) {
- cancelled = TRUE;
- }
- } else {
- queue->pendingIrp = irp;
+ IoMarkIrpPending(irp);
+ IoSetCancelRoutine(irp, OvsCancelIrp);
+ if (irp->Cancel) {
+ cancelRoutine = IoSetCancelRoutine(irp, NULL);
+ if (cancelRoutine) {
+ cancelled = TRUE;
}
+ } else {
+ queue->pendingIrp = irp;
+ status = STATUS_PENDING;
}
+
+unlock:
OvsReleaseEventQueueLock();
if (cancelled) {
OvsCompleteIrpRequest(irp, 0, STATUS_CANCELLED);
@@ -446,8 +422,7 @@ OvsRemoveEventEntry(POVS_OPEN_INSTANCE instance,
if (queue->numElems) {
elem = (POVS_EVENT_QUEUE_ELEM)RemoveHeadList(&queue->elemList);
- entry->portNo = elem->portNo;
- entry->status = elem->status;
+ *entry = elem->event;
OvsFreeMemoryWithTag(elem, OVS_EVENT_POOL_TAG);
queue->numElems--;
status = STATUS_SUCCESS;