[ofw] RE: [PATCHv2] WinVerbs: Make QP modification asynchronous

Sean Hefty sean.hefty at intel.com
Wed Feb 11 16:07:06 PST 2009


>Here's an updated patch that does the following:
>- Only allocate the work item on Vista+, otherwise processes synchronously.
>This has to do with IoQueueWorkItemEx being Vista+ only.  Uses #if WINVER
>checks, which uglifies the code, but it now will build for 32-bit XP.
>- Moves the QP ID check into the IOCTL handler rather than the work item
>callback, so that invalid handle checks are done in the context of the calling
>thread.  This is more an exercise to demonstrate parameter validation separated
>from the work item processing, but does help clients in not receiving an
>asynchronous 'invalid handle' error.
>- Removes the need to lookup the provider in the work item handler.

Before actually applying something like this, I'd like to have something
quantitative that shows the benefits.  For the OFED compatibility libraries,
this patch may hurt performance.

>+void WvQpModify(WV_PROVIDER *pProvider, WDFREQUEST Request)
>+{
>+       WV_IO_QP_ATTRIBUTES             *pattr;
>+       NTSTATUS                                status;
>+#if WINVER >= 0x0600
>+       WDFFILEOBJECT                   file;
>+       WDFDEVICE                               device;
>+       PIO_WORKITEM                    workitem;
>+#endif
>+
>+       status = WdfRequestRetrieveInputBuffer(Request,
>sizeof(WV_IO_QP_ATTRIBUTES),
>+
>&pattr, NULL);
>+       if (!NT_SUCCESS(status)) {
>+               WdfRequestCompleteWithInformation(Request, status, 0);
>+               return;
>+       }
>+
>+       pattr->Id.Id = (ULONG_PTR)WvQpAcquire(pProvider, pattr->Id.Id);
>+       if (pattr->Id.Id == 0) {
>+               WdfRequestCompleteWithInformation(Request, STATUS_NOT_FOUND,
>0);
>+               return;
>+       }
>+
>+#if WINVER >= 0x0600
>+       file = WdfRequestGetFileObject(Request);
>+       device = WdfFileObjectGetDevice(file);
>+
>+       workitem = IoAllocateWorkItem( WdfDeviceWdmGetDeviceObject(device) );
>+       if (workitem == NULL) {
>+#endif
>+               // No work item, just execute the modify synchronously.
>+               WvDoQpModify(NULL, Request, NULL);
>+#if WINVER >= 0x0600
>+       } else {
>+               IoQueueWorkItemEx(workitem, WvDoQpModify, DelayedWorkQueue,
>Request);
>+       }
>+#endif
> }

I would prefer two different functions over placing #if def's within a single
call.

- Sean




More information about the ofw mailing list