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 <[EMAIL PROTECTED]>
---
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;


_______________________________________________
ofw mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/ofw

Reply via email to