Processor Affinity in a driver

I have a couple of questions regarding processor affinity. (I am
specificly writing my driver for a WinXP system, but I would hope that
this wouldn’t change much from Win2K.)

I want a driver that can read the registers on a CPU. Problem is, if I
have a SMP system, how do I know which processors registers I am reading.
More specificly, I want to read the registers off of every CPU in the
system. (Reading the CPU registers isn’t all I do, but it is a simplified
version, I do need to read/write to hardware while being able to specify
which CPU I am reading/writing on a SMP system.)

So, how do I go about specifying the processor.

  1. Does my driver run on the same processor as the application which
    called it?
    If so, could I have an application which has N threads, and for each
    thread call SetThreadAffinityMask? Then each thread would call my driver,
    which would be running on the designated processor and read the registers.
    How would this work? In my application I call CreateThread(). My thread
    is now running on an arbitrary processor. Inside the thread I call
    SetThreadAffinityMask(). So now, how do I get the thread to actually
    switch to the correct processor? Is there some way to tell Windows to
    re-schedule the thread, or do I just tell the thread to sleep for some
    period of time, and when it wakes, it will be running on the correct
    processor?

  2. In Dekker’s book, he identifies that ZwSetInformationThread has an
    undocumented ThreadAffinityMask field. Is this setting the affinity for
    the application that is calling it, or for a thread in a multi-threaded
    driver? And, as above, once I set this field, how do I tell Windows to
    reschedule the thread on that processor?

Thanks for any help.
Brian

Hi

Yes your driver called in the context of the calling thread if there are no
filter drivers above yours to delay IRP. And in general first approach
should work for you. As for second situation I don’t think that
ZwSetInformationThread (used by Win32 function SetThreadAffinityMask) will
work for driver created system thread. However, may be I’m mistaken.

You could also use DPC’s for your needs. Initialize DPC and set target
processor via calling KeSetTargetProcessorDpc before calling IoRequestDpc.

BR,
Vadim
http://www.ntndis.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Brian Franklin
Sent: Thursday, April 04, 2002 10:49 PM
To: NT Developers Interest List
Subject: [ntdev] Processor Affinity in a driver

I have a couple of questions regarding processor affinity. (I am
specificly writing my driver for a WinXP system, but I would hope that
this wouldn’t change much from Win2K.)

I want a driver that can read the registers on a CPU. Problem is, if I
have a SMP system, how do I know which processors registers I am reading.
More specificly, I want to read the registers off of every CPU in the
system. (Reading the CPU registers isn’t all I do, but it is a simplified
version, I do need to read/write to hardware while being able to specify
which CPU I am reading/writing on a SMP system.)

So, how do I go about specifying the processor.

  1. Does my driver run on the same processor as the application which
    called it?
    If so, could I have an application which has N threads, and for each
    thread call SetThreadAffinityMask? Then each thread would call my driver,
    which would be running on the designated processor and read the registers.
    How would this work? In my application I call CreateThread(). My thread
    is now running on an arbitrary processor. Inside the thread I call
    SetThreadAffinityMask(). So now, how do I get the thread to actually
    switch to the correct processor? Is there some way to tell Windows to
    re-schedule the thread, or do I just tell the thread to sleep for some
    period of time, and when it wakes, it will be running on the correct
    processor?

  2. In Dekker’s book, he identifies that ZwSetInformationThread has an
    undocumented ThreadAffinityMask field. Is this setting the affinity for
    the application that is calling it, or for a thread in a multi-threaded
    driver? And, as above, once I set this field, how do I tell Windows to
    reschedule the thread on that processor?

Thanks for any help.
Brian


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

“Brian Franklin” wrote in message news:xxxxx@ntdev…
>
> I have a couple of questions regarding processor affinity. (I am
> specificly writing my driver for a WinXP system, but I would hope that
> this wouldn’t change much from Win2K.)
>

Here you go. The call to ZwSetInformationThread actually does the
reschedule. Required def’ns are all in NTDDK.H (at least… haven’t checked
wdm.h). This code is ANCIENT (NT 3.5?) but I can’t imagine any reason it
wouldn’t work…

if ((CpuNumber != KeGetCurrentProcessorNumber()) && (CpuNumber !=
0xffffffff)) {
DbgPrint(“OSRx (T): On wrong processor – changing affinity mask\n”);
DbgPrint(“OSRx (T): Current CPU number:
%d\n”,KeGetCurrentProcessorNumber());

AffinityMask = 1 << CpuNumber;

//
// Call ZwSetInformationThread to set the affinity mask which causes
the
// correct CPU to be selected when it gets scheduled to execute.
//
ZwSetInformationThread(ThreadHandle, ThreadAffinityMask,
&AffinityMask, sizeof(KAFFINITY));

DbgPrint(“OSRx (T): Current CPU number:
%d\n”,KeGetCurrentProcessorNumber());
} else{
DbgPrint(“OSRx (T): Already executing on requested CPU\n”);
}

Peter
OSR

Wow. Thanks. But I have a follow up question.
Would the above code work in an IOCTL where:
The application that is making the call is single threaded and passes as a
parameter the CpuNumber. The driver is also single threaded, and in the
ZwSetInformationThread call, I use the NtCurrentThread() macro to specify
the current single thread.

“Brian Franklin” wrote in message news:xxxxx@ntdev…
>
> Wow. Thanks. But I have a follow up question.
> Would the above code work in an IOCTL where:
> The application that is making the call is single threaded and passes as a
> parameter the CpuNumber. The driver is also single threaded, and in the
> ZwSetInformationThread call, I use the NtCurrentThread() macro to specify
> the current single thread.
>

Yup. BTW, you probably wanna make sure you set the affinity back to the
original thread’s affinity (do a QueryInformationThread) or “none” when
you’re done.

It really IS that easy,

Peter
OSR