ExAcquireFastMutex and I/O operations in Win2K

Another NT 4.0 to Win2K porting problem.

It seems that issuing any I/O call (ZwCreateFile, ZwOpenFile, etc) after an
“ExAcquireFastMutex” hangs on “KeWaitForSingleObject”. After investigating a
little more I realized that this makes sense since, according to the DDK
online help, “ExAcquireFastMutex sets the IRQL to APC_LEVEL, and the caller
continues to run at APC_LEVEL”. But “Callers of ZwCreateFile must be running
at IRQL PASSIVE_LEVEL”.

The same code that hangs on Win2k is working fine on NT. Did Microsoft get
strictet about this rule on Win2K or is this new functionality?

In any case, what’s a good workaround for this problem assuming the
FastMutex is necessary? I’m thinking the following would work. Is there a
better approach?

myIrql=KeGetCurrentIrql();
ExAcquireFastMutex(myMutex);
KeLowerIrql(myIrql);

{ // I/O operation here }

KeRaiseIrql(APC_LEVEL, myIrql);
ExReleaseFastMutex(myMutex);


Thanks,
Theodoros David
www.steeleye.com


You are currently subscribed to ntfsd as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntfsd-$subst(‘Recip.MemberIDChar’)@lists.osr.com

Yes, there’s a better approach. Don’t hold the lock while issuing
ZwCreateFile(). Fast mutexes are not recursively acquirable anyway. You
probably deadlocked with yourself. In general, holding a lock while
calling outside your filter is a big NO NO due to the potential for
deadlocks.
Chances are - you can workaround without holding the lock.

In your case you have a selected a lock which is not suitable for what
you wanted to do, but you are trying to hack your way through.

If you really, really know what you are doing & if you have completely
ascertained that you would not be in the path of the recursive call
yourself - well you can’t avoid in this case - but you are careful not
to try to re-acquire it:
. Disable normal APC’s via FsRtlEnterFileSystem() first.
. Use ExAcquireFastMutexUnsafe() which will not elevate the IRQL in
the first place (ExReleaseFastMutexUnsafe is the counterpart).


This posting is provided “AS IS” with no warranties, and confers no
rights. You assume all risk for your use

-----Original Message-----
From: Theodoros David [mailto:xxxxx@steeleye.com]
Sent: Thursday, December 20, 2001 1:54 PM
To: File Systems Developers
Cc: xxxxx@lists.osr.com
Subject: [ntfsd] ExAcquireFastMutex and I/O operations in Win2K

Another NT 4.0 to Win2K porting problem.

It seems that issuing any I/O call (ZwCreateFile, ZwOpenFile, etc) after
an “ExAcquireFastMutex” hangs on “KeWaitForSingleObject”. After
investigating a little more I realized that this makes sense since,
according to the DDK online help, “ExAcquireFastMutex sets the IRQL to
APC_LEVEL, and the caller continues to run at APC_LEVEL”. But “Callers
of ZwCreateFile must be running at IRQL PASSIVE_LEVEL”.

The same code that hangs on Win2k is working fine on NT. Did Microsoft
get strictet about this rule on Win2K or is this new functionality?

In any case, what’s a good workaround for this problem assuming the
FastMutex is necessary? I’m thinking the following would work. Is there
a better approach?

myIrql=KeGetCurrentIrql();
ExAcquireFastMutex(myMutex);
KeLowerIrql(myIrql);

{ // I/O operation here }

KeRaiseIrql(APC_LEVEL, myIrql);
ExReleaseFastMutex(myMutex);


Thanks,
Theodoros David
www.steeleye.com


You are currently subscribed to ntfsd as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to leave-ntfsd-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntfsd as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntfsd-$subst(‘Recip.MemberIDChar’)@lists.osr.com

Note: in your particular deadlock scenario though, it appears that
someone returned STATUS_PENDING
from the create & the create was waiting for the create IRP to complete
(i/o manager synchronizes the create)
The I/O completion was held up because you were at APC_LEVEL. Hang.

This posting is provided "AS IS" with no warranties, and confers no
rights. You assume all risk for your use

-----Original Message-----
From: Ravisankar Pudipeddi
Sent: Thursday, December 20, 2001 3:30 PM
To: 'File Systems Developers'
Cc: xxxxx@lists.osr.com
Subject: RE: [ntfsd] ExAcquireFastMutex and I/O operations in Win2K

Yes, there's a better approach. Don't hold the lock while issuing
ZwCreateFile(). Fast mutexes are not recursively acquirable anyway. You
probably deadlocked with yourself. In general, holding a lock while
calling outside your filter is a big NO NO due to the potential for
deadlocks.
Chances are - you can workaround without holding the lock.

In your case you have a selected a lock which is not suitable for what
you wanted to do, but you are trying to hack your way through.

If you really, really know what you are doing & if you have completely
ascertained that you would not be in the path of the recursive call
yourself - well you can't avoid in this case - but you are careful not
to try to re-acquire it:
. Disable normal APC's via FsRtlEnterFileSystem() first.
. Use ExAcquireFastMutexUnsafe() which will not elevate the IRQL in
the first place (ExReleaseFastMutexUnsafe is the counterpart).

--
This posting is provided "AS IS" with no warranties, and confers no
rights. You assume all risk for your use

-----Original Message-----
From: Theodoros David [mailto:xxxxx@steeleye.com]
Sent: Thursday, December 20, 2001 1:54 PM
To: File Systems Developers
Cc: xxxxx@lists.osr.com
Subject: [ntfsd] ExAcquireFastMutex and I/O operations in Win2K

Another NT 4.0 to Win2K porting problem.

It seems that issuing any I/O call (ZwCreateFile, ZwOpenFile, etc) after
an "ExAcquireFastMutex" hangs on "KeWaitForSingleObject". After
investigating a little more I realized that this makes sense since,
according to the DDK online help, "ExAcquireFastMutex sets the IRQL to
APC_LEVEL, and the caller continues to run at APC_LEVEL". But "Callers
of ZwCreateFile must be running at IRQL PASSIVE_LEVEL".

The same code that hangs on Win2k is working fine on NT. Did Microsoft
get strictet about this rule on Win2K or is this new functionality?

In any case, what's a good workaround for this problem assuming the
FastMutex is necessary? I'm thinking the following would work. Is there
a better approach?

myIrql=KeGetCurrentIrql();
ExAcquireFastMutex(myMutex);
KeLowerIrql(myIrql);

{ // I/O operation here }

KeRaiseIrql(APC_LEVEL, myIrql);
ExReleaseFastMutex(myMutex);

--
Thanks,
Theodoros David


You are currently subscribed to ntfsd as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to leave-ntfsd-$subst('Recip.MemberIDChar')@lists.osr.com


You are currently subscribed to ntfsd as: $subst('Recip.EmailAddr')
To unsubscribe send a blank email to leave-ntfsd-$subst('Recip.MemberIDChar')@lists.osr.com