mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-23 02:05:57 +01:00
poll kernel module: overhaul with prints everywhere
This commit is contained in:
@@ -3,8 +3,7 @@
|
||||
* Adapted from: https://github.com/torvalds/linux/blob/v4.17/samples/kprobes/kprobe_example.c
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTE: This example is works on x86 and powerpc.
|
||||
/* NOTE: This example is works on x86 and powerpc.
|
||||
* Here's a sample kernel module showing the use of kprobes to dump a
|
||||
* stack trace and selected registers when _do_fork() is called.
|
||||
*
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
#include <linux/seq_file.h> /* seq_read, seq_lseek, single_release */
|
||||
#include <uapi/linux/stat.h> /* S_IRUSR | S_IWUSR */
|
||||
|
||||
static u32 i = 0;
|
||||
static u32 j = 0;
|
||||
static int i = 0;
|
||||
static int j = 0;
|
||||
module_param(i, int, S_IRUSR | S_IWUSR);
|
||||
module_param(j, int, S_IRUSR | S_IWUSR);
|
||||
MODULE_PARM_DESC(i, "my favorite int");
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
#include <linux/wait.h> /* wait_queue_head_t, wait_event_interruptible, wake_up_interruptible */
|
||||
#include <uapi/linux/stat.h> /* S_IRUSR */
|
||||
|
||||
static int ret0 = 0;
|
||||
module_param(ret0, int, S_IRUSR | S_IWUSR);
|
||||
MODULE_PARM_DESC(i, "if 1, always return 0 from poll");
|
||||
|
||||
static char readbuf[1024];
|
||||
static size_t readbuflen;
|
||||
static struct dentry *debugfs_file;
|
||||
@@ -34,24 +38,33 @@ static ssize_t read(struct file *filp, char __user *buf, size_t len, loff_t *off
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* If you return 0 here, then the kernel will sleep until an event happens in the queue.
|
||||
*
|
||||
* This gets called again every time an event happens in the wait queue.
|
||||
*/
|
||||
/* If you return 0 here, then the kernel will sleep until an event
|
||||
* happens in the queue. and then call this again, because of the call to poll_wait. */
|
||||
unsigned int poll(struct file *filp, struct poll_table_struct *wait)
|
||||
{
|
||||
pr_info("poll\n");
|
||||
/* This doesn't sleep. It just makes the kernel call poll again if we return 0. */
|
||||
poll_wait(filp, &waitqueue, wait);
|
||||
if (readbuflen)
|
||||
if (readbuflen && !ret0) {
|
||||
pr_info("return POLLIN\n");
|
||||
return POLLIN;
|
||||
else
|
||||
} else {
|
||||
pr_info("return 0\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int kthread_func(void *data)
|
||||
{
|
||||
while (!kthread_should_stop()) {
|
||||
readbuflen = snprintf(readbuf, sizeof(readbuf), "%llu", (unsigned long long)jiffies);
|
||||
readbuflen = snprintf(
|
||||
readbuf,
|
||||
sizeof(readbuf),
|
||||
"%llu",
|
||||
(unsigned long long)jiffies
|
||||
);
|
||||
usleep_range(1000000, 1000001);
|
||||
pr_info("wake_up\n");
|
||||
wake_up(&waitqueue);
|
||||
}
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user