用于KMDF的多线程DeviceIOControl

时间:2017-02-07 02:50:35

标签: c++ c windows driver kmdf

在我回答我的问题之前,我会回顾一下我目前正在处理的问题,这样你就可以对我已经完成/尝试过的事情有所了解。

我有一个多线程用户模式Windows桌面应用程序,它向KMDF驱动程序发出DeviceIOControl调用(纯软件,没有硬件)。有5个单独的线程,它们不断地向驱动程序进行相同的自定义IOCTL调用。该请求包括:

  1. PsLookupProcessByProcessId以获取从中读取内存的进程。
  2. MmCopyVirtualMemory将请求的内存复制到提供的缓冲区中。
  3. ObDereferenceObject减少引用计数。
  4. 驱动程序目前正在以串行方式执行此操作,并且我的usermode应用程序中的主要瓶颈是等待内存读取完成,所有内容都需要完成才能生成场景"。

    我尽可能地减少了DeviceIOControl请求的数量,所以现在我一直在寻找重叠的IO并允许每个线程异步发送请求。我的问题是,这是否值得尝试,因为我不知道我是否可以在我的驱动程序中使用多个线程同时从不同的地址读取。

2 个答案:

答案 0 :(得分:1)

好的,看起来你问题中最重要的部分就在这里:

  

我一直在广泛搜索,试图找出究竟打开文件的重叠实际上是如何改变WDF处理IOCTL请求的方式[...]

它没有改变任何东西;对设备驱动程序的所有请求都是异步的。

当您在同步句柄上执行I / O时,Windows会代表您向驱动程序发出异步I / O请求,并等待它完成。 据我所知,司机甚至没有办法判断原始请求是同步还是重叠。 [编辑:这不是真的。正如RbMm在评论中指出的那样,内核确实区分了同步和异步I / O,但从实际的角度来看,这对你来说并不重要。]

无论如何,如果驱动程序当前只在单个线程上运行,则使用重叠I / O不会有帮助。您将不得不修改驱动程序。相反,修改驱动程序应该足够了;您可能不需要更改应用程序。 (例外:我不确定从多个线程同时使用同一个同步句柄是否合法,所以我建议每个线程打开自己的设备句柄,至少在你确定之前司机正在按要求工作。)

我不熟悉WDF,但MSDN条目Dispatching Methods for I/O Requests看起来很相关。

答案 1 :(得分:1)

首先非常重要用户模式如何打开文件 - 在同步或异步模式下? (FILE_FLAG_OVERLAPPED CreateFileFILE_SYNCHRONOUS_IO_[NO]NALERTZwOpenFile ZwCreateFile

如果以同步模式打开文件(FO_SYNCHRONOUS_IO将在FILE_OBJECT.Flags中),I / O子系统会将所有请求序列化为文件 - 因此在上一次完成之前,它不会向您的设备发送新请求。使用异步文件对象 - 没有这样的限制 - 请求(IRP)将只发送到您的设备

如果你这么说

  

然而,线程本身彼此独立。

如果线程共享单个文件句柄(FILE_FLAG_OVERLAPPED),或者每个线程必须在设备上分开打开自己的私有文件,则需要将文件作为异步打开(使用FILE_OBJECT)。认为更好的共享异步文件。

从驱动程序端,您必须使用WdfIoQueueDispatchParallel队列调度类型。所以只需要请求(IRP)处理它并完成(我如何理解你不将此请求发送到另一个驱动程序,或放到另一个队列)

  

基本上我要问的是,重叠的IO,就是它   相当于我的驱动程序处理每个线程的一个实例或是它   还有一个驱动程序从5个线程获得大量请求   努力跟上?

您始终拥有一个驱动程序实例,并且设备数量与您创建的数量完全相同。如果您只创建一个设备 - 并且只有这个一个设备。所有文件都将在此设备上打开。所有请求(来自任何进程/线程)都将发送到此单个设备实例。

如果你对所有线程使用相同的文件并且它将是同步文件 - I / O子系统将所有请求序列化到驱动程序 - 这对你不利。您的驱动程序(设备)的客户端必须以异步方式打开文件(或每个客户端打开自己的私有文件)。从驱动程序方面 - 您需要WdfIoQueueDispatchParallel队列调度类型,因为我理解所有请求是独立的,您不需要请求之间的同步