[ofw] [PATCH] [RFC] winverbs/cq: separate error notification from completions

Sean Hefty sean.hefty at intel.com
Fri May 2 07:34:29 PDT 2008


Do not signal error notification requests when completion events occur.

An error will signal all pending notifications, but completion events will
only signal CQ rearm requests.

Signed-off-by: Sean Hefty <sean.hefty at intel.com>
---
Index: core/winverbs/kernel/wv_cq.c
===================================================================
--- core/winverbs/kernel/wv_cq.c	(revision 1113)
+++ core/winverbs/kernel/wv_cq.c	(working copy)
@@ -67,29 +67,33 @@
 	WvCqPut(pCq);
 }
 
-static void WvCqCompleteRequests(WV_COMPLETION_QUEUE *pCq, NTSTATUS ReqStatus)
+static void WvCqCompleteRequests(WDFQUEUE Queue, NTSTATUS ReqStatus)
 {
 	WDFREQUEST	request;
 	NTSTATUS	status;
 
-	WdfObjectAcquireLock(pCq->Queue);
-	status = WdfIoQueueRetrieveNextRequest(pCq->Queue, &request);
+	WdfObjectAcquireLock(Queue);
+	status = WdfIoQueueRetrieveNextRequest(Queue, &request);
 
 	while (NT_SUCCESS(status)) {
 		WdfRequestComplete(request, ReqStatus);
-		status = WdfIoQueueRetrieveNextRequest(pCq->Queue, &request);
+		status = WdfIoQueueRetrieveNextRequest(Queue, &request);
 	}
-	WdfObjectReleaseLock(pCq->Queue);
+	WdfObjectReleaseLock(Queue);
 }
 
 static void WvCqEventHandler(ib_event_rec_t *pEvent)
 {
-	WvCqCompleteRequests(pEvent->context, STATUS_UNEXPECTED_IO_ERROR);
+	WV_COMPLETION_QUEUE	*cq = pEvent->context;
+	WvCqCompleteRequests(cq->Queue, STATUS_UNEXPECTED_IO_ERROR);
+	WvCqCompleteRequests(cq->ErrorQueue, STATUS_UNEXPECTED_IO_ERROR);
 }
 
 static void WvCqHandler(void *Context)
 {
-	WvCqCompleteRequests(Context, STATUS_SUCCESS);
+	WV_COMPLETION_QUEUE	*cq = Context;
+
+	WvCqCompleteRequests(cq->Queue, STATUS_SUCCESS);
 }
 
 static NTSTATUS WvCqAlloc(WV_DEVICE *pDevice, UINT32 *pSize,
@@ -115,18 +119,26 @@
 		goto err1;
 	}
 
+	status = WdfIoQueueCreate(ControlDevice, &config,
+							  WDF_NO_OBJECT_ATTRIBUTES, &cq->ErrorQueue);
+	if (!NT_SUCCESS(status)) {
+		goto err2;
+	}
+
 	ib_status = pDevice->pVerbs->create_cq(pDevice->hVerbsDevice, cq,
 										   WvCqEventHandler, WvCqHandler,
 										   pSize, &cq->hVerbsCq, pVerbsData);
 	if (ib_status != IB_SUCCESS) {
 		status = STATUS_UNSUCCESSFUL;
-		goto err2;
+		goto err3;
 	}
 
 	cq->pVerbs = pDevice->pVerbs;
 	*ppCq = cq;
 	return STATUS_SUCCESS;
 
+err3:
+	WdfObjectDelete(cq->ErrorQueue);
 err2:
 	WdfObjectDelete(cq->Queue);
 err1:
@@ -233,7 +245,9 @@
 	}
 
 	WdfIoQueuePurgeSynchronously(pCq->Queue);
+	WdfIoQueuePurgeSynchronously(pCq->ErrorQueue);
 	WdfObjectDelete(pCq->Queue);
+	WdfObjectDelete(pCq->ErrorQueue);
 	WvDevicePut(pCq->pDevice);
 	ExFreePool(pCq);
 }
@@ -281,24 +295,26 @@
 
 void WvCqNotify(WV_PROVIDER *pProvider, WDFREQUEST Request)
 {
-	UINT64					*id;
+	WV_IO_ID				*id;
 	WV_COMPLETION_QUEUE		*cq;
 	NTSTATUS				status;
+	WDFQUEUE				queue;
 
-	status = WdfRequestRetrieveInputBuffer(Request, sizeof(UINT64), &id, NULL);
+	status = WdfRequestRetrieveInputBuffer(Request, sizeof(WV_IO_ID), &id, NULL);
 	if (!NT_SUCCESS(status)) {
 		goto out;
 	}
 
-	cq = WvCqAcquire(pProvider, *id);
+	cq = WvCqAcquire(pProvider, id->Id);
 	if (cq == NULL) {
 		status = STATUS_NOT_FOUND;
 		goto out;
 	}
 
-	WdfObjectAcquireLock(cq->Queue);
-	status = WdfRequestForwardToIoQueue(Request, cq->Queue);
-	WdfObjectReleaseLock(cq->Queue);
+	queue = (id->Data == WV_CQ_ERROR) ? cq->ErrorQueue : cq->Queue;
+	WdfObjectAcquireLock(queue);
+	status = WdfRequestForwardToIoQueue(Request, queue);
+	WdfObjectReleaseLock(queue);
 	WvCqRelease(cq);
 
 out:
@@ -324,7 +340,8 @@
 		goto out;
 	}
 
-	WvCqCompleteRequests(cq, STATUS_CANCELLED);
+	WvCqCompleteRequests(cq->Queue, STATUS_CANCELLED);
+	WvCqCompleteRequests(cq->ErrorQueue, STATUS_CANCELLED);
 	WvCqRelease(cq);
 
 out:
Index: core/winverbs/kernel/wv_cq.h
===================================================================
--- core/winverbs/kernel/wv_cq.h	(revision 1099)
+++ core/winverbs/kernel/wv_cq.h	(working copy)
@@ -50,6 +50,7 @@
 	KEVENT				Event;
 	LONG				Ref;
 	WDFQUEUE			Queue;
+	WDFQUEUE			ErrorQueue;
 
 }	WV_COMPLETION_QUEUE;
 
Index: core/winverbs/user/wv_cq.cpp
===================================================================
--- core/winverbs/user/wv_cq.cpp	(revision 1113)
+++ core/winverbs/user/wv_cq.cpp	(working copy)
@@ -222,10 +222,13 @@
 STDMETHODIMP CWVCompletionQueue::
 Notify(WV_CQ_NOTIFY_TYPE Type, OVERLAPPED* pOverlapped)
 {
+	WV_IO_ID	id;
 	DWORD		bytes;
 	HRESULT		hr;
 
-	if (DeviceIoControl(m_hFile, WV_IOCTL_CQ_NOTIFY, &m_Id, sizeof m_Id,
+	id.Id = m_Id;
+	id.Data = Type;
+	if (DeviceIoControl(m_hFile, WV_IOCTL_CQ_NOTIFY, &id, sizeof id,
 						NULL, 0, &bytes, pOverlapped)) {
 		switch (Type) {
 		case WvCqSolicited:
Index: core/winverbs/wv_ioctl.h
===================================================================
--- core/winverbs/wv_ioctl.h	(revision 1113)
+++ core/winverbs/wv_ioctl.h	(working copy)
@@ -182,7 +182,7 @@
 #define WV_IOCTL_CQ_RESIZE				WV_IOCTL(WV_IO_FUNCTION_BASE + \
 
WV_IO_FUNCTION_CQ_RESIZE)
 
-// UINT64 Id / none
+// WV_IO_ID / none
 #define WV_IOCTL_CQ_NOTIFY				WV_IOCTL(WV_IO_FUNCTION_BASE + \
 
WV_IO_FUNCTION_CQ_NOTIFY)
 
@@ -457,6 +457,10 @@
 
 }	WV_IO_AH_CREATE;
 
+#define WV_CQ_ERROR				0
+#define	WV_CQ_SOLICITED			1
+#define	WV_CQ_NEXT_COMPLETION	2
+
 typedef struct _WV_IO_SRQ_ATTRIBUTES
 {
 	WV_IO_ID		Id;





More information about the ofw mailing list