I need to write some kernel module for my university classes and now I’m trying to understand various kernel mechanisms that I have to use. One of them are wait queues. I wrote a simple module that registers a /proc entry and does some simple logic inside its read function:
DECLARE_WAIT_QUEUE_HEAD(event);
volatile int condvar = 0;
volatile int should_wait = 1;
int simple_read_proc(char *page, char **start, off_t offset, int count, int *eof, void *data) {
printk(KERN_INFO "simple_read_proc from %i\n", current->pid);
if(should_wait == 1) {
printk(KERN_INFO "Waiting in %i\n", current->pid);
should_wait = 0;
wait_event_interruptible(event, condvar == 1);
printk(KERN_INFO "Wait finished in %i\n", current->pid);
condvar = 0;
return sprintf(page, "%s", "The wait has finished!\n");
} else {
printk(KERN_INFO "Waking up in %i\n", current->pid);
condvar = 1;
wake_up_interruptible(&event);
return sprintf(page, "%s", "Woke up the other process!\n");
}
}
This is what happens when I try to run cat twice on the registered /proc file:
First cat process waits for the second one to wake him up. Second cat process does exactly that. Each process prints what it should. So far, everything as planned. But then I look into dmesg and that is what I see:
[11405.484168] Initializing proc_module
[11413.209535] simple_read_proc from 6497
[11413.209543] Waiting in 6497
[11415.498482] simple_read_proc from 6499
[11415.498489] Waking up in 6499
[11415.498507] simple_read_proc from 6499
[11415.498514] Wait finished in 6497
[11415.498518] Waking up in 6499
[11415.498546] simple_read_proc from 6497
[11415.498550] Waking up in 6497
[11415.498554] simple_read_proc from 6497
[11415.498557] Waking up in 6497
[11415.498689] simple_read_proc from 6499
[11415.498694] Waking up in 6499
[11415.498753] simple_read_proc from 6497
[11415.498757] Waking up in 6497
My question is: why the simple_read_proc function was invoked so many times? I thought that this may be because cat invoked read many times, but I checked it with strace and this is not the case – each cat invoked read only once.
I would be grateful for some explanation of this phenomenon.
Look at the comment in
fs/proc/generic.cabout “How to be a proc read function.” Since you are not changingeof, the loop in__proc_file_readwill call yourread_procfunction multiple times.