Reputation: 23
Before I get to my question, I'll go over what I am currently working with so you have a decent idea of what I've already done/tried.
I have a multithreaded usermode Windows Desktop Application that issues DeviceIOControl calls to a KMDF driver (purely software, no hardware). There are 5 seperate threads that all make the same custom IOCTL call to the driver constantly. This request consists of:
The driver is currently doing this serially, and the main bottleneck in my usermode application is waiting for the memory reads to complete and everything needs to be complete before the scene can be "rendered".
I've reduced the amount of DeviceIOControl requests as much as I can, so now I've been looking into overlapped IO and allowing each thread to send requests asynchronously. My question is if this is even something worth trying, as I do not know if I can use multiple threads in my driver to read from different addresses at the same time.
Upvotes: 1
Views: 1694
Reputation: 33754
at first very important how user mode open file - in synchronous or asynchronous mode ? (FILE_FLAG_OVERLAPPED
for CreateFile
or FILE_SYNCHRONOUS_IO_[NO]NALERT
for ZwOpenFile
or ZwCreateFile
)
if file opened in synchronous mode (FO_SYNCHRONOUS_IO
will be in FILE_OBJECT.Flags
) I/O subsystem serialize all request to file - so it not send new request to your device until previous is finished. with asynchronous file object - no such restriction - request(IRP) will be just send to your device
if you say that
The threads themselves are independent of one another however.
you need open file as asynchronous (with FILE_FLAG_OVERLAPPED
) if threads share single file handle (FILE_OBJECT
) or every thread must separate open own private file on your device. think better shared asynchronous file.
from driver side you must use WdfIoQueueDispatchParallel
queue dispatch type. so just take request (IRP) handle it and complete (how i understand you not send this request to another driver, or put to some another queue)
Essentially what I'm asking is, with overlapped IO, is it the equivalent of one instance of my driver handling each thread or is it still one driver getting a ton of requests from 5 threads and struggling to keep up?
you always have one instance of driver and count of device exactly how many you create it. if you create only one device - and will be only this one device. all files will be opened on this device. all requests (from any process/thread) will be send to this single device instance.
if you use same file for all threads and it will be synchronous file - the I/O subsystem serialize all request to driver - and this is bad for you. clients of your driver (device) must open file as asynchronous (or every client open own private file). from driver side - you need WdfIoQueueDispatchParallel
queue dispatch type because how i understand all request is independent and you not need synchronization between requests
Upvotes: 2
Reputation: 36338
OK, it looks like the most important part of your question is here:
I've been searching far and wide trying to find out what exactly opening a file as overlapped actually changes with respect to how the WDF handles IOCTL requests [...]
It doesn't change anything; all requests to device drivers are asynchronous.
When you perform I/O on a synchronous handle, Windows issues an asynchronous I/O request to the driver on your behalf and waits for it to complete. As far as I know, the driver doesn't even have any way to tell whether the original request was synchronous or overlapped. [Edit: this isn't really true. As RbMm points out in the comments, the kernel does in fact draw a distinction between synchronous and asynchronous I/O, but from a practical standpoint this shouldn't matter to you.]
Anyway, if the driver is currently only running on a single thread, using overlapped I/O won't help. You will have to modify the driver. Conversely, modifying the driver should be sufficient; you probably don't need to change the application. (Exception: I'm not sure whether or not it is legal to use the same synchronous handle simultaneously from multiple threads, so I recommend that each thread open its own handle to the device, at least until you're sure the driver is working as desired.)
I'm not familiar with WDF, but the MSDN entry Dispatching Methods for I/O Requests looks relevant.
Upvotes: 2