IoCancelIrp

Does IoCancelIrp do an InterlockedExchange with 0 for the cancel routine as implied by the design guide,
or does it only set irp->Cancel to TRUE, and read the cancel routine, as stated in the Reference section?


Dave Harvey, System Software Solutions, Inc.
617-964-7039, FAX 208-361-9395, xxxxx@syssoftsol.com, http://www.syssoftsol.com
Creators of RedunDisks - Robust RAID 1 for embedded systems.

The IoCancelIrp looks like this…

BOOLEAN
IoCancelIrp (
IN PIRP Irp
)
{
KIRQL Irql;
PDRIVER_CANCEL CancelRoutine;

ASSERT(Irp->Type == IO_TYPE_IRP);

IoAcquireCancelSpinLock(&Irql);

Irp->Cancel = TRUE;
CancelRoutine = Irp->CancelRoutine;
Irp->CnacelRoutine = NULL;

if (CancelRoutine != NULL)
{
if (Irp->CurrentLocation > Irp->StackCount + 1)
{
KeBugCheckEx(CANCEL_STATE_IN_COMPLETED_IRP, Irp, 0, 0, 0);
}

Irp->CancelIrql = Irql;
CancelRoutine(IoGetCurrentIrpStackLocation(Irp)->DeviceObject, Irp);
return TRUE;
}

IoReleaseCancelSpinLock(&Irql);
return FALSE;
}

Paul

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Dave Harvey
Sent: Thursday, February 28, 2002 4:20 AM
To: NT Developers Interest List
Subject: [ntdev] IoCancelIrp

Does IoCancelIrp do an InterlockedExchange with 0 for the cancel routine as
implied by the design guide,
or does it only set irp->Cancel to TRUE, and read the cancel routine, as
stated in the Reference section?



Dave Harvey, System Software Solutions, Inc.
617-964-7039, FAX 208-361-9395, xxxxx@syssoftsol.com,
http://www.syssoftsol.com
Creators of RedunDisks - Robust RAID 1 for embedded systems.


You are currently subscribed to ntdev as: xxxxx@compelson.com
To unsubscribe send a blank email to %%email.unsub%%

Why do you care? If the doc doesn’t say it uses “interlocked exchange”
you are not to rely on this behavior, are you? As they say, “it can change
in the next OS release”. If you still care, take a look at the function
in a debugger. It is really short and simple, I promise :slight_smile:

— Dave Harvey wrote:
> Does IoCancelIrp do an InterlockedExchange with 0 for the cancel routine as
> implied by the design guide,
> or does it only set irp->Cancel to TRUE, and read the cancel routine, as
> stated in the Reference section?
>
>
>
----------------------------------------------------------------------------------------------------------
> Dave Harvey, System Software Solutions, Inc.
> 617-964-7039, FAX 208-361-9395, xxxxx@syssoftsol.com,
> http://www.syssoftsol.com
> Creators of RedunDisks - Robust RAID 1 for embedded systems.
>
>
>
>
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@yahoo.com
> To unsubscribe send a blank email to %%email.unsub%%

__________________________________________________
Do You Yahoo!?
Yahoo! Greetings - Send FREE e-cards for every occasion!
http://greetings.yahoo.com

Why dont you let himslef to decide if he cares or not ? Moreover , this list
is to put and answer and receive questions. If everyone would be very good
at reverse enginnering, and have the time to accomplish this activity, then
this list would be almost
futile. So you can leave your "It is really short and simple, I promise "
apart, Reverse enginnering is not always simple, and not always short.

Respectfully yours, Dan

----- Original Message -----
From: “Ntdev Reader”
To: “NT Developers Interest List”
Sent: Friday, March 01, 2002 1:09 AM
Subject: [ntdev] Re: IoCancelIrp

> Why do you care? If the doc doesn’t say it uses “interlocked exchange”
> you are not to rely on this behavior, are you? As they say, “it can change
> in the next OS release”. If you still care, take a look at the function
> in a debugger. It is really short and simple, I promise :slight_smile:
>
> — Dave Harvey wrote:
> > Does IoCancelIrp do an InterlockedExchange with 0 for the cancel routine
as
> > implied by the design guide,
> > or does it only set irp->Cancel to TRUE, and read the cancel routine, as
> > stated in the Reference section?
> >
> >
> >
> --------------------------------------------------------------------------
--------------------------------
> > Dave Harvey, System Software Solutions, Inc.
> > 617-964-7039, FAX 208-361-9395, xxxxx@syssoftsol.com,
> > http://www.syssoftsol.com
> > Creators of RedunDisks - Robust RAID 1 for embedded systems.
> >
> >
> >
> >
> >
> >
> > —
> > You are currently subscribed to ntdev as: xxxxx@yahoo.com
> > To unsubscribe send a blank email to %%email.unsub%%
>
>
> __________________________________________________
> Do You Yahoo!?
> Yahoo! Greetings - Send FREE e-cards for every occasion!
> http://greetings.yahoo.com
>
> —
> You are currently subscribed to ntdev as: xxxxx@rdsor.ro
> To unsubscribe send a blank email to %%email.unsub%%
>

I apologize. Now that I have re-read my message it does seem to contain
very little useful information. To compensate for this I will tell that
I looked at the function in one of NT4 kernels (don’t remember which one)
and the function did use the “interlocked exchange” to set the cancel
function pointer to NULL and then called the cancel function if it was in
the IRP. This apparently might have changed since then, for the other
poster’s “pseudo-code” for the function doesn’t show the “interlocked
exchange” and differs from what I saw in several other places.

— Dan Partelly wrote:
> Why dont you let himslef to decide if he cares or not ? Moreover , this list
> is to put and answer and receive questions. If everyone would be very good
> at reverse enginnering, and have the time to accomplish this activity, then
> this list would be almost
> futile. So you can leave your "It is really short and simple, I promise "
> apart, Reverse enginnering is not always simple, and not always short.
>
>
> Respectfully yours, Dan
>
> ----- Original Message -----
> From: “Ntdev Reader”
> To: “NT Developers Interest List”
> Sent: Friday, March 01, 2002 1:09 AM
> Subject: [ntdev] Re: IoCancelIrp
>
>
> > Why do you care? If the doc doesn’t say it uses “interlocked exchange”
> > you are not to rely on this behavior, are you? As they say, “it can change
> > in the next OS release”. If you still care, take a look at the function
> > in a debugger. It is really short and simple, I promise :slight_smile:
> >
> > — Dave Harvey wrote:
> > > Does IoCancelIrp do an InterlockedExchange with 0 for the cancel routine
> as
> > > implied by the design guide,
> > > or does it only set irp->Cancel to TRUE, and read the cancel routine, as
> > > stated in the Reference section?
> > >
> > >
> > >
> > --------------------------------------------------------------------------
> --------------------------------
> > > Dave Harvey, System Software Solutions, Inc.
> > > 617-964-7039, FAX 208-361-9395, xxxxx@syssoftsol.com,
> > > http://www.syssoftsol.com
> > > Creators of RedunDisks - Robust RAID 1 for embedded systems.
> > >
> > >
> > >
> > >
> > >
> > >
> > > —
> > > You are currently subscribed to ntdev as: xxxxx@yahoo.com
> > > To unsubscribe send a blank email to %%email.unsub%%
> >
> >
> >
> > Do You Yahoo!?
> > Yahoo! Greetings - Send FREE e-cards for every occasion!
> > http://greetings.yahoo.com
> >
> > —
> > You are currently subscribed to ntdev as: xxxxx@rdsor.ro
> > To unsubscribe send a blank email to %%email.unsub%%
> >
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@yahoo.com
> To unsubscribe send a blank email to %%email.unsub%%


Do You Yahoo!?
Yahoo! Greetings - Send FREE e-cards for every occasion!
http://greetings.yahoo.com

RE: [ntdev] IoCancelIrpIf I’m protecting my queue with my own lock, and use the example from the DDK design guide,
and the code is as you show it, isn’t there a race on two CPUs where the cancel routine
will not be called? i.e., IoCancelIrp reads irp->CancelRoutine, the driver then sets it
on the other CPU, then IoCancelIrp overwrites it.

If the code was:
CancelRoutine = Irp->CancelRoutine;
if (CancelRoutine != NULL)
{
Irp->CnacelRoutine = NULL;

Then there is a race were the IRP could be completed twice.
-DH

Here’s the DDK example:

KeAcquireSpinLock(&deviceContext->irpQueueSpinLock, &oldIrql);

// Queue the IRP and call IoMarkIrpPending
// to indicate that the IRP may complete on a different thread.
// N.B. It’s okay to call these inside the spin lock because they’re macros, not functions.
IoMarkIrpPending(Irp);
InsertTailList(&deviceContext->irpQueue, &Irp->Tail.Overlay.ListEntry);

// Must set a Cancel routine before checking the Cancel flag.
oldCancelRoutine = IoSetCancelRoutine(Irp, IrpCancelRoutine);
ASSERT(!oldCancelRoutine);

if (Irp->Cancel){
// The IRP was canceled. Check whether our cancel routine was called.
oldCancelRoutine = IoSetCancelRoutine(Irp, NULL);
if (oldCancelRoutine){
// The cancel routine was NOT called.
// So dequeue the IRP now and complete it after releasing the spinlock.
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
status = Irp->IoStatus.Status = STATUS_CANCELLED;
} //endif
else {
// The cancel routine WAS called.
// As soon as we drop our spin lock it will dequeue and complete the IRP.
// So leave the IRP in the queue and otherwise don’t touch it.
// Return pending since we’re not completing the IRP here.
} //end else
} // endif

KeReleaseSpinLock(&deviceContext->irpQueueSpinLock, oldIrql);

“Pavel Hrdina” wrote in message news:xxxxx@ntdev…
The IoCancelIrp looks like this…
BOOLEAN
IoCancelIrp (
IN PIRP Irp
)
{
KIRQL Irql;
PDRIVER_CANCEL CancelRoutine;
ASSERT(Irp->Type == IO_TYPE_IRP);
IoAcquireCancelSpinLock(&Irql);
Irp->Cancel = TRUE;
CancelRoutine = Irp->CancelRoutine;
Irp->CnacelRoutine = NULL;
if (CancelRoutine != NULL)
{
if (Irp->CurrentLocation > Irp->StackCount + 1)
{
KeBugCheckEx(CANCEL_STATE_IN_COMPLETED_IRP, Irp, 0, 0, 0);
}
Irp->CancelIrql = Irql;
CancelRoutine(IoGetCurrentIrpStackLocation(Irp)->DeviceObject, Irp);
return TRUE;
}
IoReleaseCancelSpinLock(&Irql);
return FALSE;
}
Paul
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Dave Harvey
Sent: Thursday, February 28, 2002 4:20 AM
To: NT Developers Interest List
Subject: [ntdev] IoCancelIrp

Does IoCancelIrp do an InterlockedExchange with 0 for the cancel routine as implied by the design guide,
or does it only set irp->Cancel to TRUE, and read the cancel routine, as stated in the Reference section?

----------------------------------------------------------------------------------------------------------
Dave Harvey, System Software Solutions, Inc.
617-964-7039, FAX 208-361-9395, xxxxx@syssoftsol.com, http://www.syssoftsol.com
Creators of RedunDisks - Robust RAID 1 for embedded systems.


You are currently subscribed to ntdev as: xxxxx@compelson.com
To unsubscribe send a blank email to %%email.unsub%%

IoCancelIrp does indeed use InterlockedExchangePointer to grab the
function pointer, so it is synchronized with IoSetCancelRoutine
(otherwise IoSetCancelRoutine would also have to grab the cancel spin
lock). You can easily find this out by dumping the asm for IoCancelIrp.

D

This posting is provided “AS IS” with no warranties, and confers no
rights.

-----Original Message-----
From: Dave Harvey [mailto:xxxxx@syssoftsol.com]
Sent: Thursday, February 28, 2002 7:12 PM
To: NT Developers Interest List
Subject: [ntdev] Re: IoCancelIrp

RE: [ntdev] IoCancelIrpIf I’m protecting my queue with my own lock, and
use the example from the DDK design guide, and the code is as you show
it, isn’t there a race on two CPUs where the cancel routine
will not be called? i.e., IoCancelIrp reads irp->CancelRoutine, the
driver then sets it
on the other CPU, then IoCancelIrp overwrites it.

If the code was:
CancelRoutine = Irp->CancelRoutine;
if (CancelRoutine != NULL)
{
Irp->CnacelRoutine = NULL;

Then there is a race were the IRP could be completed twice.
-DH

Here’s the DDK example:

KeAcquireSpinLock(&deviceContext->irpQueueSpinLock, &oldIrql);

// Queue the IRP and call IoMarkIrpPending
// to indicate that the IRP may complete on a different thread. //
N.B. It’s okay to call these inside the spin lock because they’re
macros, not functions. IoMarkIrpPending(Irp);
InsertTailList(&deviceContext->irpQueue, &Irp->Tail.Overlay.ListEntry);

// Must set a Cancel routine before checking the Cancel flag.
oldCancelRoutine = IoSetCancelRoutine(Irp, IrpCancelRoutine);
ASSERT(!oldCancelRoutine);

if (Irp->Cancel){
// The IRP was canceled. Check whether our cancel routine was
called.
oldCancelRoutine = IoSetCancelRoutine(Irp, NULL);
if (oldCancelRoutine){
// The cancel routine was NOT called.
// So dequeue the IRP now and complete it after releasing the
spinlock.
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
status = Irp->IoStatus.Status = STATUS_CANCELLED;
} //endif
else {
// The cancel routine WAS called.
// As soon as we drop our spin lock it will dequeue and
complete the IRP.
// So leave the IRP in the queue and otherwise don’t touch it.
// Return pending since we’re not completing the IRP here.
} //end else
} // endif

KeReleaseSpinLock(&deviceContext->irpQueueSpinLock, oldIrql);

“Pavel Hrdina” wrote in message news:xxxxx@ntdev…
The IoCancelIrp looks like this… BOOLEAN IoCancelIrp (
IN PIRP Irp
)
{
KIRQL Irql;
PDRIVER_CANCEL CancelRoutine;
ASSERT(Irp->Type == IO_TYPE_IRP);
IoAcquireCancelSpinLock(&Irql);
Irp->Cancel = TRUE;
CancelRoutine = Irp->CancelRoutine;
Irp->CnacelRoutine = NULL;
if (CancelRoutine != NULL)
{
if (Irp->CurrentLocation > Irp->StackCount + 1)
{
KeBugCheckEx(CANCEL_STATE_IN_COMPLETED_IRP, Irp, 0, 0, 0);
}
Irp->CancelIrql = Irql;
CancelRoutine(IoGetCurrentIrpStackLocation(Irp)->DeviceObject,
Irp);
return TRUE;
}
IoReleaseCancelSpinLock(&Irql);
return FALSE;
}
Paul
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Dave Harvey
Sent: Thursday, February 28, 2002 4:20 AM
To: NT Developers Interest List
Subject: [ntdev] IoCancelIrp

Does IoCancelIrp do an InterlockedExchange with 0 for the cancel routine
as implied by the design guide, or does it only set irp->Cancel to TRUE,
and read the cancel routine, as stated in the Reference section?

------------------------------------------------------------------------
----------------------------------
Dave Harvey, System Software Solutions, Inc.
617-964-7039, FAX 208-361-9395, xxxxx@syssoftsol.com,
http://www.syssoftsol.com
Creators of RedunDisks - Robust RAID 1 for embedded systems.


You are currently subscribed to ntdev as: xxxxx@compelson.com
To unsubscribe send a blank email to %%email.unsub%%


You are currently subscribed to ntdev as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to %%email.unsub%%

“Ntdev Reader” wrote in message news:xxxxx@ntdev…
>
> Why do you care?
I like my code to work under all cases?

> If the doc doesn’t say it uses “interlocked exchange”
> you are not to rely on this behavior, are you?
What about when another part of the documentation
gives an example of how I’m supposed to code that can
only work if it does?

This seems like a lose-lose situation:
1) I get Flamed because I proposed a solution assuming that IoCancelIrp works as documented, because said solution is
inefficient.
2) I get Flamed because I ask how it really works.
-DH

PS. If you’d read your license, you’d find that reverse engineering the kernel violates it…

> As they say, “it can change
> in the next OS release”. If you still care, take a look at the function
> in a debugger. It is really short and simple, I promise :slight_smile:
>
> — Dave Harvey wrote:
> > Does IoCancelIrp do an InterlockedExchange with 0 for the cancel routine as
> > implied by the design guide,
> > or does it only set irp->Cancel to TRUE, and read the cancel routine, as
> > stated in the Reference section?
> >
> >
> >
> ----------------------------------------------------------------------------------------------------------
> > Dave Harvey, System Software Solutions, Inc.
> > 617-964-7039, FAX 208-361-9395, xxxxx@syssoftsol.com,
> > http://www.syssoftsol.com
> > Creators of RedunDisks - Robust RAID 1 for embedded systems.
> >
> >
> >
> >
> >
> >
> > —
> > You are currently subscribed to ntdev as: xxxxx@yahoo.com
> > To unsubscribe send a blank email to %%email.unsub%%
>
>
> __________________________________________________
> Do You Yahoo!?
> Yahoo! Greetings - Send FREE e-cards for every occasion!
> http://greetings.yahoo.com
>
>

> ----------

From:
xxxxx@windows.microsoft.com[SMTP:xxxxx@windows.microsoft.com]
Reply To: xxxxx@lists.osr.com
Sent: Friday, March 01, 2002 4:14 AM
To: xxxxx@lists.osr.com
Subject: [ntdev] Re: IoCancelIrp

IoCancelIrp does indeed use InterlockedExchangePointer to grab the
function pointer, so it is synchronized with IoSetCancelRoutine
(otherwise IoSetCancelRoutine would also have to grab the cancel spin
lock). You can easily find this out by dumping the asm for IoCancelIrp.

Easily? It is easy to miss it as Paul did in his disassembly. Compiler
generated intrinsic code and used XCHG instruction there (XP SMP kernel)
which should be sufficient for interlocked exchange (can’t be quite sure
without looking to Intel docs). As Dan wrote, reverse engeneering isn’t
always simple.

Best regards,

Michal Vodicka
STMicroelectronics Design and Application s.r.o.
[michal.vodicka@st.com, http:://www.st.com]

> ----------

From:
xxxxx@syssoftsol.com[SMTP:xxxxx@syssoftsol.com]
Reply To: xxxxx@lists.osr.com
Sent: Friday, March 01, 2002 4:27 AM
To: xxxxx@lists.osr.com
Subject: [ntdev] Re: IoCancelIrp

PS. If you’d read your license, you’d find that reverse engineering the
kernel violates it…

Are you sure? So we can’t use disassembly in windbg or softice? You don’t
need more to see how IoCancelIrp works.

Best regards,

Michal Vodicka
STMicroelectronics Design and Application s.r.o.
[michal.vodicka@st.com, http:://www.st.com]

— Dave Harvey wrote:
>
> “Ntdev Reader” wrote in message news:xxxxx@ntdev…
> >
> > Why do you care?
> I like my code to work under all cases?

I know you do :slight_smile: That was said in the context of the following -
that the doc doesn’t say anything about the actual behavior.
But since everybody knows that the doc often fails to deliver
comprehensive information, and in the light of the sample you mention,
you have a reasonable hope that they just failed to document this
crucial detail.

> This seems like a lose-lose situation:
> 1) I get Flamed because I proposed a solution assuming that IoCancelIrp works
> as documented, because said solution is
> inefficient.
> 2) I get Flamed because I ask how it really works.

I’m sorry, I had no intention to flame you. I have respect for prudent
people who want to know what is going on around them. I justw anted to
tell you how close to you is the answer to your question.

> -DH
>
> PS. If you’d read your license, you’d find that reverse engineering the
> kernel violates it…

I never reverse-engineer anything. Sometimes I do see Microsoft’s code
in the debugger when I’m pressing F8 many times so quickly that I fail
to stop at the right moment and press F10 to jump over a Microsoft
function, so… Oops! I’m there… what can I do? And once I’m there
I now have to press F8 again many times to quit their function, but I
can’t close my eyes because I need to know when I’m back in my code!
So, I see what their function is doing – and can you teach me how can
I forget what I saw? It is all their fault - why can’t their debugger
jump over their functions automatically? I’m no machine, I’m gonna make
mistakes. But I never thought of producing any engineering documentation
from what I saw, so it is not reverse-engineering. Seeing other people’s
code becomes harmful when you start incorporating ideas you saw in their
code into your code, without developing them yourself and paying royalty
to the authors. If your looking at it just helped you to call their code
correctly, it is rather useful to them, because now your driver will not
occationally crash their system.

And if you thought that looking at the function was reverse engeneering,
how did you expect somebody to answer your question and thus admit to it?
:slight_smile:

>
> > As they say, “it can change
> > in the next OS release”. If you still care, take a look at the function
> > in a debugger. It is really short and simple, I promise :slight_smile:
> >
> > — Dave Harvey wrote:
> > > Does IoCancelIrp do an InterlockedExchange with 0 for the cancel routine
> as
> > > implied by the design guide,
> > > or does it only set irp->Cancel to TRUE, and read the cancel routine, as
> > > stated in the Reference section?
> > >
> > >
> > >
> >
>
----------------------------------------------------------------------------------------------------------
> > > Dave Harvey, System Software Solutions, Inc.
> > > 617-964-7039, FAX 208-361-9395, xxxxx@syssoftsol.com,
> > > http://www.syssoftsol.com
> > > Creators of RedunDisks - Robust RAID 1 for embedded systems.
> > >
> > >
> > >
> > >
> > >
> > >
> > > —
> > > You are currently subscribed to ntdev as: xxxxx@yahoo.com
> > > To unsubscribe send a blank email to %%email.unsub%%
> >
> >
> >
> > Do You Yahoo!?
> > Yahoo! Greetings - Send FREE e-cards for every occasion!
> > http://greetings.yahoo.com
> >
> >
>
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@yahoo.com
> To unsubscribe send a blank email to %%email.unsub%%


Do You Yahoo!?
Yahoo! Greetings - Send FREE e-cards for every occasion!
http://greetings.yahoo.com

I assumed the following:
xchg without lock prefix is equivalent with two movs
on both UP and SMP. However there very different situation
is if the lock is present. Then it should equivalent with
InterlockedExchange.

However, now I’m looking into InetrlockedExchange and I’m
very surprised that it is implemented really by only simple
xchg without lock prefix, however every other InterlockedXxx
is implemented with that lock prefix (Increment,Decrement and
ExchangeAdd by lock xadd; CompareExchange[64] by lock cmpxchg[64]).

So I agree that two lines in my disassembly are not correct:
CancelRoutine = Irp->CancelRoutine and Irp->CancelRoutine = NULL
should be replaced by CancelRoutine = IoSetCancelRoutine(Irp, NULL);

But now my code should be correct, don’t you think so?

Paul

PS: Does any of you know why xchg doesn’t need lock to be safe in SMP?

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Michal Vodicka
Sent: Friday, March 01, 2002 4:45 AM
To: NT Developers Interest List
Subject: [ntdev] Re: IoCancelIrp


From:
xxxxx@windows.microsoft.com[SMTP:xxxxx@windows.microsoft.com]
Reply To: xxxxx@lists.osr.com
Sent: Friday, March 01, 2002 4:14 AM
To: xxxxx@lists.osr.com
Subject: [ntdev] Re: IoCancelIrp

IoCancelIrp does indeed use InterlockedExchangePointer to grab the
function pointer, so it is synchronized with IoSetCancelRoutine
(otherwise IoSetCancelRoutine would also have to grab the cancel spin
lock). You can easily find this out by dumping the asm for IoCancelIrp.

Easily? It is easy to miss it as Paul did in his disassembly. Compiler
generated intrinsic code and used XCHG instruction there (XP SMP kernel)
which should be sufficient for interlocked exchange (can’t be quite sure
without looking to Intel docs). As Dan wrote, reverse engeneering isn’t
always simple.

Best regards,

Michal Vodicka
STMicroelectronics Design and Application s.r.o.
[michal.vodicka@st.com, http:://www.st.com]


You are currently subscribed to ntdev as: xxxxx@compelson.com
To unsubscribe send a blank email to %%email.unsub%%

From

IA-32 Intel® Architecture
Software Developer’s
Manual
Volume 1:

“The XCHG (exchange) instruction swaps the contents of two operands. This instruction takes
the place of three MOV instructions and does not require a temporary location to save the
contents of one operand location while the other is being loaded. When a memory operand is
used with the XCHG instruction, the processor’s LOCK signal is automatically asserted. This
instruction is thus useful for implementing semaphores or similar data structures for process
synchronization. (See “Bus Locking” in Chapter 7 of the Intel Architecture Software Developer’s
Manual, Volume 3, for more information on bus locking.)”

Regards,

| Norbert Kawulski | mailto:xxxxx@stollmann.de |
| Stollmann E+V GmbH, Development | http://www.stollmann.de |
–If it’s ISDN or Bluetooth, make sure it’s driven by Stollmann–

“Make Love, not war. Hell, do both, get married!”

I believe in previous OS versions (NT4 or w2k) there was a call to
interlocked exchange instead of intrinsic code inside IoCancelIrp(). I was
surprised it was missing in XP code and found there are intrinsic pragmas
for all interlocked functions in XP DDK headers. It would be nice if
disassembler detects and marks such pieces of code, it is really easy to
overlook (have to check if IDA is able to do it :). As for XCHG, I vaguely
remember this exception (automatic lock) was always there on x86
architecture. Norbert posted piece of docs which confirms it for new CPUs.

Yes, your code seems correctly now (not verified carefully :).

Michal

Best regards,

Michal Vodicka
STMicroelectronics Design and Application s.r.o.
[michal.vodicka@st.com, http:://www.st.com]


I assumed the following:
xchg without lock prefix is equivalent with two movs
on both UP and SMP. However there very different situation
is if the lock is present. Then it should equivalent with
InterlockedExchange.

However, now I’m looking into InetrlockedExchange and I’m
very surprised that it is implemented really by only simple
xchg without lock prefix, however every other InterlockedXxx
is implemented with that lock prefix (Increment,Decrement and
ExchangeAdd by lock xadd; CompareExchange[64] by lock cmpxchg[64]).

So I agree that two lines in my disassembly are not correct:
CancelRoutine = Irp->CancelRoutine and Irp->CancelRoutine = NULL
should be replaced by CancelRoutine = IoSetCancelRoutine(Irp, NULL);

But now my code should be correct, don’t you think so?

Paul

PS: Does any of you know why xchg doesn’t need lock to be safe in SMP?

ya, It was ExInterlockedExchangeUlong, but it is decalred as obsolete now,
best to my knowledge. And I doubt they used that even for NT 40, it does not
makes too much sense. However, xchg was always locking when dealing with
memory, on i386+. And best to my knowldge IDA will spit out correct code ,
thats only a xchg , whithout any locking prefix or whatever. Atomic
operations & instructions , and serializing instructions on IA32
architecture are clear defined in Intel’s manuals , but maybe they should
find their way into an FAQ. And Paul’s code is correct …

----- Original Message -----
From: “Michal Vodicka”
To: “NT Developers Interest List”
Sent: Friday, March 01, 2002 11:43 PM
Subject: [ntdev] Re: IoCancelIrp

> I believe in previous OS versions (NT4 or w2k) there was a call to
> interlocked exchange instead of intrinsic code inside IoCancelIrp(). I was
> surprised it was missing in XP code and found there are intrinsic pragmas
> for all interlocked functions in XP DDK headers. It would be nice if
> disassembler detects and marks such pieces of code, it is really easy to
> overlook (have to check if IDA is able to do it :). As for XCHG, I vaguely
> remember this exception (automatic lock) was always there on x86
> architecture. Norbert posted piece of docs which confirms it for new CPUs.
>
> Yes, your code seems correctly now (not verified carefully :).
>
> Michal
>
> Best regards,
>
> Michal Vodicka
> STMicroelectronics Design and Application s.r.o.
> [michal.vodicka@st.com, http:://www.st.com]
>
> > ----------
> >
> > I assumed the following:
> > xchg without lock prefix is equivalent with two movs
> > on both UP and SMP. However there very different situation
> > is if the lock is present. Then it should equivalent with
> > InterlockedExchange.
> >
> > However, now I’m looking into InetrlockedExchange and I’m
> > very surprised that it is implemented really by only simple
> > xchg without lock prefix, however every other InterlockedXxx
> > is implemented with that lock prefix (Increment,Decrement and
> > ExchangeAdd by lock xadd; CompareExchange[64] by lock cmpxchg[64]).
> >
> > So I agree that two lines in my disassembly are not correct:
> > CancelRoutine = Irp->CancelRoutine and Irp->CancelRoutine = NULL
> > should be replaced by CancelRoutine = IoSetCancelRoutine(Irp, NULL);
> >
> > But now my code should be correct, don’t you think so?
> >
> > Paul
> >
> > PS: Does any of you know why xchg doesn’t need lock to be safe in SMP?
> >
> >
>
> —
> You are currently subscribed to ntdev as: xxxxx@rdsor.ro
> To unsubscribe send a blank email to %%email.unsub%%
>