I frankly would suggest that your kernel module should implement a virtual device for your application to read and write into. Even if "what it actually does" merely involves reading and writing to shared memory, this protocol will provide an explicit method for your driver to remain in-sync with what your app is doing and when it's doing it. Your driver is now "the one who gets the call." So, now, you have your fingers on both the carrying-out of work requests and the issuing of them. It's all now under the same set of code, all of which you have control of. There could be all sorts of possible "race conditions" otherwise, and this conceptual change ought to enable you to quash them all.
I say "virtual device" because that's a generally useful and generally easy-to-digest software handle for any ol' application program to deal with, but of course it's not the only one. And, yeah, maybe the overhead is more than you can afford to incur. So, "it's just a thought," and maybe/maybe-not a good one.
Last edited by sundialsvcs; 06-21-2012 at 08:28 AM.