0

I am working on a kernel driver which logs some spi data in a virtual file using debugfs.

My main goal is to be able to "listen" for incomming data from userspace using for example $ tail -f /sys/kernel/debug/spi-logs which is using select to wait for new data on the debugfs file.

I've implemented the fops poll function in the driver and when I am trying to get the data from the userspace, the poll function is never called even though there is new data available in the kernel to be read.

I assume that the poll function never gets called because the debugfs file never gets actually written.

My question is, is there a way to trigger the poll function from the kernel space when new data is available?

EDIT: Added an example

#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");

Using tail -f /sys/kernel/debug/spi_logs, the poll function never gets called

Mihai
  • 972
  • 2
  • 13
  • 35
  • "I assume that the poll function never gets called because the debugfs file never gets actually written." - No, that assumption is incorrect. A `poll` function is called whenever program uses `select`, `poll`, or similar syscalls. Probably, something wrong with your **code**, e.g. in its `read` function. Please, add your code into the question post, so we will be able to help you. – Tsyvarev Feb 20 '22 at 18:34
  • @Tsyvarev added an example – Mihai Feb 20 '22 at 19:09
  • It is better to use **newline**-terminating strings in `printk` and related functions: otherwise the string could be printed with a great delay. – Tsyvarev Feb 20 '22 at 20:53
  • @Tsyvarev true but that’s not what’s happening here – Mihai Feb 20 '22 at 20:54

1 Answers1

0

Semantic of poll is to return whenever encoded operations (read and/or write) on a file would return without block. In case of read operation, "block" means:

  • If read is called in nonblocking mode (field f_flags of the struct file has flag O_NONBLOCK set), then it returns -EAGAIN.
  • If read is called in blocking mode, then it puts a thread into the waiting state.

As you can see, your read function doesn't follow that convention and returns 0, which means EOF. So the caller has no reason to call poll after that.


Semantic of -f option for tail:

... not stop when end of file is reached, but rather to wait ...

is about the situation, when read returns 0, but the program needs to wait.

As you can see, poll semantic is not suitable for such wait. Instead, such programs use inotify mechanism.

Tsyvarev
  • 60,011
  • 17
  • 110
  • 153