A Basic doubt about I/O completion routine and APC

its said that in case of synchronous I/o request i/o manager doesnt have to bouther about the i/0 issuing thread context, since the i/o completion routine will be returning in the original user thread context which issued the request.
How this can be true since according to my understanding in synchronous i/o the request is waiting for the i/o to complete,and when that thread is waiting for i/o to complete its a blocking call and it can be scheduled out and other thread might be running??

I’m not sure what you don’t understand.

Clearly, you know that Windows queues an APC to the thread, to cause execution to return to the context of the requesting process and thread. The WAIT that’s block the thread takes place in the I/O Manager. Queuing an APC to a waiting thread causes the wait to be satisfied, IF the wait is “altertable.” So, the APC gets queued, the thread wakes, gets scheduled, runs the APC, and then continues back to the user application.

If that doesn’t answer your question, please feel free to ask something very clear and specific.

Peter
OSR
@OSRDrivers

I understand the things in case of asynchronous I/O where in i know that originator user mode requester thread might not be running at the time I/O completes so the I/O manager queues an APC which runs when originator threads context,till that fine.

Now My doubt is wrt Synchronous I/O,here it is said that originator requestor thread will be running when I/O completes?This is what i am not able to understand.

windows driver,

There are two cases of synchronous IO:

  1. The IO completes synchronously in the context of the originating thread.
  2. The underlying driver returns STATUS_PENDING. In this case the originating thread waits on FILE_OBJECT’s event. Setting the event and waiting for it is part of IO completion process implemented by IO manager.

xxxxx@hotmail.com wrote:

Now My doubt is wrt Synchronous I/O,here it is said that originator requestor thread will be running when I/O completes?This is what i am not able to understand.

The “originator requestor thread” will, of course, not be running as the
I/O completes. As Marion said, that is the very definition of
synchronous I/O. It is waiting. When the I/O completes, the I/O
manager will start up the originator requestor thread, but it will have
registered an APC to handle the completion. When the scheduler restarts
the thread, it checks to see whether there is an APC queued. If there
is, it saved the threads current state and “hijacks” it to run the APC.
When the APC completes, the thread’s original state is restored, and the
user app continues.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

thank you for the answers Mikae, Roberts and Peter.

So now how will the I/O manager now wether the synchronous I/O is already completed in the originator threads context or it hs to queue an APC ?

STATUS_PENDING return value is for this.

wrote in message news:xxxxx@ntdev…
> thank you for the answers Mikae, Roberts and Peter.
>
> So now how will the I/O manager now wether the synchronous I/O is already completed in the originator threads context or it hs to queue an APC ?
>

Well, you have just now asked the question that comes to the heart of the matter. And the answer is not pretty. Nor is it easy to explain.

Mr. Shatskih wrote:

And while this is correct, Mr. Shatskih knows very well that this is just the start of what many people find to be a baffling process.

The whole I/O Completion process was described in an article first published almost 20 years ago in The NT Insider: https://www.osronline.com/article.cfm?article=83 – The article may be ancient, but it’s still reasonably accurate and will give you an overview of the entire process.

I think we need to update this article and republish it in The NT Insider. Not even people understand the details… and they should.

Peter
OSR
@OSRDrivers

Moreover, if the request is issued for a synchronous handle (the thread is waiting for it), the IO manager can go without even using an APC.

(speaking to the community and the archives… I realize Mr. Grig already knows what I’m about to write)

CAN or WILL? It CAN, but only if the request is completed synchronously by the driver… and how many requests are completed synchronously?

There are two issues at play here, right? The app can ask for synch or async service, and the driver can actually complete the request synchronously or asynchronously. The “screw case” as we call it, is when the app asks for synchronous service and the driver decides to pend the request and complete it later in an arbitrary thread/process context (that is, complete is “asynchronously”). The I/O Manager is the guy who’s responsible for detecting and fixing things up in this screw case… and that’s where we get the whole IoMarkIrpPending(), STATUS_PENDING, and Irp->PendingReturned nonsense.

Peter
OSR
@OSRDrivers

Peter,

The APC is necessary to return to the thread context while the thread is chugging along somewhere, to copy the data and IO_STATUS back. If the request is issued while I/O manager knows the thread has to wait for its completion (synchronous handle), this copy can be done immediately after KeWaitForSingleObject, without APC.

Disclaimer: I don’t know if that’s what is actually done, but there is IRP_SYNCHRONOUS_API flag.

> Disclaimer: I don’t know if that’s what is actually done, but there is IRP_SYNCHRONOUS_API flag.

It is actually done :slight_smile: there was some flag like “defer IO completion” in the IRP.

One of the goals of this arcane STATUS_PENDING/IoMarkIrpPending mechanism is to allow the sync thread itself, without the APC, to do the IRP completion if possible, thus removing the APC overhead.

The sync thread is allowed to do so in some specific cases, the condition has the AND term of “…and the IRP was IoCompleteRequest’ed inline by the driver stack, so that != STATUS_PENDING was returned from topmost IoCallDriver”.

If STATUS_PENDING is returned, then it is not known when will (or was already) IoCompleteRequest be called. And, since there is no event to be signaled in the 1st stage of IoCompleteRequest - that function itself and not the IopCompleteRequest APC - then even the sync thread cannot wait in such a case.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

The synchronous completion optimizations mostly benefit cached reads and writes to the file system driver. Of that’s probably the majority of IO operations on most systems. Cached FS requests will either go through with a synchronous copy from the cache to the users buffers, or go through some blocking synchronization (grabbing an ERESOURCE or Mutex, taking a page fault in the cache manager and then complete synchronously.

It’s much less common for HW drivers to have critical performance paths that rely on the synchronous completion optimizations.

As my boss told me shortly after I joined the Windows NT drivers team - all drivers are created equal, but some are more equal than others. There are a lot of pieces of the IO manager that are designed to optimize the FS/Cache layer.

-p

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@osr.com
Sent: Friday, July 10, 2015 5:39 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] A Basic doubt about I/O completion routine and APC



(speaking to the community and the archives… I realize Mr. Grig already knows what I’m about to write)

CAN or WILL? It CAN, but only if the request is completed synchronously by the driver… and how many requests are completed synchronously?

There are two issues at play here, right? The app can ask for synch or async service, and the driver can actually complete the request synchronously or asynchronously. The “screw case” as we call it, is when the app asks for synchronous service and the driver decides to pend the request and complete it later in an arbitrary thread/process context (that is, complete is “asynchronously”). The I/O Manager is the guy who’s responsible for detecting and fixing things up in this screw case… and that’s where we get the whole IoMarkIrpPending(), STATUS_PENDING, and Irp->PendingReturned nonsense.

Peter
OSR
@OSRDrivers


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

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

Max:

I was talking about the case when IoCallDriver actually returns STATUS_PENDING, and the calling thread has to wait for the completion. But if the IO manager knows that the calling thread waits for completion immediately after IoCallDriver (in kernel mode), the rest of the completion (copying of the buffer and of IO_STATUS) can be done immediately after KeWaitForSingleObject, without having to queue a APC.

One more question here, everybody says that USER MODE APC will run only when the corressponding thread enters alertaible wait?

why this restriction why it cant run immediately after the thread runs as in case of kernel mode APC?

I am not sure if this is a valid question to ask …

windows driver,

Short answer: because of synchronization issues.
Long answer is here:

http://www.osronline.com/showthread.cfm?link=201006

or in the article:

http://www.flounder.com/asynchexplorer.htm

(CTRL+F for Dave Cutler or read the whole thing).

It’s a fine question to ask. The answer I’ve always heard was to give the application control over when it would have to worry about reentrancy. Your app would only do an alertable wait when it was safe for the thread to be interrupted, like when you weren’t holding any other resources that the APC callback might be trying to acquire.

Personally every time I’ve ever really thought about how to use a user APC I’ve found the idea unmanageable.

-p

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.com
Sent: Friday, July 10, 2015 1:44 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] A Basic doubt about I/O completion routine and APC

One more question here, everybody says that USER MODE APC will run only when the corressponding thread enters alertaible wait?

why this restriction why it cant run immediately after the thread runs as in case of kernel mode APC?

I am not sure if this is a valid question to ask …


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

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

> One more question here, everybody says that USER MODE APC will run only when the

corressponding thread enters alertaible wait?

Yes.

why this restriction why it cant run immediately after the thread runs as in case of kernel mode APC?

I think to allow you to control when the APC runs.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

>Personally every time I’ve ever really thought about how to use a user APC I’ve found the idea

unmanageable.

Inverted call user mode driving code which does ReadFileEx and then the user APC calls the processing path for the data BLOB from kmode.

After this, the user APC calls another ReadFileEx.

So, its main thread is always in SleepEx(INFINITE, TRUE) or such. All work is done by user APCs (yes, shutdown can be done this way too).

I think there were some very old audio driver WDK samples of this kind.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

>wanted to do anything about it. IMHO UM APCs have very limited applications; unlike KM APCs

I think IopCompleteRequest is the only useful kernel APC :slight_smile:

I never ever heard about any driver except inbox MS ones (and probably the kernel itself) using APCs.

They are also undocumented.

So, major doubts that kernel APCs are useful.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com