[ofw] [PATCH][RFC] winverbs/cq: implement CQ:Notify()

Sean Hefty sean.hefty at intel.com
Wed Apr 30 18:33:19 PDT 2008


Initial implementation of CQ:Notify() to support asynchronous notification
of CQ events.

Signed-off-by: Sean Hefty <sean.hefty at intel.com>
---
I'm not sure if the WdfObject*Lock() routines for an IO queue work at dispatch
by default, but that looks easy enough to correct if they don't.

Index: core/winverbs/kernel/wv_cq.c
===================================================================
--- core/winverbs/kernel/wv_cq.c	(revision 1090)
+++ core/winverbs/kernel/wv_cq.c	(working copy)
@@ -27,6 +27,7 @@
  * SOFTWARE.
  */
 
+#include "wv_driver.h"
 #include "wv_cq.h"
 #include "wv_ioctl.h"
 
@@ -68,13 +69,32 @@
 
 static void WvCqEventHandler(ib_event_rec_t *pEvent)
 {
-	pEvent;
+	WV_COMPLETION_QUEUE *cq = pEvent->context;
+	WDFREQUEST			request;
+	NTSTATUS			status;
+
+	WdfObjectAcquireLock(cq->Queue);
+	status = WdfIoQueueRetrieveNextRequest(cq->Queue, &request);
+	WdfObjectReleaseLock(cq->Queue);
+
+	if (NT_SUCCESS(status)) {
+		WdfRequestComplete(request, STATUS_UNEXPECTED_IO_ERROR);
+	}
 }
 
 static void WvCqHandler(void *Context)
 {
-	 WV_COMPLETION_QUEUE *pCq = Context;
-	 pCq;
+	WV_COMPLETION_QUEUE *cq = Context;
+	WDFREQUEST			request;
+	NTSTATUS			status;
+
+	WdfObjectAcquireLock(cq->Queue);
+	status = WdfIoQueueRetrieveNextRequest(cq->Queue, &request);
+	WdfObjectReleaseLock(cq->Queue);
+
+	if (NT_SUCCESS(status)) {
+		WdfRequestComplete(request, STATUS_SUCCESS);
+	}
 }
 
 static NTSTATUS WvCqAlloc(WV_DEVICE *pDevice, UINT32 *pSize,
@@ -82,8 +102,10 @@
 {
 	ib_api_status_t		ib_status;
 	WV_COMPLETION_QUEUE	*cq;
+	WDF_IO_QUEUE_CONFIG	config;
+	NTSTATUS			status;
 
-	cq = ExAllocatePoolWithTag(PagedPool, sizeof(WV_COMPLETION_QUEUE), 'qcvw');
+	cq = ExAllocatePoolWithTag(NonPagedPool, sizeof(WV_COMPLETION_QUEUE), 'qcvw');
 	if (cq == NULL) {
 		return STATUS_NO_MEMORY;
 	}
@@ -91,10 +113,18 @@
 	cq->Ref = 1;
 	KeInitializeEvent(&cq->Event, NotificationEvent, FALSE);
 
+	WDF_IO_QUEUE_CONFIG_INIT(&config, WdfIoQueueDispatchManual);
+	status = WdfIoQueueCreate(ControlDevice, &config,
+							  WDF_NO_OBJECT_ATTRIBUTES, &cq->Queue);
+	if (!NT_SUCCESS(status)) {
+		goto err;
+	}
+
 	ib_status = pDevice->pVerbs->create_cq(pDevice->hVerbsDevice, cq,
 										   WvCqEventHandler, WvCqHandler,
 										   pSize, &cq->hVerbsCq, pVerbsData);
 	if (ib_status != IB_SUCCESS) {
+		status = STATUS_UNSUCCESSFUL;
 		goto err;
 	}
 
@@ -104,7 +134,7 @@
 
 err:
 	ExFreePool(cq);
-	return STATUS_UNSUCCESSFUL;
+	return status;
 }
 
 void WvCqCreate(WV_PROVIDER *pProvider, WDFREQUEST Request)
@@ -249,3 +279,38 @@
 complete:
 	WdfRequestCompleteWithInformation(Request, status, len);
 }
+
+void WvCqNotify(WV_PROVIDER *pProvider, WDFREQUEST Request)
+{
+	WV_IO_ID				*id;
+	WV_COMPLETION_QUEUE		*cq;
+	NTSTATUS				status;
+	ib_api_status_t			ib_status;
+
+	status = WdfRequestRetrieveInputBuffer(Request, sizeof(WV_IO_ID), &id, NULL);
+	if (!NT_SUCCESS(status)) {
+		goto out;
+	}
+
+	cq = WvCqAcquire(pProvider, id->Id);
+	if (cq == NULL) {
+		status = STATUS_NOT_FOUND;
+		goto out;
+	}
+
+	WdfObjectAcquireLock(cq->Queue);
+	ib_status = cq->pVerbs->enable_cq_notify(cq->hVerbsCq,
+											 id->Data ==
WV_IO_CQ_NOTIFY_SOLICITED);
+	if (ib_status == IB_SUCCESS) {
+		status = WdfRequestForwardToIoQueue(Request, cq->Queue);
+	} else {
+		status = STATUS_UNSUCCESSFUL;
+	}
+	WdfObjectReleaseLock(cq->Queue);
+	WvCqRelease(cq);
+
+out:
+	if (!NT_SUCCESS(status)) {
+		WdfRequestComplete(Request, status);
+	}
+}
Index: core/winverbs/kernel/wv_cq.h
===================================================================
--- core/winverbs/kernel/wv_cq.h	(revision 1075)
+++ core/winverbs/kernel/wv_cq.h	(working copy)
@@ -49,6 +49,7 @@
 
 	KEVENT				Event;
 	LONG				Ref;
+	WDFQUEUE			Queue;
 
 }	WV_COMPLETION_QUEUE;
 
@@ -63,5 +64,6 @@
 void WvCqPut(WV_COMPLETION_QUEUE *pCq);
 
 void WvCqResize(WV_PROVIDER *pProvider, WDFREQUEST Request);
+void WvCqNotify(WV_PROVIDER *pProvider, WDFREQUEST Request);
 
 #endif //_WV_CQ_H_
Index: core/winverbs/kernel/wv_driver.c
===================================================================
--- core/winverbs/kernel/wv_driver.c	(revision 1075)
+++ core/winverbs/kernel/wv_driver.c	(working copy)
@@ -49,7 +49,7 @@
 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(WV_RDMA_DEVICE, WvRdmaDeviceGetContext)
 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(WV_PROVIDER, WvProviderGetContext)
 
-static WDFDEVICE		ControlDevice;
+WDFDEVICE				ControlDevice;
 static LIST_ENTRY		DevList;
 static LIST_ENTRY		ProvList;
 static KGUARDED_MUTEX	Lock;
@@ -233,8 +233,7 @@
 		WvCqResize(prov, Request);
 		break;
 	case WV_IOCTL_CQ_NOTIFY:
-		//WvCqNotify(prov, Request);
-		WdfRequestComplete(Request, STATUS_NOT_IMPLEMENTED);
+		WvCqNotify(prov, Request);
 		break;
 	case WV_IOCTL_CQ_BATCH_NOTIFY:
 		//WvCqBatchNotify(prov, Request);
Index: core/winverbs/kernel/wv_driver.h
===================================================================
--- core/winverbs/kernel/wv_driver.h	(revision 1071)
+++ core/winverbs/kernel/wv_driver.h	(working copy)
@@ -34,11 +34,14 @@
 
 #include <ntddk.h>
 #include <wdm.h>
+#include <wdf.h>
 
 #include <iba\ib_types.h>
 #include <iba\ib_ci.h>
 #include <rdma\verbs.h>
 
+extern WDFDEVICE			ControlDevice;
+
 typedef struct _WV_RDMA_DEVICE
 {
 	LIST_ENTRY				Entry;
Index: core/winverbs/wv_ioctl.h
===================================================================
--- core/winverbs/wv_ioctl.h	(revision 1089)
+++ core/winverbs/wv_ioctl.h	(working copy)
@@ -493,6 +493,9 @@
 
 }	WV_IO_QP_CREATE;
 
+#define WV_IO_CQ_NOTIFY_SOLICITED	1
+#define WV_IO_CQ_NOTIFY_NEXT		2
+
 #define WV_IO_QP_STATE_RESET	0
 #define WV_IO_QP_STATE_INIT		1
 #define WV_IO_QP_STATE_RTR		2





More information about the ofw mailing list