LIST_ENTRY ovsEventQueue;
static NDIS_SPIN_LOCK eventQueueLock;
UINT32 ovsNumEventQueue;
-UINT32 ovsNumPollAll;
NTSTATUS
OvsInitEventQueue()
LIST_FORALL_SAFE(&queue->elemList, link, next) {
elem = CONTAINING_RECORD(link, OVS_EVENT_QUEUE_ELEM, link);
- OvsFreeMemory(elem);
+ OvsFreeMemoryWithTag(elem, OVS_EVENT_POOL_TAG);
}
- OvsFreeMemory(queue);
+ OvsFreeMemoryWithTag(queue, OVS_EVENT_POOL_TAG);
}
}
* --------------------------------------------------------------------------
*/
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)OvsAllocateMemory(sizeof(*elem));
- 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);
- OvsFreeMemory(elem);
- }
- 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;
OVS_LOG_INFO("Wakeup thread with IRP: %p", irp);
OvsCompleteIrpRequest(irp, 0, STATUS_SUCCESS);
}
- OVS_LOG_TRACE("Exit: triggered pollAll: %s",
- (triggerPollAll ? "TRUE" : "FALSE"));
}
}
if (request->subscribe) {
- queue = (POVS_EVENT_QUEUE)OvsAllocateMemory(sizeof (OVS_EVENT_QUEUE));
+ queue = (POVS_EVENT_QUEUE)OvsAllocateMemoryWithTag(
+ sizeof(OVS_EVENT_QUEUE), OVS_EVENT_POOL_TAG);
if (queue == NULL) {
status = STATUS_NO_MEMORY;
OVS_LOG_WARN("Fail to allocate event queue");
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;
}
LIST_FORALL_SAFE(&queue->elemList, link, next) {
elem = CONTAINING_RECORD(link, OVS_EVENT_QUEUE_ELEM, link);
- OvsFreeMemory(elem);
+ OvsFreeMemoryWithTag(elem, OVS_EVENT_POOL_TAG);
}
- OvsFreeMemory(queue);
+ OvsFreeMemoryWithTag(queue, OVS_EVENT_POOL_TAG);
} else {
OvsReleaseEventQueueLock();
}
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)) {
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);
if (queue->numElems) {
elem = (POVS_EVENT_QUEUE_ELEM)RemoveHeadList(&queue->elemList);
- entry->portNo = elem->portNo;
- entry->status = elem->status;
- OvsFreeMemory(elem);
+ *entry = elem->event;
+ OvsFreeMemoryWithTag(elem, OVS_EVENT_POOL_TAG);
queue->numElems--;
status = STATUS_SUCCESS;
}