i am practicing using sync mechanism (mutex) in a minifilter and i am
having some doubts related to it.
I have a global to minifilter structure which data have to be
synchronize. Following i describe how data is manipulated:
User-mode sends data to minifilter using “FilterSendMessage”
Minifilter receives data via a callback routine given to
“FltCreateCommunicationPort”. Data is written in the global structure
inside the callback routine like this:
ExAcquireFastMutex(myMutex);
WriteData();
ExReleaseFastMutex(myMutex);
Minifilter filters IRP Create and read the structure, performing
some checkings:
ExAcquireFastMutex(myMutex);
ReadData();
ExReleaseFastMutex(myMutex);
My doubts are:
I have read (http://msdn.microsoft.com/en-us/windows/hardware/gg487402.aspx)
that it is necessary to raise the IRQL when using mutex, preventing
the interruption or pre-emption of the executing code, but what would
be the problem if the IRQL is not raised?
If a mutex raise the IRQL, normally to APC_LEVEL, what happens if it
is used some routine that needs PASSIVE_LEVEL?. I refer this because
driver vierifier shown me this error.
If a mutex raise the IRQL to APC_LEVEL, it is possible that the
minifilter driver execute code in DISPATCH_LEVEL and what would
happen?.
> My doubts are: > - I have read (http://msdn.microsoft.com/en-us/windows/hardware/gg487402.aspx) > that it is necessary to raise the IRQL when using mutex, preventing > the interruption or pre-emption of the executing code, but what would > be the problem if the IRQL is not raised?
The call raises the IRQL for you
> - If a mutex raise the IRQL, normally to APC_LEVEL, what happens if it > is used some routine that needs PASSIVE_LEVEL?. I refer this because > driver vierifier shown me this error.
It is an error, you need to redesign your code to not call routines that must run at passive level while holding the mutex.
> - If a mutex raise the IRQL to APC_LEVEL, it is possible that the > minifilter driver execute code in DISPATCH_LEVEL and what would > happen?. >
If once the mutex is held you raise the thread to DISPATCH_LEVEL there is no problem. Of course you can only do operations legal at dispatch when at that level.
You might want to ask minifilter question over on ntfsd.
if you don’t follow the rules bad things may happen.
running at dispatch level after acquiring the mutex is not in
itself a problem, accessing pageable code and data is.
Mark Roddy
On Thu, Jun 2, 2011 at 2:01 PM, Fran Baena wrote: > Hi all, > > i am practicing using sync mechanism (mutex) in a minifilter and i am > having some doubts related to it. > > I have a global to minifilter structure which data have to be > synchronize. Following i describe how data is manipulated: > > 1. User-mode sends data to minifilter using “FilterSendMessage” > 2. Minifilter receives data via a callback routine given to > “FltCreateCommunicationPort”. Data is written in the global structure > inside the callback routine like this: > > ExAcquireFastMutex(myMutex); > > WriteData(); > > ExReleaseFastMutex(myMutex); > > 3. Minifilter filters IRP Create and read the structure, performing > some checkings: > > ExAcquireFastMutex(myMutex); > > ReadData(); > > ExReleaseFastMutex(myMutex); > > > My doubts are: > ?- I have read (http://msdn.microsoft.com/en-us/windows/hardware/gg487402.aspx) > that it is necessary to raise the IRQL when using mutex, preventing > the interruption or pre-emption of the executing code, but what would > be the problem if the IRQL is not raised? > - If a mutex raise the IRQL, normally to APC_LEVEL, what happens if it > is used some routine that needs PASSIVE_LEVEL?. ?I refer this because > driver vierifier shown me this error. > - If a mutex raise the IRQL to APC_LEVEL, it is possible that the > minifilter driver execute code in DISPATCH_LEVEL and what would > happen?. > > > Thank you guys for the help. > > Fran > > — > NTDEV is sponsored by OSR > > 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 >
I have read (http://msdn.microsoft.com/en-us/windows/hardware/gg487402.aspx)
that it is necessary to raise the IRQL when using mutex, preventing
the interruption or pre-emption of the executing code, but what would
be the problem if the IRQL is not raised?
You get into a potential deadlock situation if two processes with
different IRQLs are competing for the same resource. If a higher
priority thread (which cannot block) needs to grab a mutex owned by a
lower priority thread, the higher priority thread cannot release the CPU
so that the lower priority thread can run and release it.
By raising the IRQL to the same level, all of the threads are forced to
share equally. The mutex holder will eventually be able to run and
release the mutex.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
“Fran Baena” wrote in message news:xxxxx@ntdev… > Hi all, > > i am practicing using sync mechanism (mutex) in a minifilter and i am > having some doubts related to it. > > I have a global to minifilter structure which data have to be > synchronize. Following i describe how data is manipulated: > > 1. User-mode sends data to minifilter using “FilterSendMessage” > 2. Minifilter receives data via a callback routine given to > “FltCreateCommunicationPort”. Data is written in the global structure > inside the callback routine like this: > > ExAcquireFastMutex(myMutex); > > WriteData(); > > ExReleaseFastMutex(myMutex); > > 3. Minifilter filters IRP Create and read the structure, performing > some checkings: > > ExAcquireFastMutex(myMutex); > > ReadData(); > > ExReleaseFastMutex(myMutex); > > > My doubts are: > - I have read (http://msdn.microsoft.com/en-us/windows/hardware/gg487402.aspx) > that it is necessary to raise the IRQL when using mutex, preventing > the interruption or pre-emption of the executing code, but what would > be the problem if the IRQL is not raised? > - If a mutex raise the IRQL, normally to APC_LEVEL, what happens if it > is used some routine that needs PASSIVE_LEVEL?. I refer this because > driver vierifier shown me this error. > - If a mutex raise the IRQL to APC_LEVEL, it is possible that the > minifilter driver execute code in DISPATCH_LEVEL and what would > happen?. > > > Thank you guys for the help. > > Fran >
> (http://msdn.microsoft.com/en-us/windows/hardware/gg487402.aspx)
> that it is necessary to raise the IRQL when using mutex,
> preventing the interruption or pre-emption of the executing code,
> but what would be the problem if the IRQL is not raised?
You get into a potential deadlock situation if two processes with
different IRQLs are competing for the same resource. If a higher
priority thread (which cannot block) needs to grab a mutex owned
by a lower priority thread, the higher priority thread cannot
release the CPU so that the lower priority thread can run and
release it.
By raising the IRQL to the same level, all of the threads are
forced to share equally. The mutex holder will eventually be
able to run and release the mutex.
No, that’s not the reason. Being at APC_LEVEL has no impact on how
threads are scheduled or whether they can block.
The actual reason why disabling APCs (either by raising to APC_LEVEL
or by entering a critical region) is necessary before acquiring a lock
is to prevent deadlocks that can occur if a user thread is suspended
while holding a kernel lock. See for example discussion under
“Security Issues” in this article:
mm
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Pavel Lebedynskiy
Sent: Thursday, June 02, 2011 5:21 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] IRQL management using file system filter driver
> - I have read
> (http://msdn.microsoft.com/en-us/windows/hardware/gg487402.aspx)
> that it is necessary to raise the IRQL when using mutex,
> preventing the interruption or pre-emption of the executing code,
> but what would be the problem if the IRQL is not raised?
You get into a potential deadlock situation if two processes with
different IRQLs are competing for the same resource. If a higher
priority thread (which cannot block) needs to grab a mutex owned
by a lower priority thread, the higher priority thread cannot
release the CPU so that the lower priority thread can run and
release it.
By raising the IRQL to the same level, all of the threads are
forced to share equally. The mutex holder will eventually be
able to run and release the mutex.
No, that’s not the reason. Being at APC_LEVEL has no impact on how
threads are scheduled or whether they can block.
The actual reason why disabling APCs (either by raising to APC_LEVEL
or by entering a critical region) is necessary before acquiring a lock
is to prevent deadlocks that can occur if a user thread is suspended
while holding a kernel lock. See for example discussion under
“Security Issues” in this article:
2011/6/2 Pavel Lebedynskiy : >>> ?- I have read >>> (http://msdn.microsoft.com/en-us/windows/hardware/gg487402.aspx) >>> that it is necessary to raise the IRQL when using mutex, >>> preventing the interruption or pre-emption of the executing code, >>> but what would be the problem if the IRQL is not raised? >> >> You get into a potential deadlock situation if two processes with >> different IRQLs are competing for the same resource. ?If a higher >> priority thread (which cannot block) needs to grab a mutex owned >> by a lower priority thread, the higher priority thread cannot >> release the CPU so that the lower priority thread can run and >> release it. >> >> By raising the IRQL to the same level, all of the threads are >> forced to share equally. ?The mutex holder will eventually be >> able to run and release the mutex. > > No, that’s not the reason. Being at APC_LEVEL has no impact on how > threads are scheduled or whether they can block. > > The actual reason why disabling APCs (either by raising to APC_LEVEL > or by entering a critical region) is necessary before acquiring a lock > is to prevent deadlocks that can occur if a user thread is suspended > while holding a kernel lock. See for example discussion under > “Security Issues” in this article:
OK, i understand the importance of raising the IRQL when acquiring a mutex. I have two more questions: 1) IRQL belongs to the thread or the processor? At “Scheduling, Thread Context, and IRQL” document the definition says that is related to the processor, but in practice it is referenced to the thread: thread A running in IRQL=PASSIVE_LEVEL… 2) What happens if a thread acquire a mutex raising the IRQL and it is not released in such thread? The next scheduled thread will run at previous thread IRQL? 3) What happens if a thread runs in IRQL=DISPATCH_LEVEL and acquires a fast mutext (it is supposed that it raises the IRQL to APC_LEVEL)?
Thank you for the answers. I really apreciate your collaboration. Fran
OK, i understand the importance of raising the IRQL when acquiring a
mutex. I have two more questions:
IRQL belongs to the thread or the processor? At “Scheduling, Thread
Context, and IRQL” document the definition says that is related to the
processor, but in practice it is referenced to the thread: thread A
running in IRQL=PASSIVE_LEVEL…
Well, the question is a little confusing. Really, the answer is
“both”. It’s almost like another CPU register. When a thread is not
running, the thread still has an IRQL. When it gets scheduled, the IRQL
is set for that processor by (in part) modifying the interrupt controller.
In your mental model, you need to think about it both ways. The current
processor has an IRQL, but it does so because the thread it is running
has that IRQL.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.