Inverted Call reference work

Hi,

Thanks to the many participations and contributions that I maximally appreciate I know that I should use ‘inverted call’ - a method that uses pended io requests such that I not only can get an interrupt signalled, to the user application through the fact that the io request was completed, but the now completed io request can also contain additional data which at this point seams meaningful from a conceptual point of view. I like!

Maybe I am spoiled because the only framework I have been using up til now is ‘kmdf’.
It uses the now for me more&less familiar WDFREQUEST / WDFMEMORY / … types. The references I am finding are mostly not written taking ‘wdf:kmdf/umdf’ in mind but rather ‘wdm’ or ‘legacy driver’ topologies. I do am aware that under the hood you could do wdm in a kmdf context, but this is not my expertise.

I am trying to keep what I do clean such that it is

  • fundamentally sound conceptually ( thank you *3 already osronline )
  • readable
  • expandable (2 years after touching the code I would like to be able to continue working on it with ~.5 day of getting in to the groove of driver development)

I have found reference workpieceA :
http://www.osronline.com/article.cfm?name=inverted_call.zip&id=94

I have found reference workpieceB(within winddk source samples) :
C:\WinDDK\7600.16385.1\src\general\event\wdm\event.c
–> taking only in consideration the ‘2) Pending Irp’ context

Both give me a better grasp of what I should do but I am not getting too much traction in adapting this in my own code. For now I am figuring that ‘LIST_ENTRY’ at some abstract level might be interchangeable with WDFQUEUE, but I might be entirely wrong.

Question:
Is there a reference solution/code base for inverted call within the wdf framework?

Question:
With wdf in mind,
do you guys,
that implement inverted call on your own driver based on ‘article.cfm?name=inverted_call.zip&id=94’,
–> make adapter pieces to work with wdf, making minimal changes under the hood?
–> rewrite the inverted call plumbing with wdf objects ?

Many thanks in advance,
Kind Regards,
Donald

You just write it natively in KMDF. It’s FAR simpler in KMDF than it is in WDM.

You receive the Request you’re going to keep in progress in the appropriate EvtIo Event Processing Callback. You store the handle to that Request someplace. A good place to store the Request is a WDFIOQUEUE. In determining where to store the Request, consider how you want to handle if it is cancelled (that is, if the thread that issued the Request exits or is aborted while the Request is queued in your driver). f you simply want the Request to disappear if the thread that issued it goes away, simply store the pending Request in a Queue do nothing further. If you want to do something specific when/if the Request is cancelled, register a Cancelled On Queue Event Processing Callback for the Queue on which you store the Request.

In any case, to put the Request on a Queue you simply call WdfRequestForwardToIoQueue in your EvtIo Event Processing Callback.

When the condition you want to notify the application about occurs, simply remove the Request from its Queue (using WdfIoQueueRemoveNextRequest or similar) and call WdfRequestComplete on it. If you want to complete ALL the pending Requests, just keep calling WdfIoQueueRemoveNextRequest until the QUeue is empty.

Done.

Does that help? Ask more questions.

I suggest you take a seminar… we practice all this in class.

Peter
OSR

Peter,

Given the number of times a year that inverted calls come up by new
driver writers (in the Microsoft forums it is more than once a month
average), perhaps it is time to update the article and sample. Yes thus
easy for any experienced dev, but a good discussion for newbie’s would
help.

Don Burn
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

xxxxx@osr.com” wrote in message news:xxxxx@ntdev:

> You just write it natively in KMDF. It’s FAR simpler in KMDF than it is in WDM.
>
> You receive the Request you’re going to keep in progress in the appropriate EvtIo Event Processing Callback. You store the handle to that Request someplace. A good place to store the Request is a WDFIOQUEUE. In determining where to store the Request, consider how you want to handle if it is cancelled (that is, if the thread that issued the Request exits or is aborted while the Request is queued in your driver). f you simply want the Request to disappear if the thread that issued it goes away, simply store the pending Request in a Queue do nothing further. If you want to do something specific when/if the Request is cancelled, register a Cancelled On Queue Event Processing Callback for the Queue on which you store the Request.
>
> In any case, to put the Request on a Queue you simply call WdfRequestForwardToIoQueue in your EvtIo Event Processing Callback.
>
> When the condition you want to notify the application about occurs, simply remove the Request from its Queue (using WdfIoQueueRemoveNextRequest or similar) and call WdfRequestComplete on it. If you want to complete ALL the pending Requests, just keep calling WdfIoQueueRemoveNextRequest until the QUeue is empty.
>
> Done.
>
> Does that help? Ask more questions.
>
> I suggest you take a seminar… we practice all this in class.
>
> Peter
> OSR

Sigh. I was just thinking that myself.

The original article is old and overly complicated in any case.

OK, we’ll get something written for the next issue of The NT Insider… which should (finally!) come out in the next six weeks or so.

Peter
OSR

Peter Viscarola,

Thank you for your input (I’m not just writing this as an automated response!) I really appreciate your effort.

I will figure out a way to apply your description of implementing for now.
The way I see it is that kmdf types are the the toolset to apply to a problem, ‘inverted call’ is a fundamental design pattern - for driver development. Within the scope of what I am trying to do, the possibility to have the iorequest return data, gives me a razor sharp edge which I require with the event firing context - ‘something happened, but a little more info would help a lot’ .

I probably should take a seminar some time. But I might be able to say this as well for doing firmware vhdl/verilog + simulations + driver development + c++ +.net, all related to the same project. I do agree that driver development kicks up a notch with respect to features not easily mind transferred. What I can say is that kmdf helps a lot. Probably every single one of these aspects has much more than meets the eye.

Don Burn,

I will be looking forward to the article!

You guys are doing an amazing job.

Kind Regards,
Donald

Hi,

Peter, I have followed your brief guideline and has proven to be very worthwhile.
The issue I had is putting the puzzle together,
the driver development time was minimal,
compared to the user app to test the driver with.

I ended up creating some software IOCTL’s that interact with the ‘inverted_call’ queue.
IOCTL_INVERTED_CALL_QUEUE_STATUS
IOCTL_INVERTED_CALL_ENQUEUE_REQUEST
IOCTL_INVERTED_CALL_COMPLETE_QUEUE_REQUEST
IOCTL_INVERTED_CALL_COMPLETE_ALL_REQUESTS

Adding the appropriate call in the MSI deffered procedure call to complete the
next request on the ‘inverted call’ queue is easy as turning the key on a car,
once the you have a basic inverted call user test framework.

The other issue is to get the overlapped way of thinking in the head,
as well as multi threaded user app + cross thread syncrhonisation.

For now I found the following very useful, more specifically the CopyFile example attached
(although it needed tuning to visual studio 2012)
(and tuning to do DeviceIOControl instead of WritFile/ReadFile)
http://msdn.microsoft.com/en-us/magazine/cc163327.aspx#S7

I might be wrong, but to put together a starter guide to inverted call,
I think it requires an equal effort on the user app to get the concepts
to contrast in front of the unknowing.

Kind Regards,
Donald

Thanks for the suggestion… Let’s see how the article turns out.

Peter
OSR

I have found out a number of things which may relate to this. First,
waiting on handles or event objects sucks as an asynchronous I/O
mechanism, except in one case: where you are wanting to treat “ordinary”
read/write operations as synchronous, but need the asynchrony to handle
inverted call. In that case, GetOverlappedResult with a blocking wait is
appropriate; I call this “pseudo-synchronous I/O”.

The problem with doing a WaitFor on more than one Event object is that the
bookkeeping required to manage what to do afterwards is annoyingly
complex. And if you don’t execute the WaitFor… often enough, throughput
can suffer.

Callback I/O is fairly useless in that it does not scale well; since the
callback has to be processed in the thread that initiated the I/O call, it
also is not as efficient in utilizing multicore resources as it should be.

My own preference for asynch I/O is the I/O completion port, which is a
fully-asynchronous, nicely-scalable solution that distributes the
processing load across as many cores as desired.

As far as synchronization is concerned, I never use it for I/O like this.
When I initiate the I/O, the initiating thread abandons all interest in
the buffers and every other resource that might be relevant and require
synchronization. Instead, it hands responsibility for all of this to the
thread that unblocks from the completion port. Anything I care about I
have put in the OVERLAPPED structure by doing

typedef struct {
OVERLAPPED ovl;
…whatever I want here…
} MYOVERLAPPED, *PMYOVERLAPPED;

which means the OVERLAPPED structure carries all the information I need
with it. When the receiving thread dequeues the OVERLAPPED request, it
can recast it to a PMYOVERLAPPED pointer and have access to whatever I’ve
stored out there, and since no other thread can be using that information,
synchronization is not required because there is no concurrency.

I strongly believe that the best synchronization is no synchronization, a
goal which is fairly easy to achieve in user space and absolutely
impossible to achieve in kernel space. Which is why we have spin locks.
joe

Thanks for the suggestion… Let’s see how the article turns out.

Peter
OSR


NTDEV is sponsored by OSR

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer