Reputation: 355
I'm implementing a kernel module that drives GPIOs. I offer the possibility for the userland to perform actions on it via ioctls, but I'd like to get deeper and set up a "notification" system, where the kernel module will contact directly userland on a detected event. For example, a value change on a GPIO (already notified by interrupt in the kernel module).
The main purpose is to avoid active polling loops in userland, and I really don't know how to interface kernel module and userland to keep speed, efficiency, and more or less passive.
I can't find anything on a good practice in this case. Some people talk about having a character interface (via a file in /dev) and performing a blocking read() from userland, and so get notified when the read returns.
This method should be good enough, but in case of very fast GPIO value changes, the userland would maybe be too slow to handle a notification and finally would be crushed by tons of notifications it can't handle.
So I'm looking for a method like userland callback functions, that could be called from the kernel module on an event.
What do you guys think is the best solution ? Is there any existing way of solving this specific problem ?
Thank you :)
Upvotes: 1
Views: 2097
Reputation: 355
I finally changed for something else, as spawning userland processes was far too slow and error likely.
I changed my software design to make the userland call an ioctl to get last events. The ioctl is blocking via wait queues, sleeping while the event queue is empty.
Thanks for your answer guys !
Upvotes: 0
Reputation: 90
I'm sorry, I don't know if you could call userland callbacks from kernel space, but you can make your user space application to listen on different signals like SIGKILL, SIGTERM, etc. which you can send to a user space process from kernel space.
There are also SIGUSR1 and SIGUSR2, which are reserved for custom use/implementation. Your application could listen on SIGUSR1 and/or SIGUSR2. Then you only have to check, why you were notified.
I know, it's not exactly what you wanted, but maybe it's a little help. ;)
Upvotes: 0
Reputation: 1057
Calling from the kernel to userspace is certainly possible, for instance spawning a userspace process (consider the kernel launches init
, udev
and some more) or using IPC (netlink and others).
However, this is not what you want.
As people mentioned to you, the way to go is to have a char device and then use standard and well-known select/poll
semantics. I don't think you should be worried about this being slow, assuming your userspace program is well-designed.
In fact, this design is so common that there is an existing framework called UIO or Userspace I/O (see here and here).
Upvotes: 2