Method_neither vs method_buffered

Hi folks,

I am trying to create some IOCTLS with method_neither as the mode. I expect that the callers will call in passive level. But if the IOCTL occurs in dispatch level, how will this get handled? Will the state get switched to the passive level before my IOCTL callback gets executed? Or is there a way to ensure that my functions always execute at the passive level? Any penalties in doing so?

Or should i switch to buffered IO? I am trying to make sure that we get performance in whichever way possible and so decided to start with method_neither as the first approach.

thanks,
Venkat

WDM or WDF?

If WDF, any sync scope or execution level constraints?

Kernel-mode caller or user-mode caller?

Peter
OSR

Method_neither should never be the first approach. Are you using KMDF? How are you measuring perf? Do you know where your hot spots are? What size buffers are you transferring?

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@yahoo.com
Sent: Wednesday, September 28, 2011 12:40 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Method_neither vs method_buffered

Hi folks,

I am trying to create some IOCTLS with method_neither as the mode. I expect that the callers will call in passive level. But if the IOCTL occurs in dispatch level, how will this get handled? Will the state get switched to the passive level before my IOCTL callback gets executed? Or is there a way to ensure that my functions always execute at the passive level? Any penalties in doing so?

Or should i switch to buffered IO? I am trying to make sure that we get performance in whichever way possible and so decided to start with method_neither as the first approach.

thanks,
Venkat


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

Have you done measurement yet that shows that buffered I/O is your bottleneck? Or are you just starting out and assuming that this is needed for your driver to be fast?

-p

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@yahoo.com
Sent: Wednesday, September 28, 2011 12:40 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Method_neither vs method_buffered

Hi folks,

I am trying to create some IOCTLS with method_neither as the mode. I expect that the callers will call in passive level. But if the IOCTL occurs in dispatch level, how will this get handled? Will the state get switched to the passive level before my IOCTL callback gets executed? Or is there a way to ensure that my functions always execute at the passive level? Any penalties in doing so?

Or should i switch to buffered IO? I am trying to make sure that we get performance in whichever way possible and so decided to start with method_neither as the first approach.

thanks,
Venkat


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

METHOD_NEITHER is something that should be used only in rare cases for
regular IOCTL’s. To answer your performance question, how much data is
being passed? If it is a 4KB or less use METHOD_BUFFERED, some folks
place the bar higher than that. If it above those limits look at
METHOD_IN_DIRECT or METHOD_OUT_DIRECT.

Don Burn
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

xxxxx@yahoo.com” wrote in message
news:xxxxx@ntdev:

> Hi folks,
>
> I am trying to create some IOCTLS with method_neither as the mode. I expect that the callers will call in passive level. But if the IOCTL occurs in dispatch level, how will this get handled? Will the state get switched to the passive level before my IOCTL callback gets executed? Or is there a way to ensure that my functions always execute at the passive level? Any penalties in doing so?
>
> Or should i switch to buffered IO? I am trying to make sure that we get performance in whichever way possible and so decided to start with method_neither as the first approach.
>
> thanks,
> Venkat

I am just starting out, and basing my design based on what i read. Looked like method_neither was simple but dangerous.

This is a WDF driver and the sync scope for the IO_QUEUE is set to WDFDevice object. Also the clients are expected to be kernel mode callers only, though we won’t really police it (can we?).

Also speaking of performance, is KeQueryPerformanceCounter is the only way to measure time taken for the IOCTLs or is there a better/elegant way to measure performance?

thanks

>level. But if the IOCTL occurs in dispatch level, how will this get handled?

How? user mode cannot run on DISPATCH.

So, this should be an IRP sent from another kernel-mode party, and, in this case, neither or buffered method are just plain the same - just use another pointer in the IRP.

Actually, neither IO is usually only used by the Cache Manager’s clients.


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

>Also the clients are expected to be kernel mode callers only, though we won’t really police it (can we?).

You can. Irp->RequestorMode must be KernelMode.

What are the kernel mode callers do? ZwDeviceIoControlFile? or IoAllocateIrp + submitting? in the latter case, the buffering in METHOD_BUFFERED will not occur, you will just get the IRP with some pointers, so in this case it is a moot point to decide between buffered/neither.


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

xxxxx@yahoo.com wrote:

I am just starting out, and basing my design based on what i read. Looked like method_neither was simple but dangerous.

This is a WDF driver and the sync scope for the IO_QUEUE is set to WDFDevice object. Also the clients are expected to be kernel mode callers only, though we won’t really police it (can we?).

Well, if your callers are all kernel mode, then the method is
irrelevant. The automatic buffered and direct management stuff gets
applied at the user/kernel boundary.

You CAN police it, actually. User mode clients always send
IRP_MJ_DEVICE_CONTROL, but kernel clients can send any IRP, including
IRP_MJ_INTERNAL_DEVICE_CONTROL. If you implement that, user-mode
clients can’t get in. And in that case, you can use the other parameter
words however you want. It’s a private communication.

Also speaking of performance, is KeQueryPerformanceCounter is the only way to measure time taken for the IOCTLs or is there a better/elegant way to measure performance?

There are other ways, but KQPC has finer resolution than the other
choices. If you need sub-millisecond timing, it’s probably the one you
want.


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

As Mr. Roberts said, use IRP_MJ_INTERNAL_DEVICE_CONTROL and you’ll be assured that you’ll only have kernel-mode requestors.

If you’re callers are all kernel-mode, METHOD_NEITHER makes perfect sense. You’re all in the same address space, so… no worries.

No, regarding DISPATCH_LEVEL… it’s perfectly OK for your caller to call IoCallDriver at IRQL DISPATCH_LEVEL. Then the Framework will take care of the rest. Your EvtIoInternalDeviceControl event processing callback will be called at IRQL DISPATCH_LEVEL in any case, given that you’ve specified a sync scope and no execution level constraint.

SO… bottom line… no problem.

Peter
OSR

Nice. I mis-understood IRP_MJ_INTERNAL_DEVICE_CONTROL as an ioctl mode for undocumented IOCTLs. So looks like as long as I am in kernel space I can use METHOD_NEITHER. I will try to profile the METHOD_BUFFERED and see if i can live with it as well…

Thanks for the swift responses…

xxxxx@yahoo.com wrote:

Nice. I mis-understood IRP_MJ_INTERNAL_DEVICE_CONTROL as an ioctl mode for undocumented IOCTLs. So looks like as long as I am in kernel space I can use METHOD_NEITHER. I will try to profile the METHOD_BUFFERED and see if i can live with it as well…

Please allow me to reiterate that, if your requests all come from kernel
mode, the method has no meaning. The processing for buffered and direct
I/O all happens at the user/kernel border. For kernel-to-kernel
requests, the method is never checked, and there is no automatic mapping
and/or locking.


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

On the other hand if you use METHOD_BUFFERED, please use it the way the kernel would. Don’t use METHOD_BUFFERED IOCTLs and then stick pointers in weird places in the IRP.

-p

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Thursday, September 29, 2011 10:15 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Method_neither vs method_buffered

xxxxx@yahoo.com wrote:

Nice. I mis-understood IRP_MJ_INTERNAL_DEVICE_CONTROL as an ioctl mode for undocumented IOCTLs. So looks like as long as I am in kernel space I can use METHOD_NEITHER. I will try to profile the METHOD_BUFFERED and see if i can live with it as well…

Please allow me to reiterate that, if your requests all come from kernel mode, the method has no meaning. The processing for buffered and direct I/O all happens at the user/kernel border. For kernel-to-kernel requests, the method is never checked, and there is no automatic mapping and/or locking.


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


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

Thanks for the tips. My IRPs contain only data, no pointers (except ofcourse completionroutine entries that are taken care of by the WDF).

thanks!

To be specific and clear: I’s not really at the user-kernel border. It’s in the system service.

So, if you’re building an IRP and sending it, the method doesn’t matter as Tim has very clearly stated.

If you’re communicating with the target driver using a system service (ZwReadFile or whatever… I don’t know why you’d do this necessarily… and it’s that common… but it’s certainly possible) that WOULD implement the buffering rules.

Peter
OSR

Mine will be published as IRP_MJ_INTERNAL_DEVICE_CONTROL IOCTLs. So can I safely assume that there is no way for the user space apps to interact with my driver?

xxxxx@yahoo.com wrote:

Mine will be published as IRP_MJ_INTERNAL_DEVICE_CONTROL IOCTLs. So can I safely assume that there is no way for the user space apps to interact with my driver?

Correct. Other than opening and closing, user space apps can only
trigger IRP_MJ_READ, IRP_MJ_WRITE, and IRP_MJ_DEVICE_CONTROL.

How will kernel clients get to your driver? There are other protection
mechanisms, as well. You can use a DACL to restrict access. If you
don’t create a driver name or symbolic link, then there’s no easy way
for applications to open your driver in the first place.


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

> I/O all happens at the user/kernel border. For kernel-to-kernel

requests, the method is never checked

For IoAllocateIrp-based ones, yes.

But what about ZwDeviceIoControlFile?


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

>METHOD_BUFFERED IOCTLs and then stick pointers in weird places in the IRP.

For pointers in weird places, MJ_INTERNAL_DEVICE_CONTROL should be used, like it is used in storage, USB and 1394 stacks.


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

>there is no way for the user space apps to interact with my driver?

Yes.

No syscall can send such an IRP. Only IoAllocateIrp or IoBuildXxxRequest can do this.


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