从内核模块通知用户空间

Notify userland from a kernel module

我正在实现一个驱动 GPIO 的内核模块。我为用户区提供了通过 ioctls 对其执行操作的可能性,但我想更深入地设置一个 "notification" 系统,其中内核模块将在检测到的事件上直接联系用户区。例如,GPIO 上的值更改(已通过内核模块中的中断通知)。

主要目的是避免用户态中的主动轮询循环,我真的不知道如何连接内核模块和用户态以保持速度、效率和或多或少的被动。

在这种情况下,我找不到任何好的做法。有些人谈论拥有字符界面(通过 /dev 中的文件)并从用户空间执行阻塞 read(),因此在读取 returns.

时得到通知

这个方法应该足够好,但是如果 GPIO 值变化非常快,用户空间可能会太慢而无法处理一个通知,最终会被它无法处理的大量通知压垮。

所以我正在寻找一种方法,如用户态回调函数,可以在事件发生时从内核模块调用。

你们认为最好的解决方案是什么?有解决这个具体问题的现有方法吗?

谢谢:)

从内核调用用户空间当然是可能的,例如生成用户空间进程(考虑内核启动 initudev 等)或使用 IPC(netlink 等)。

然而,这不是你想要的。

正如人们向您提到的那样,要走的路是拥有一个字符设备,然后使用标准和众所周知的 select/poll 语义。我不认为你应该担心这会很慢,假设你的用户空间程序设计得很好。

事实上,这种设计非常普遍,以至于有一个名为 UIO 或 Userspace I/O 的现有框架(参见 here and here)。

抱歉,我不知道您是否可以从内核 space 调用用户态回调,但您可以让您的用户 space 应用程序监听不同的信号,例如 SIGKILL、SIGTERM等,您可以从内核 space.

发送给用户 space 进程

还有SIGUSR1和SIGUSR2,留给自定义use/implementation。您的应用程序可以监听 SIGUSR1 and/or SIGUSR2。然后你只需要检查,你为什么被通知。

我知道,这不是您想要的,但也许有点帮助。 ;)

我终于换了别的东西,因为生成用户态进程太慢而且很可能出错。

我改变了我的软件设计,让用户空间调用 ioctl 来获取最后的事件。 ioctl 通过等待队列阻塞,在事件队列为空时休眠。

谢谢大家的回答!