when reviewing some old WDM disk filter code on the possibility of KMDF port, I found one nasty thing with KMDF which is maybe a stopper for this task of mine.
Namely: it looks like, for direct IO, KMDF always maps all MDLs by MmGetSystemAddressForMdlSafe, even if it is not required.
System PTEs are a valuable resource, so probably it is really a very bad idea to map all MDLs in the disk IO path. I'm not sure whether the loaded server will run out of system PTEs in this case and start to fail.
- existing WDM logic (to be reproduced with KMDF) splits the request to several sub-requests by IoBuildPartialMdl.
- to reproduce this in KMDF, I need to first get the memory buffer of the master request. There are only 2 ways of doing this:
a) as WDFMEMORY
b) as WdmMdl
- and now, if you will see the KMDF source, you will see that, when you retrieve the incoming direct IO request memory as WDFMEMORY, MmGetSystemAddressForMdlSafe is ALWAYS called for the MDL (which is being wrapped around by FxRequestBuffer and then FxMemory).
- more so. Somewhere in the source there is a comment like (not exactly) "if we will remake the WdfMemoryGetBuffer API and allow it to fail, then we can avoid to do the possibly redundant mapping of the MDL here".
- definitely, since WdfMemoryGetBuffer is not allowed to fail, MmGetSystemAddressForMdlSafe (which can fail) for the MDL-based WDFMEMORY cannot be delayed till WdfMemoryGetBuffer, so it MUST be executed during WDFMEMORY creation, even if the pointer is not needed at all, i.e. this memory object will only be used as a master for splitting.
- OK, but, master-side, I have WdfRequestRetrieveInputWdmMdl. Kinda a solution.
- the things are much worse slave-side. I can use the MDL to create a KMDF slave request in only 2 ways a) using WDF_MEMORY_DESCRIPTOR or b) using WDFMEMORY.
- WDF_MEMORY_DESCRIPTOR is absolutely a great structure, but it cannot do the subdivision of MDL. Its union branch for the "raw MDL" case only has a length in it, not offset.
- OK, so I'm back to WDFMEMORY, with its limitation of always map the MDL.
So the question once more: can I rewrite the WDM IoBuildPartialMdl request splitting logic in KMDF without mapping all MDLs to system PTEs?
If not so - then I would say this is a very serious deficiency of KMDF, which will require do raw WDM IRP handling in this project of mine (losing the sweet stuff like the KMDF IO target).
Is it possible in the future to a) improve WDF_MEMORY_DESCRIPTOR to allow for MasterMdl/Offset/Length parameter block b) allow usage of WDF_MEMORY_DESCRIPTOR not only in SendSynchronously API family, but also in Send and FormatRequest API families?