Provide occurrence of interrupt from kmdf driver to user mode application

“Tim Roberts” wrote in message news:xxxxx@ntdev…
> KeQueryPerformanceCounter is the exact kernel equivalent of
> QueryPerformanceCounter. In fact, the UM version calls the KM version
> to do its job.
>

It doesn’t. RtlQueryPerformanceCounter in usermode has a separate
implementation and doesn’t switch to kernel mode.

//Daniel

“Tim Roberts” wrote in message news:xxxxx@ntdev…
> … The exact mechanism really doesn’t matter. The ISR
> could set an event, which makes the application ready to run,

He cannot call KeSetEvent from a DIRQL so he must schedule a DPC for that.

//Daniel

> 1. the first way is very easy NotificationEvent, or create Named Event in User mode and send it to the

driver.

The second way is unreliable and depends on OS version and whether Fast User Switching is on.

So, create the event in user mode, pass the handle down to the driver in an IOCTL, and then the driver will signal it.

This will result in something more complex then an inverted call - you need an IOCTL anyway.

Also note that, if the driver is KMDF, then it will need EvtIoInCallerContext to properly deref the event handle.

All of this makes the event-based solution just plain ugly, especially with KMDF, while inverted call is trivial in KMDF where you have the queue to pend it.

Also, with event, you cannot distinguish whether it was signaled once or many times. With inverted calls, you can.

Things like WMI events and FltMgr ports are based on inverted calls, and also inverted calls are very popular in Linux and other similar OSes, so the driver will have better portability.

This method is easy, I used it in WIN and it was very effective for me but you should care for some >sync issues.

For lots of sync issues, since you cannot count how many times your HW event have occured.

  1. The second way is to send several request to the driver (they sometimes called post calls) .

“Inverted calls”.

I used this techniche in linux but , it should be Ok for win too.

More so: it is a recommended technique on Win. And, with KMDF, it is next to trivial to implement. Just route these IOCTLs to their dedicated queue, and then, when a HW event occurs, take one from this queue and complete it.

Sometimes you need to cope with the picture when the HW event occurs and there is no IOCTLs in the queue, but not in all scenarios. In some scenarios like “update the UI” it is probably not needed - what is the need of processing the HW event if nobody listens for it?


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

you mean >= win7 ??

reading using rdtsc ?

xp doesnt seem to even have an RtlVersion

C:\WinDDK\7600.16385.1>grep -ir RtlQueryPerformanceCounter *.*
Binary file lib/win7/amd64/ntdll.lib matches
Binary file lib/win7/amd64/ntdllp.lib matches
Binary file lib/win7/i386/ntdll.lib matches
Binary file lib/win7/i386/ntdllp.lib matches
Binary file lib/win7/ia64/ntdll.lib matches
Binary file lib/win7/ia64/ntdllp.lib matches

lkd> .shell -ci “x *!*QueryPer*” grep -i -v imp

3d96057c WININET!QueryPerConnOptions =
7c82fa4e kernel32!QueryPerformanceFrequency =
7c80a4c7 kernel32!QueryPerformanceCounter =
7c90d8ae ntdll!ZwQueryPerformanceCounter =
7c90d8ae ntdll!NtQueryPerformanceCounter =
80650c82 nt!VfQueryPerformanceCounter =
804fea8c nt!ZwQueryPerformanceCounter =
8060e198 nt!NtQueryPerformanceCounter =
8066004a nt!KdpQueryPerformanceCounter =
806d8de0 hal!HalpPmTimerQueryPerfCount =
806d8da0 hal!HalpQueryPerformanceCounter =
806d774c hal!KeQueryPerformanceCounter =
806d68f8 hal!HalpmmTimerQueryPerfCount =
bf8198d2 win32k!EngQueryPerformanceCounter =
bf894481 win32k!EngQueryPerformanceFrequency =
bf978423 win32k!UMPDDrvQueryPerBandInfo =
f676b138 VIDEOPRT!VideoPortQueryPerformanceCounter =

On 12/8/11, xxxxx@resplendence.com wrote:
> “Tim Roberts” wrote in message news:xxxxx@ntdev…
>> KeQueryPerformanceCounter is the exact kernel equivalent of
>> QueryPerformanceCounter. In fact, the UM version calls the KM version
>> to do its job.
>>
>
> It doesn’t. RtlQueryPerformanceCounter in usermode has a separate
> implementation and doesn’t switch to kernel mode.
>
> //Daniel
>
>
>
> —
> 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
>

Yes, on the older OS it used to call into the kernel. But it’s obviously
not a good idea. Calling into the kernel can be very expensive, this can
dramatically impact the results thus defeating its purpose as a reliable
measuring mechanism.

//Daniel

“raj_r” wrote in message news:xxxxx@ntdev…
> you mean >= win7 ??
>
> reading using rdtsc ?
>
> xp doesnt seem to even have an RtlVersion
>
>

xxxxx@resplendence.com wrote:

Yes, on the older OS it used to call into the kernel. But it’s obviously
not a good idea. Calling into the kernel can be very expensive, this can
dramatically impact the results thus defeating its purpose as a reliable
measuring mechanism.

In fairness, this design did make sense way back when. Twentieth
Century NT systems used the motherboard interval timer to get the
performance counter. That required reading from ISA I/O ports from an
extremely slow device. Just reading the registers took between 5 and 10
microseconds, so the overhead of the user/kernel transition was trivial.

Now that we use the cycle counter, the overhead would swamp the
measurement time.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

ok even in win7+ it seems RtlVersion isnt called if TscQpcData Field isnt set

kd> !process 0 0 Explorer.exe
PROCESS 844b22b0 SessionId: 1 Cid: 0510 Peb: 7ffd4000 ParentCid: 04f0
DirBase: 088fb000 ObjectTable: 8a8f1ed8 HandleCount: 603.
Image: explorer.exe

kd> .process /p /r 844b22b0
Implicit process is now 844b22b0
.cache forcedecodeuser done
Loading User Symbols


kd> lm m ntdll*
start end module name
76fa0000 770dc000 ntdll (pdb symbols)
f:\symbols\ntdll.pdb\F0164DA71FAF4765B8F3DB4F2D7650EA2\ntdll.pdb

kd> x ntdll!*Rt*Quer*Perf*Cou*

76ff2441 ntdll!RtlQueryPerformanceCounter =

kd> u 76ff2448 l1

ntdll!RtlQueryPerformanceCounter+0x7:
76ff2448 f605ed02fe7f01 test byte ptr [SharedUserData+0x2ed (7ffe02ed)],1

kd> dt nt!_KUSER_SHARED_DATA -y nt -y tsc 7ffe0000
+0x030 NtSystemRoot : [260] “C:\Windows”
+0x264 NtProductType : 1 ( NtProductWinNt )
+0x26c NtMajorVersion : 6
+0x270 NtMinorVersion : 1
+0x2ed TscQpcData : 0 ‘’
+0x2ed TscQpcEnabled : 0y0
+0x2ed TscQpcSpareFlag : 0y0
+0x2ed TscQpcShift : 0y000000 (0)
+0x2ee TscQpcPad : [2] “”
+0x3b8 TscQpcBias : 0

btw there is a #field_offset(…,…) macro this requires a name and
it returns the byte offset

for example in the disassembly above if i do

?? #FIELD_OFFSET(nt!_KUSER_SHARED_DATA,TscQpcData) windbg will return
0n749 == 0x2ed

is there a reverse macro
ie given struct , byteoffset i get a nearest field returned somewhat
akin to LN ??

On 12/8/11, xxxxx@resplendence.com wrote:
> Yes, on the older OS it used to call into the kernel. But it’s obviously
> not a good idea. Calling into the kernel can be very expensive, this can
> dramatically impact the results thus defeating its purpose as a reliable
> measuring mechanism.
>
> //Daniel
>
>
> “raj_r” wrote in message news:xxxxx@ntdev…
>> you mean >= win7 ??
>>
>> reading using rdtsc ?
>>
>> xp doesnt seem to even have an RtlVersion
>>
>>
>
>
>
> —
> 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
>

Any idea under what conditions this is switched off , if RDTSC is not
available ? On my system the UM version does a quick RDTSC, the kernel
implementation instead reads from some ports, I assume HPET.

//Daniel.

“raj_r” wrote in message news:xxxxx@ntdev…
> ok even in win7+ it seems RtlVersion isnt called if TscQpcData Field isnt
> set

If RDTSC is unsuitable as a measuring source (for example, including but not limited to if RDTSC ticks at a different rate based on the current processor performance state) then a different counter is used. QueryPerformanceCounter will use the best reliable counter available on the platform.

Most modern amd64 and x86 platforms will be able to use RDTSC.

  • S (Msft)

From: xxxxx@lists.osr.com [xxxxx@lists.osr.com] on behalf of xxxxx@resplendence.com [xxxxx@resplendence.com]
Sent: Friday, December 09, 2011 12:15 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Provide occurrence of interrupt from kmdf driver to user mode application

Any idea under what conditions this is switched off , if RDTSC is not
available ? On my system the UM version does a quick RDTSC, the kernel
implementation instead reads from some ports, I assume HPET.

//Daniel.

“raj_r” wrote in message news:xxxxx@ntdev…
> ok even in win7+ it seems RtlVersion isnt called if TscQpcData Field isnt
> set


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

You mean best reliable counter available in usermode, which excludes HPET ?

//Daniel

“Skywing” wrote in message
news:xxxxx@ntdev…
>QueryPerformanceCounter will use the best reliable counter available on
the platform.