I'm looking for a fast and efficient way for user-space to send I/O to my driver. One way I'd have hoped to do this, was through a shared memory ring-buffer.
In the WWDC19 presentation on System Extensions and DriverKit, at roughly 17:00, they mention an IOSharedDataQueueDispatchSource. This doesn't exist in the DriverKit API. An IODataQueueDispatchSource is available, but doesn't seem to be meant to be shared.
In the old IOKit framework, there are similar IOSharedDataQueue and IODataQueue, but they are unavailable in DriverKit.
So, what are my options for implementing a fast, efficient I/O path to my driver?
The answer seems to be that DriverKit does not provide any functionality for this. So I ended up making my own ring-buffer queue.
In essence, I allocate two buffers in my driver -- a submission and a completion queue -- and share these with my user-space application through CopyClientMemoryForType
. In these buffers I have a head and tail variable and the actual memory for the queue. By atomically advancing head and tail and pushing tasks into the buffer, I can communicate between the two very efficiently. I still do a IOConnectCallStructMethod
to signal when there's new queue entries.
The code can be found here:
https://github.com/OpenMPDK/MacVFN/blob/master/MacVFN/MacVFNShared.h