我正在开发一个内核驱动程序,它使用调试器将一些spi数据记录在虚拟文件中。
我的主要目标是能够“监听”用户空间中的数据,例如使用$ tail -f /sys/kernel/debug/spi-logs,它使用select等待调试器文件上的新数据。
我在驱动程序中实现了fops轮询函数,当我试图从用户空间获取数据时,即使内核中有可读取的新数据,也不会调用轮询函数。
我假设投票函数永远不会被调用,因为调试器文件从未真正被写入。
我的问题是,当有新数据可用时,是否有一种方法可以从内核空间触发轮询函数?
编辑:添加了一个示例
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/debugfs.h>
#include <linux/wait.h>
#include <linux/poll.h>
struct module_ctx {
struct wait_queue_head wq;
};
struct module_ctx module_ctx;
static ssize_t debugfs_read(struct file *filp, char __user *buff, size_t count, loff_t *off)
{
// simulate no data left to read for now
return 0;
}
static __poll_t debugfs_poll(struct file *filp, struct poll_table_struct *wait) {
struct module_ctx *module_hdl;
__poll_t mask = 0;
module_hdl = filp->f_path.dentry->d_inode->i_private;
pr_info("CALLED!!!");
poll_wait(filp, &module_hdl->wq, wait);
if (is_data_available_from_an_external_ring_buffer())
mask |= POLLIN | POLLRDNORM;
return mask;
}
loff_t debugfs_llseek(struct file *filp, loff_t offset, int orig)
{
loff_t pos = filp->f_pos;
switch (orig) {
case SEEK_SET:
pos = offset;
break;
case SEEK_CUR:
pos += offset;
break;
case SEEK_END:
pos = 0; /* Going to the end => to the beginning */
break;
default:
return -EINVAL;
}
filp->f_pos = pos;
return pos;
}
static const struct file_operations debugfs_fops = {
.owner = THIS_MODULE,
.read = debugfs_read,
.poll = debugfs_poll,
.llseek = debugfs_llseek,
};
static int __init rb_example_init(void)
{
struct dentry *file;
init_waitqueue_head(&module_ctx.wq);
file = debugfs_create_file("spi_logs", 0666, NULL, &module_ctx,
&debugfs_fops);
if (!file) {
pr_err("qm35: failed to create /sys/kernel/debug/spi_logs\n");
return 1;
}
return 0;
}
static void __exit
rb_example_exit(void) {
}
module_init(rb_example_init);
module_exit(rb_example_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mihai Pop");
MODULE_DESCRIPTION("A simple example Linux module.");
MODULE_VERSION("0.01");使用tail -f /sys/kernel/debug/spi_logs,轮询函数永远不会被调用
发布于 2022-02-20 21:32:14
poll的语义是在文件上的编码操作(read和/或write)不需要块而返回时返回。在read操作中,“块”是指:
如果在非阻塞模式下调用-EAGAIN.
struct file的字段f_flags有标志O_NONBLOCK集),则返回以阻塞模式调用的read read,然后将线程置于等待状态。如您所见,您的read函数不遵循该约定并返回0,这意味着EOF。因此,调用者没有理由在此之后调用poll。
-f选项在tail中的语义
...当到达文件结束时,不是停止,而是等待.
是关于当read返回0时的情况,但是程序需要等待。
正如您所看到的,poll语义不适合这样的等待。相反,这样的程序使用inotify机制。
https://stackoverflow.com/questions/71196334
复制相似问题