The key idea here is that it
"pokes" the thread, in order to be certain that the thread is not asleep, after first putting a new unit-of-work onto the queue
(if it can). Every (productive) interrupt "wakes up the sleepyhead." It does not create the thread, nor start it: the thread is always out there.
The thread, since it
does operate asynchronously, can take as long as it needs to, to complete any request. (Of course, it must be mindful that it must not monopolize kernel time, since it can't be pre-empted.)
Another strategy that is sometimes used is a "virtual device driver," which actually exposes a
/dev entry (or somesuch ...) that a suitably privileged
user-land daemon can use. The kernel thread hands-off the work to user-land, using ordinary and easy-to-use filesystem semantics.
As always, look through the kernel source tree (and GitHub) for "prior art."
"Somebody out there has
already done this ... I don't need to write this from scratch. I just need to
steal 'borrow it,' then whack on it until it becomes what
I need." (And then, like a good netizen, contribute it back to GitHub ...)