Skip to content

Commit 08910ae

Browse files
committed
Implement poll to make select work correctly
Using ftrace, I observed that during the select system call, the kernel invokes do_select → select_poll_one → vfs_poll → file->f_op->poll. However, the kxo device did not implement the poll file operation. In this case, vfs_poll returns a default mask that causes select to assume the file is always ready for I/O, even if a subsequent read would block. This behavior led to user-facing issues in xo-user. For example, attempting to pause (Ctrl+P) or stop (Ctrl+Q) could be delayed or ignored due to the blocking nature of kxo's read when no data is available. I implemented poll support using a wait queue to resolve this problem.
1 parent 04978e7 commit 08910ae

File tree

1 file changed

+14
-1
lines changed

1 file changed

+14
-1
lines changed

main.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <linux/interrupt.h>
66
#include <linux/kfifo.h>
77
#include <linux/module.h>
8+
#include <linux/poll.h>
89
#include <linux/slab.h>
910
#include <linux/sysfs.h>
1011
#include <linux/version.h>
@@ -380,6 +381,18 @@ static void timer_handler(struct timer_list *__timer)
380381
local_irq_enable();
381382
}
382383

384+
static __poll_t kxo_poll(struct file *filp, struct poll_table_struct *wait)
385+
{
386+
__poll_t mask = 0;
387+
388+
poll_wait(filp, &rx_wait, wait);
389+
390+
if (kfifo_len(&rx_fifo))
391+
mask |= EPOLLRDNORM | EPOLLIN;
392+
393+
return mask;
394+
}
395+
383396
static ssize_t kxo_read(struct file *file,
384397
char __user *buf,
385398
size_t count,
@@ -449,7 +462,7 @@ static const struct file_operations kxo_fops = {
449462
.llseek = no_llseek,
450463
.open = kxo_open,
451464
.release = kxo_release,
452-
};
465+
.poll = kxo_poll};
453466

454467
static int __init kxo_init(void)
455468
{

0 commit comments

Comments
 (0)