Why does blocking the Paging I/O request lead to deadlock?

Hi!
I have searched the archive and read the documentation present, but could
not find a concrete answer to this question:
“Why does blocking the Paging I/O request lead to deadlock?”.

At many places in the forum, i have seen people mentioning that it can lead
to a deadlock but with no explanation.

As a background, i would like to first tell what i know (came to know) after
reading Rajeev Nagar’s book, regarding Paging I/O.

First, the book in general says that blocking asynchronous IRPs is not a
good idea because that will hamper system performance.
Second, There is a difference between Paging I/O done on Paging file and
that done on normal files.
Third, blocking a paging i/o request can lead to a deadlock. From what the
author has written, i can only infer that if we try to make memory access or
try to access (read/write) cached file, it may lead to overburdening the
Memory manager to flush out dirty pages to make room for the requested
pages, if they are not present in memory.
Plus, if we block the modified page writer thread or the mapped page writer
thread and try to do what is mentioned above, it may lead to a deadlock.

I wanted to know the following:

  1. Is my inference correct?
  2. A detailed description of why it happens and how it can be avoided.

I would really appreciate if someone can provide some help on this topic.

Thanks!
-K. Dev.

A blocking operation needing code to run,
causing a page fault to load the code needed to be run,
reentering and hitting the locked VMM?
Wait, yes/no?..
Perhaps if all other I/O threads are also in the same state of Being blocked…
Wait, yes/no?..
Blocking does not deadlock?, causing page fault on paging i/o causes deadlock.

My non answer
“(I don’t consider myself an expert by a long shot but thought I’d take a stab to his question)”
brings another question to mind…

Is the I/O thread count,
(if they are even specific to I/O, which I believe they are not)
static, or can and do new system threads be created at will subject to available memory resources as needed by systemload.
Usually higher load means less resources, but if many memory-light i/o’s are taken at once, My experimental observation is that there are a set number of system threads to handle these I/O’s even if more threads could be created without incurring a paged i/o.

Ramblin…

|-----Original Message-----
|From: xxxxx@lists.osr.com
|[mailto:xxxxx@lists.osr.com] On Behalf Of Kernel
|Developer
|Sent: Monday, July 30, 2007 2:23 PM
|To: Windows File Systems Devs Interest List
|Subject: [ntfsd] Why does blocking the Paging I/O request lead
|to deadlock?
|
|Hi!
|I have searched the archive and read the documentation
|present, but could not find a concrete answer to this question:
|“Why does blocking the Paging I/O request lead to deadlock?”.
|
|At many places in the forum, i have seen people mentioning
|that it can lead to a deadlock but with no explanation.
|
|As a background, i would like to first tell what i know (came
|to know) after reading Rajeev Nagar’s book, regarding Paging I/O.
|
|First, the book in general says that blocking asynchronous
|IRPs is not a good idea because that will hamper system performance.
|Second, There is a difference between Paging I/O done on
|Paging file and that done on normal files.
|Third, blocking a paging i/o request can lead to a deadlock.
|From what the author has written, i can only infer that if we
|try to make memory access or try to access (read/write) cached
|file, it may lead to overburdening the Memory manager to flush
|out dirty pages to make room for the requested pages, if they
|are not present in memory.
|Plus, if we block the modified page writer thread or the
|mapped page writer thread and try to do what is mentioned
|above, it may lead to a deadlock.
|
|I wanted to know the following:
|1. Is my inference correct?
|2. A detailed description of why it happens and how it can be avoided.
|
|I would really appreciate if someone can provide some help on
|this topic.
|
|Thanks!
|-K. Dev.
|
|
|—
|NTDEV is sponsored by OSR
|
|For our schedule debugging and file system seminars (including
|our new fs mini-filter seminar) visit:
|http://www.osr.com/seminars
|
|You are currently subscribed to ntfsd as: xxxxx@lrs.com To
|unsubscribe send a blank email to xxxxx@lists.osr.com
|

> From what the author has written, i can only infer that if we

|try to make memory access or try to access (read/write) cached
file, it may lead to overburdening the Memory manager to flush
out dirty pages to make room for the requested pages, if they
are not present in memory.
Plus, if we block the modified page writer thread or the
mapped page writer thread and try to do what is mentioned
above, it may lead to a deadlock.

I wanted to know the following:

  1. Is my inference correct?
  2. A detailed description of why it happens and how it can be avoided.

I can tell you my vision of the situation…

Modified page writer and mapped page writer are just 2 out of 6 Memory Manager’s threads - besides them, there are also stack swapper, working set manager, dereference segment thread and zero page thread. Now imagine what happens if you block a stack swapper thread - a thread that it waits for may have its stack paged, so that it has no chance to run until stack swapper that waits for this is eligible for execution. As a result, you deadlock - the whole situation is just a stalemate that has no chance to get resolved…

This is the way I see it - I may be wrong here…

Anton Bassov

Following is my analysis of the topic “Blocking in the Paging I/O path CAN lead to deadlock”.

The Virtual Memory Manager uses secondary storage devices as a backing store for in-memory data and pages data in and out. It automatically flushes dirty or modified pages to secondary storage to reclaim page frames for use by other threads in the system. These pages can either be backed on the page file or on the mapped file (in case of memory mapped files). The VMM creates at least 2 threads (it can create more threads also, but since we are analyzing why a deadlock can happen, let’s keep it to the minimum): Modified Page Writer and Mapped Page Writer.
Both of them do essentially the same work, except that the Modified Page Writer flushes modified pages to Page File and Mapped Page Writer flushes modified pages to the mapped file.
Now, let us analyze what happens when we get a callback for Paging I/O in our minifilter. Since it is a Paging I/O, it can either be on a Page File or on a memory mapped file. First we will take the case in which the I/O is on the Page File:
This I/O is happening to either bring in a Page from Page File to Memory (in case of Paging Read) or to write modified pages to Page file (in case of Paging Write). Let’s keep in mind that this request was issued by the Modified Page Writer thread or the thread to read in the pages. If it’s a read on the page file, we can clearly see that the file system is NOT ALLOWED to generate any page fault. Because if it does, who will serve this request? The VMM’s reading thread is already waiting for the previous read to complete. However, if it is a Paging Write request, then we know that the modified page writer has issued this request to write modified pages to page file. Note that it is always an asynchronous request. Suppose we do one of the following in this path:

  1. Access any paged code or data.
  2. Issue any cached I/O.
    They may lead to memory manger trying to flush out more pages to disk, if the page (to which 1 or 2 refer) is not present in memory. And to top it all, if we wait in this path after doing 1 or 2, we may end up in a situation in which the Modified Page Writer is trying to write out pages to the Page File to make space to bring in the pages required for doing 1 or 2. And since we have already blocked that thread before by waiting in that path, it’s an indirect recursion that will never end. The only way out would be when the other thread, Mapped Page Writer flushes enough pages to free up the memory so that the Paged data requested by us can be brought to memory.

Now, we take the case when the Paging I/O is done on a mapped file:
Since, it is on a memory mapped file, the paging read will be done to bring in the pages and the write will be done by the Mapped Page Writer to write out dirty pages to the mapped file. Suppose, we receive a paging read request in our minifilter ( which I think is a synchronous request, since that thread waits for the page to come into memory), and we do anything that causes a page fault, who will handle it? No one. The thread responsible for reading is blocked. Now, suppose we receive a Paging I/O write to a mapped file. And we make any call that makes use of Pageable memory (Paged code, data,etc), again the same thing will happen that happened in case of Modified page writer. Recursion. This time the rescue depends on the Modified Page Writer.

That is why the safest thing is to call functions that can be called at IRQL<=DISPATCH_LEVEL, because we are certain that they will not cause any page faults.

Hi K. Dev.!

I am sorry for providing some misleading and incorrect information in my last post. Even I am learning… J

I am making some significant changes in my post. While I was analyzing properly, I found out that what I wrote about the Paging I/O Read was WRONG. It seems that the Paging Read actually comes in the same thread context, which generated the page fault. This is a synchronous I/O. And it makes sense too. The thread cannot continue till the page is present in memory.

Moreover, the FS filter CANNOT generate a page fault when this Paging I/O is directed to the PAGE FILE, however, it CAN generate page fault when it is on a mapped file.

I am not very sure why, but this is what I found after trying to access paged data in both the cases.

Ayush Gupta

K7 Computing Pvt. Ltd.

www.k7computing.com

> Moreover, the FS filter CANNOT generate a page fault when this Paging I/O is

directed to the PAGE FILE, however, it CAN generate page fault when it is on a
mapped file.

You cannot generate *ANY* page faults when processing paging IO to the paging file. When you process paging IO to the mapped file, you cannot generate page faults on code, although you can generate them on data. Therefore, when you process paging IO to the paging file, you cannot safely call any function that is not callable at DPC level. When you process paging IO to the mapped file, you cannot safely call only those functions that are callable *strictly* at PASSIVE_LEVEL (Zw, Ob,etc) - those functions that are callable at IRQL<=APC_LEVEL are OK.

I am not very sure why, but this is what I found after trying to access paged data
in both the cases.

Is it so complex??? If a code that retrieves a swapped page is paged itself, you will get into an infinite chain of nested page faults. Therefore, you cannot take page faults on code when you process paging IO, no matter if the target file is mapped file or paging file itself.

When the target file is a paging one, a page fault on data produces exactly the same scenario that
a paging fault on code does - once any attempt to retrieve a page from the paged file results in a page fault, you get into an infinite chain of nested page faults. However, when the target file is a mapped one, a page fault on data is OK - once paged data on IO path has to be retrieved from the paging file and not from the target one, there is no infinite chain of page faults…

Anton Bassov

Thanks Anton and Ayush!

Some doubts…

Anton mentioned:

>>When the target file is a paging one, a page fault on data produces
>>exactly the same scenario that
a paging fault on code does - once any attempt to retrieve a page from the
paged file results in a page fault, you get into an infinite chain of
nested page faults. However, when the target file is a mapped one, a page
fault on data is OK - once paged data on IO path has to be retrieved from
the paging file and not from the target one, there is no infinite chain of
page faults…<<<

  1. Where does the code gets swapped out? To the PAGE FILE I suppose. Then
    why can’t the code be also brought in similar to the DATA in case of MAPPED
    FILE?

Ayush mentioned:

>>Now, suppose we receive a Paging I/O write to a mapped file. And we make
>>any call that makes use of Pageable memory (Paged code, data,etc), again
>>the same thing will happen that happened in case of Modified page writer.
>>Recursion. This time the rescue depends on the Modified Page Writer.<<<

  1. Does this mean that if I take care that I don’t Wait in the Paging I/O
    path directed to PAGE FILE, it will work?
  2. In other words using a wait function like KeWaitForSingleObject after
    calling a function F that can be called at IRQL <= APC_LEVEL is OK?
  3. My logic being that even if this function F accesses a paged data, it can
    be fetched from the PAGE FILE. Is my logic correct?

> 1. Where does the code gets swapped out? To the PAGE FILE I suppose. Then

why can’t the code be also brought in similar to the DATA in case of MAPPED FILE?

Look - say, you are processing paging IO, and a function X that you have to execute is currently swapped to the disk. Therefore, you take page fault ( page fault A), which has to get processed before you can continue with your operation - otherwise, you just haven’t got a chance to execute function X that is vital for your task. In order to process page fault A you, again, have to execute the same function X which is still swapped to the disk, i.e. you generate one more page fault (page fault B). In order to process page fault B, you have to execute function X -> you generate page fault C- > in order to process page fault C, you have to execute function X -> you generate page fault D->and so on and so forth up to infinity.

If you replace “execute function X” with “access variable X”, the above paragraph also described what happens when you page fault on data while processing a paging IO to the page file - you have no chance to process page faults without accessing variable X, but any access to this variable generates a page fault, i.e., again, you get into an infinite chain of page faults.

However, if the target file is a mapped one, situation is somehow different when you page fault on data - variable X will be brough to memory from the paging file, and, at this point, you can continue with your task of processing paging IO to the target mapped file.

>>Now, suppose we receive a Paging I/O write to a mapped file. And we make
>>any call that makes use of Pageable memory (Paged code, data,etc), again
>>the same thing will happen that happened in case of Modified page writer.
>>Recursion. This time the rescue depends on the Modified Page Writer.<<<

As you must have already understood, the above excerpt is just wrong, and Ayush already made a correction to his earlier post. Therefore, you should not try to make any conclusions based upon the above excerpt…

Anton Bassov

>When you process paging IO to the mapped file, you cannot generate page

faults on code, although you can generate them on data.

Wrong, this is a way to a deadlock. The division is not by code and data but
by those who back page(s).
Actually, the rule is - you CAN generate any page fault on any code and data
that are backed by a pagefile when you are processing request(s) to the
page(s) backed by an ordinary file(s)( data stream(s) ).

Therefore, when you process paging IO to the paging file, you cannot safely
call any function that is not callable at DPC level.

Wrong again. The function is allowed to wait for completion or
synchronization purposes, this is not possible at DISPATCH_LEVEL.

Therefore, you cannot take page faults on code when you process paging IO,
no matter if the target file is mapped file or paging file itself.

Wrong, read my first statement.


Slava Imameyev, xxxxx@hotmail.com

wrote in message news:xxxxx@ntfsd…
>> Moreover, the FS filter CANNOT generate a page fault when this Paging I/O
>> is
>> directed to the PAGE FILE, however, it CAN generate page fault when it is
>> on a
>> mapped file.
>
> You cannot generate ANY page faults when processing paging IO to the
> paging file. When you process paging IO to the mapped file, you cannot
> generate page faults on code, although you can generate them on data.
> Therefore, when you process paging IO to the paging file, you cannot
> safely call any function that is not callable at DPC level. When you
> process paging IO to the mapped file, you cannot safely call only those
> functions that are callable strictly at PASSIVE_LEVEL (Zw, Ob,etc) -
> those functions that are callable at IRQL<=APC_LEVEL are OK.
>
>
>> I am not very sure why, but this is what I found after trying to access
>> paged data
>> in both the cases.
>
> Is it so complex??? If a code that retrieves a swapped page is paged
> itself, you will get into an infinite chain of nested page faults.
> Therefore, you cannot take page faults on code when you process paging IO,
> no matter if the target file is mapped file or paging file itself.
>
> When the target file is a paging one, a page fault on data produces
> exactly the same scenario that
> a paging fault on code does - once any attempt to retrieve a page from the
> paged file results in a page fault, you get into an infinite chain of
> nested page faults. However, when the target file is a mapped one, a page
> fault on data is OK - once paged data on IO path has to be retrieved from
> the paging file and not from the target one, there is no infinite chain of
> page faults…
>
>
> Anton Bassov
>

> 1. Where does the code gets swapped out? To the PAGE FILE I suppose. Then

why can’t the code be also brought in similar to the DATA in case of
MAPPED FILE?

Correct.
Anton’s statement was wrong.


Slava Imameyev, xxxxx@hotmail.com

“Kernel Developer” wrote in message
news:xxxxx@ntfsd…
> Thanks Anton and Ayush!
>
> Some doubts…
>
> Anton mentioned:
>
>>>>When the target file is a paging one, a page fault on data produces
>>>>exactly the same scenario that
> a paging fault on code does - once any attempt to retrieve a page from the
> paged file results in a page fault, you get into an infinite chain of
> nested page faults. However, when the target file is a mapped one, a page
> fault on data is OK - once paged data on IO path has to be retrieved from
> the paging file and not from the target one, there is no infinite chain of
> page faults…<<<
>
> 1. Where does the code gets swapped out? To the PAGE FILE I suppose. Then
> why can’t the code be also brought in similar to the DATA in case of
> MAPPED FILE?
>
>
> Ayush mentioned:
>
>>>>Now, suppose we receive a Paging I/O write to a mapped file. And we make
>>>>any call that makes use of Pageable memory (Paged code, data,etc), again
>>>>the same thing will happen that happened in case of Modified page
>>>>writer. Recursion. This time the rescue depends on the Modified Page
>>>>Writer.<<<
>
> 1. Does this mean that if I take care that I don’t Wait in the Paging I/O
> path directed to PAGE FILE, it will work?
> 2. In other words using a wait function like KeWaitForSingleObject after
> calling a function F that can be called at IRQL <= APC_LEVEL is OK?
> 3. My logic being that even if this function F accesses a paged data, it
> can be fetched from the PAGE FILE. Is my logic correct?
>

> As you must have already understood, the above excerpt is just wrong, and

Ayush already made a correction to his earlier post. Therefore, you should
not try to make any conclusions based upon the above excerpt…

The statement made by Ayush was “the FS filter CANNOT generate a page fault
when this Paging I/O is directed to the PAGE FILE, however, it CAN generate
page fault when it is on a mapped file.” and it is correct and means - page
fault on “code and data”.


Slava Imameyev, xxxxx@hotmail.com

wrote in message news:xxxxx@ntfsd…
>> 1. Where does the code gets swapped out? To the PAGE FILE I suppose. Then
>> why can’t the code be also brought in similar to the DATA in case of
>> MAPPED FILE?
>
>
> Look - say, you are processing paging IO, and a function X that you have
> to execute is currently swapped to the disk. Therefore, you take page
> fault ( page fault A), which has to get processed before you can continue
> with your operation - otherwise, you just haven’t got a chance to execute
> function X that is vital for your task. In order to process page fault A
> you, again, have to execute the same function X which is still swapped to
> the disk, i.e. you generate one more page fault (page fault B). In order
> to process page fault B, you have to execute function X -> you generate
> page fault C- > in order to process page fault C, you have to execute
> function X -> you generate page fault D->and so on and so forth up to
> infinity.
>
>
> If you replace “execute function X” with “access variable X”, the above
> paragraph also described what happens when you page fault on data while
> processing a paging IO to the page file - you have no chance to process
> page faults without accessing variable X, but any access to this variable
> generates a page fault, i.e., again, you get into an infinite chain of
> page faults.
>
> However, if the target file is a mapped one, situation is somehow
> different when you page fault on data - variable X will be brough to
> memory from the paging file, and, at this point, you can continue with
> your task of processing paging IO to the target mapped file.
>
>
>
>>>>Now, suppose we receive a Paging I/O write to a mapped file. And we make
>>>>any call that makes use of Pageable memory (Paged code, data,etc), again
>>>>the same thing will happen that happened in case of Modified page
>>>>writer.
>>>>Recursion. This time the rescue depends on the Modified Page Writer.<<<
>
> As you must have already understood, the above excerpt is just wrong, and
> Ayush already made a correction to his earlier post. Therefore, you should
> not try to make any conclusions based upon the above excerpt…
>
> Anton Bassov
>
>
>
>

Thanks Slava for backing up my statement.
But I think that Anton was referring to Message 4 of this thread. Actually,
in message 5, I had made some corrections.
However, could you let me know whether the whole scenario of paging i/o
write that I explained for MAPPED FILES was correct?
I know that description of paging read was wrong and I made the corrections
in message 5.
I know that Message 4 is almost wrong, but still I think that this situation
can occur with respect to MAPPED FILES.

Regards!
Ayush Gupta
K7 Computing Pvt. Ltd.
www.k7computing.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Slava Imameyev
Sent: Wednesday, August 01, 2007 3:22 PM
To: Windows File Systems Devs Interest List
Subject: Re:[ntfsd] Why does blocking the Paging I/O request lead to
deadlock?

As you must have already understood, the above excerpt is just wrong, and
Ayush already made a correction to his earlier post. Therefore, you should

not try to make any conclusions based upon the above excerpt…

The statement made by Ayush was "the FS filter CANNOT generate a page fault

when this Paging I/O is directed to the PAGE FILE, however, it CAN generate
page fault when it is on a mapped file." and it is correct and means - page
fault on “code and data”.


Slava Imameyev, xxxxx@hotmail.com

wrote in message news:xxxxx@ntfsd…
>> 1. Where does the code gets swapped out? To the PAGE FILE I suppose. Then
>> why can’t the code be also brought in similar to the DATA in case of
>> MAPPED FILE?
>
>
> Look - say, you are processing paging IO, and a function X that you have
> to execute is currently swapped to the disk. Therefore, you take page
> fault ( page fault A), which has to get processed before you can continue
> with your operation - otherwise, you just haven’t got a chance to execute

> function X that is vital for your task. In order to process page fault A
> you, again, have to execute the same function X which is still swapped to
> the disk, i.e. you generate one more page fault (page fault B). In order
> to process page fault B, you have to execute function X -> you generate
> page fault C- > in order to process page fault C, you have to execute
> function X -> you generate page fault D->and so on and so forth up to
> infinity.
>
>
> If you replace “execute function X” with “access variable X”, the above
> paragraph also described what happens when you page fault on data while
> processing a paging IO to the page file - you have no chance to process
> page faults without accessing variable X, but any access to this variable
> generates a page fault, i.e., again, you get into an infinite chain of
> page faults.
>
> However, if the target file is a mapped one, situation is somehow
> different when you page fault on data - variable X will be brough to
> memory from the paging file, and, at this point, you can continue with
> your task of processing paging IO to the target mapped file.
>
>
>
>>>>Now, suppose we receive a Paging I/O write to a mapped file. And we make
>>>>any call that makes use of Pageable memory (Paged code, data,etc), again
>>>>the same thing will happen that happened in case of Modified page
>>>>writer.
>>>>Recursion. This time the rescue depends on the Modified Page Writer.<<<
>
> As you must have already understood, the above excerpt is just wrong, and
> Ayush already made a correction to his earlier post. Therefore, you should

> not try to make any conclusions based upon the above excerpt…
>
> Anton Bassov
>
>
>
>


NTDEV is sponsored by OSR

For our schedule debugging and file system seminars
(including our new fs mini-filter seminar) visit:
http://www.osr.com/seminars

You are currently subscribed to ntfsd as: xxxxx@yahoo.co.in
To unsubscribe send a blank email to xxxxx@lists.osr.com

> But I think that Anton was referring to Message 4 of this thread.

Yes, but the reference was made in the context of supporting the wrong
statement, though your last statement was correct and contradicted with the
wrong statement in which support it was used.

However, could you let me know whether the whole scenario of paging i/o
write that I explained for MAPPED FILES was correct?

Actually, your first mesage was very intricate, it is hard to catch the
meaning, but the second message was clear. There is a strange phrase in your
first message “The thread responsible for reading is blocked.”. I know only
the one reading thread - the Cache Manager’s read-ahead-thread( beside this,
it also works as a writing thread ) and it has nothing to do with this
discussion. The read requests issued by the page fault handler are always
sent in the context of the thread where page fault occures. There is no
thread dedicated for processing requests from page fault handler. The paging
write requests might be sent either in the context of the Mapped and
Modified page writer or in the context of the thread flushing mapped file’s
pages( cache manager’s thread, user’s thread etc. ). It is obvious that if
the page is supported by an ordinary data stream you can generate page fault
for pages backed by the pagefile, the opposite is wrong. Whether the page
fault has been caused by reading from or writing in the page backed by the
pagefile doesn’t have any matter.


Slava Imameyev, xxxxx@hotmail.com

“Ayush Gupta” wrote in message news:xxxxx@ntfsd…
> Thanks Slava for backing up my statement.
> But I think that Anton was referring to Message 4 of this thread.
> Actually,
> in message 5, I had made some corrections.
> However, could you let me know whether the whole scenario of paging i/o
> write that I explained for MAPPED FILES was correct?
> I know that description of paging read was wrong and I made the
> corrections
> in message 5.
> I know that Message 4 is almost wrong, but still I think that this
> situation
> can occur with respect to MAPPED FILES.
>
> Regards!
> Ayush Gupta
> K7 Computing Pvt. Ltd.
> www.k7computing.com
>
>
>
> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com] On Behalf Of Slava Imameyev
> Sent: Wednesday, August 01, 2007 3:22 PM
> To: Windows File Systems Devs Interest List
> Subject: Re:[ntfsd] Why does blocking the Paging I/O request lead to
> deadlock?
>
>> As you must have already understood, the above excerpt is just wrong, and
>> Ayush already made a correction to his earlier post. Therefore, you
>> should
>
>> not try to make any conclusions based upon the above excerpt…
>
> The statement made by Ayush was “the FS filter CANNOT generate a page
> fault
>
> when this Paging I/O is directed to the PAGE FILE, however, it CAN
> generate
> page fault when it is on a mapped file.” and it is correct and means -
> page
> fault on “code and data”.
>
> –
> Slava Imameyev, xxxxx@hotmail.com
>
>
> wrote in message news:xxxxx@ntfsd…
>>> 1. Where does the code gets swapped out? To the PAGE FILE I suppose.
>>> Then
>>> why can’t the code be also brought in similar to the DATA in case of
>>> MAPPED FILE?
>>
>>
>> Look - say, you are processing paging IO, and a function X that you have
>> to execute is currently swapped to the disk. Therefore, you take page
>> fault ( page fault A), which has to get processed before you can continue
>> with your operation - otherwise, you just haven’t got a chance to
>> execute
>
>> function X that is vital for your task. In order to process page fault A
>> you, again, have to execute the same function X which is still swapped to
>> the disk, i.e. you generate one more page fault (page fault B). In order
>> to process page fault B, you have to execute function X -> you generate
>> page fault C- > in order to process page fault C, you have to execute
>> function X -> you generate page fault D->and so on and so forth up to
>> infinity.
>>
>>
>> If you replace “execute function X” with “access variable X”, the above
>> paragraph also described what happens when you page fault on data while
>> processing a paging IO to the page file - you have no chance to process
>> page faults without accessing variable X, but any access to this variable
>> generates a page fault, i.e., again, you get into an infinite chain of
>> page faults.
>>
>> However, if the target file is a mapped one, situation is somehow
>> different when you page fault on data - variable X will be brough to
>> memory from the paging file, and, at this point, you can continue with
>> your task of processing paging IO to the target mapped file.
>>
>>
>>
>>>>>Now, suppose we receive a Paging I/O write to a mapped file. And we
>>>>>make
>>>>>any call that makes use of Pageable memory (Paged code, data,etc),
>>>>>again
>>>>>the same thing will happen that happened in case of Modified page
>>>>>writer.
>>>>>Recursion. This time the rescue depends on the Modified Page Writer.<<<
>>
>> As you must have already understood, the above excerpt is just wrong, and
>> Ayush already made a correction to his earlier post. Therefore, you
>> should
>
>> not try to make any conclusions based upon the above excerpt…
>>
>> Anton Bassov
>>
>>
>>
>>
>
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule debugging and file system seminars
> (including our new fs mini-filter seminar) visit:
> http://www.osr.com/seminars
>
> You are currently subscribed to ntfsd as: xxxxx@yahoo.co.in
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>

Thanks Everyone!

Ok. Now let me put it altogether. From a FS filter point of view, should we follow following rules? Please correct me if i am wrong or put your comments if there is a better explanation.

  1. If I receive a Paging I/O request to a PAGE FILE, i should not call any function that cannot be called at DISPATCH_LEVEL -
    This is so because any function that cannot be called at IRQL = DISPATCH_LEVEL may be using some data that is allocated from Paged Pool and hence may be present in the PAGE FILE itself. This may cause a never ending recursion and thus a deadlock.

  2. If I receive a Paging I/O request to a MAPPED FILE, i can call any function that can be called at IRQL <= APC_LEVEL -
    This flexibility is due to the fact that if a page fault occurs, either for bringing in the CODE or DATA, they will be brought in by issuing a read request targeted to the PAGE FILE. Since, the second call is directed to PAGE FILE rather than the MAPPED FILE for which i had originally received the request, there will be no recursion and hence no deadlock.

  3. I should avoid issuing any cached I/O or allocating huge amount of memory from Paged Pool in the Paging I/O path especially if i wait after issuing that cached i/o -
    This is so because if i request huge amount of memory, that can lead to flushing of dirty pages in memory to disk (To PAGE FILE or MAPPED FILE). This may slow down the system. And if i am waiting on a Paging I/O path directed to a MAPPED FILE, i have blocked the Mapped Page Writer Thread. Hence, the only way sufficient memory will be available will depend on how much page frames can Modified Page Writer can free up by flushing the dirty pages to the PAGE FILE. And, if it is unable to provide the required no. of pages, the system can go in partial deadlock because no more writes can happen on MAPPED FILES.

  4. I can issue non cached file system calls directed to a different file (say a Journal file, Log file, etc ) and wait for completion, in the Paging I/O path targeted to MAPPED FILE.

Regards!
-K. Dev.

Hello

There is another case of interest for the MappedPageWrite (paging for mapped
file). If in MappedPageWriter you acess memory mapped to some file then you
might cause the situation where in order for mm to remove a dirty mapped
page your driver will generate a dirty mapped page and this can lead to the
wonderful bugcheck DIRTY_MAPPED_PAGES_CONGESTION (eb).

Cheers
Lyndon

“Kernel Developer” wrote in message
news:xxxxx@ntfsd…
Thanks Everyone!

Ok. Now let me put it altogether. From a FS filter point of view, should we
follow following rules? Please correct me if i am wrong or put your comments
if there is a better explanation.

1. If I receive a Paging I/O request to a PAGE FILE, i should not call any
function that cannot be called at DISPATCH_LEVEL -
This is so because any function that cannot be called at IRQL =
DISPATCH_LEVEL may be using some data that is allocated from Paged Pool and
hence may be present in the PAGE FILE itself. This may cause a never
ending recursion and thus a deadlock.

2. If I receive a Paging I/O request to a MAPPED FILE, i can call any
function that can be called at IRQL <= APC_LEVEL -
This flexibility is due to the fact that if a page fault occurs,
either for bringing in the CODE or DATA, they will be brought in by issuing
a read request targeted to the PAGE FILE. Since, the second call is
directed to PAGE FILE rather than the MAPPED FILE for which i had originally
received the request, there will be no recursion and hence no deadlock.

3. I should avoid issuing any cached I/O or allocating huge amount of memory
from Paged Pool in the Paging I/O path especially if i wait after issuing
that cached i/o -
This is so because if i request huge amount of memory, that can lead
to flushing of dirty pages in memory to disk (To PAGE FILE or MAPPED FILE).
This may slow down the system. And if i am waiting on a Paging I/O path
directed to a MAPPED FILE, i have blocked the Mapped Page Writer Thread.
Hence, the only way sufficient memory will be available will depend on how
much page frames can Modified Page Writer can free up by flushing the dirty
pages to the PAGE FILE. And, if it is unable to provide the required no. of
pages, the system can go in partial deadlock because no more writes can
happen on MAPPED FILES.

4. I can issue non cached file system calls directed to a different file
(say a Journal file, Log file, etc ) and wait for completion, in the Paging
I/O path targeted to MAPPED FILE.

Regards!
-K. Dev.

>Ok. Now let me put it altogether. From a FS filter point of view, should we follow following rules? Please correct me if i am wrong or put your comments if there is a better explanation.

Actually you choose the wrong basis for classification - IRQL is not an appropriate basis for this, it is impossible to define a correct set of functions by using IRQL.

In the following explanation the term “ordinary data stream” stands for any data steram except pagefile data streams, i.e. “ordinary data stream” is not a pagefile. You can find exceptions to the following rules, but these exceptions always increase the possibility of a deadlock due to the page shortage and requires special conditions( if … and if … and if … then … ).

  1. If I receive a Paging I/O request to a PAGE FILE, i should not call any function that cannot be called at DISPATCH_LEVEL -

Wrong, function called at DISPATCH_LEVEL can’t wait, but in the case of paging IO to a pagefile you can wait, so the set of functions is much broader.
The correct definition for available function set is - the functions which don’t generate any page fault and do not acquire any resources related with any data stream if TopLevelIrp is not NULL.

  1. If I receive a Paging I/O request to a MAPPED FILE, i can call any function that can be called at IRQL <= APC_LEVEL -

This is a wrong definition. In that case the set of functions is defined by the following definition - you can use ANY functions which don’t generate page faults for pages backed by ordinary data streams and don’t acquire resources related with ordinary data stream if TopLevelIrp is not NULL, while there are exceptions to the former rule the latter prohibits any page fault except to pages backed by a pagefile.

  1. I should avoid issuing any cached I/O or allocating huge amount of memory from Paged Pool in the Paging I/O path especially if i wait after issuing that cached i/o -

Let’s rephrase this - You must not issue any cached I/O for any paging I/O path( it is better not to do this, though might be possible in some cases when TopLevelIrp is NULL ) and you must not allocate memory from Paged Pool when processing requests to a pagefile.

. I can issue non cached file system calls directed to a different file (say a Journal file, Log file, etc ) and wait for completion, in the Paging I/O path targeted to MAPPED FILE.

You can’t if TopLevelIpr is not NULL, because you do not know the synchronization model( lock hierarchy etc. ) used by the underlying FSD. If the TopLevelIpr is NULL then you can issue some type of requests, but as I said above it is better to avoid cached requests or requests to mapped files .


Slava Imameyev, xxxxx@hotmail.com

“Kernel Developer” wrote in message news:xxxxx@ntfsd…
Thanks Everyone!

Ok. Now let me put it altogether. From a FS filter point of view, should we follow following rules? Please correct me if i am wrong or put your comments if there is a better explanation.

1. If I receive a Paging I/O request to a PAGE FILE, i should not call any function that cannot be called at DISPATCH_LEVEL -
This is so because any function that cannot be called at IRQL = DISPATCH_LEVEL may be using some data that is allocated from Paged Pool and hence may be present in the PAGE FILE itself. This may cause a never ending recursion and thus a deadlock.

2. If I receive a Paging I/O request to a MAPPED FILE, i can call any function that can be called at IRQL <= APC_LEVEL -
This flexibility is due to the fact that if a page fault occurs, either for bringing in the CODE or DATA, they will be brought in by issuing a read request targeted to the PAGE FILE. Since, the second call is directed to PAGE FILE rather than the MAPPED FILE for which i had originally received the request, there will be no recursion and hence no deadlock.

3. I should avoid issuing any cached I/O or allocating huge amount of memory from Paged Pool in the Paging I/O path especially if i wait after issuing that cached i/o -
This is so because if i request huge amount of memory, that can lead to flushing of dirty pages in memory to disk (To PAGE FILE or MAPPED FILE). This may slow down the system. And if i am waiting on a Paging I/O path directed to a MAPPED FILE, i have blocked the Mapped Page Writer Thread. Hence, the only way sufficient memory will be available will depend on how much page frames can Modified Page Writer can free up by flushing the dirty pages to the PAGE FILE. And, if it is unable to provide the required no. of pages, the system can go in partial deadlock because no more writes can happen on MAPPED FILES.

4. I can issue non cached file system calls directed to a different file (say a Journal file, Log file, etc ) and wait for completion, in the Paging I/O path targeted to MAPPED FILE.

Regards!
-K. Dev.

Hi Lyndon!

>>There is another case of interest for the MappedPageWrite (paging for
mapped
file). If in MappedPageWriter you acess memory mapped to some file then you
might cause the situation where in order for mm to remove a dirty mapped
page your driver will generate a dirty mapped page and this can lead to the
wonderful bugcheck DIRTY_MAPPED_PAGES_CONGESTION (eb).<<<

I had given this scenario in message 4, though much part of the message was
wrong, but I wanted to explain the same thing. I did not know of this
bugcheck.
So, if you are issuing any file system call and waiting for it, ensure that
it is on a NON CACHED file. Moreover, DO NOT request huge memory allocation
from Paged Pool. This can lead to the bugcheck mentioned by Lyndon, if the
system is low on no. of free pages, when you do such a thing.

Regards!
Ayush Gupta
K7 Computing Pvt. Ltd.
www.k7computing.com

Hi Slava!

Some doubts on what you replied:

<<
I can issue non cached file system calls directed to a different file (say a Journal file, Log file, etc ) and wait for completion, in the Paging I/O path targeted to MAPPED FILE.-

You can’t if TopLevelIpr is not NULL, because you do not know the synchronization model( lock hierarchy etc. ) used by the underlying FSD. If the TopLevelIpr is NULL then you can issue some type of requests, but as I said above it is better to avoid cached requests or requests to mapped files .

>

In the above reply you are saying that I should avoid cached requests or requests to MAPPED files.
But I am asked whether i can issue file system calls to a NON CACHED file ( which may be my Log file ) and wait for its completion.
Let me explain it with an example:
Suppose i receive a paging i/o write on a Mapped file. Can i issue a NON CACHED write request to my log file and wait for its completion?

And one more thing, Why will TopLevelIrp cause any problem if i issue any NON CACHED I/O in this situation?

Thanks!
K. Dev.

>But I am asked whether i can issue file system calls to a NON CACHED file ( which may be my Log file ) and wait for its completion.

I gave the answer, the first sentence - “You can’t if TopLevelIpr is not NULL, because you do not know the synchronization model( lock hierarchy etc. ) used by the underlying FSD.”
The situation is softer if a log file and a file to which the requests is issued are on different volumes, in this case you might issue the write or read request if TopLevelIpr is not NULL, but there is a problem - some FSDs use Cache Manager for non cached requests, in this case the possibility of a deadlock is higher.

Suppose i receive a paging i/o write on a Mapped file. Can i issue a NON CACHED write request to my log file and wait for its completion?

Generally NO.

And one more thing, Why will TopLevelIrp cause any problem if i issue any NON CACHED I/O in this situation?

“because you do not know the synchronization model( lock hierarchy etc. ) used by the underlying FSD” and NON CACHED I/O doesn’t mean that the Cache Manager won’t be used, only PAGING I/O provides this guarantee.


Slava Imameyev, xxxxx@hotmail.com

“Kernel Developer” wrote in message news:xxxxx@ntfsd…
Hi Slava!

Some doubts on what you replied:

<<
I can issue non cached file system calls directed to a different file (say a Journal file, Log file, etc ) and wait for completion, in the Paging I/O path targeted to MAPPED FILE.-

You can’t if TopLevelIpr is not NULL, because you do not know the synchronization model( lock hierarchy etc. ) used by the underlying FSD. If the TopLevelIpr is NULL then you can issue some type of requests, but as I said above it is better to avoid cached requests or requests to mapped files .
>>

In the above reply you are saying that I should avoid cached requests or requests to MAPPED files.
But I am asked whether i can issue file system calls to a NON CACHED file ( which may be my Log file ) and wait for its completion.
Let me explain it with an example:
Suppose i receive a paging i/o write on a Mapped file. Can i issue a NON CACHED write request to my log file and wait for its completion?

And one more thing, Why will TopLevelIrp cause any problem if i issue any NON CACHED I/O in this situation?

Thanks!
K. Dev.

Thanks Slava!

You said:

“because you do not know the synchronization model( lock hierarchy etc. ) used
by the underlying FSD” and NON CACHED I/O doesn’t mean that the Cache Manager
won’t be used, only PAGING I/O provides this guarantee."

  1. Why will the FSD involve Cache Manager for NON CACHED I/O?
  2. A case where the FSD can involve Cache manager in a Non Cached I/O is that the file is also cached by the chache manager. So, even if i make a non cached request, it will have to update the cache too… Right?
  3. What if I open my log file in DriverEntry itself and lock it. Then if i issue Non Cached I/O on it in a Paging I/O path ( to a mapped file of course ). Why will it involve the cache manager?
  4. Can i issue a Paging I/O request to my log file and escape from all this trouble?

Thanks!
-K. Dev.