[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