I was trying to read a loopback device that I have created through a kernel module in periods of 200ms, but it is crashing the kernel, when I try to insert it.
I think there is problem with my read module, but it works fine without timer.
I am new to kernel programming,please help. Thank you in advance:D
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/timer.h>
#include<linux/fs.h>
#include <linux/init.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
#include <linux/buffer_head.h>
static struct timer_list my_timer;
static void read_file(char *filename)
{
struct file *fd;
char buf[1];
unsigned long long offset=0;
mm_segment_t old_fs = get_fs();
set_fs(KERNEL_DS);
fd = filp_open(filename, O_RDONLY, 0);
if (fd >= 0) {
printk(KERN_DEBUG);
while (vfs_read(fd, buf, 1,&offset) == 1)
{
if((0 <= buf[0]) && (buf[0] <=255))
printk("%c", buf[0]);
}
printk(KERN_ALERT "Loop Ran\n");
filp_close(fd,NULL);
}
set_fs(old_fs);
}
void my_timer_callback( unsigned long data )
{
int ret;
printk( "my_timer_callback called (%ld).\n", jiffies );
printk( "Starting timer to fire in 200ms (%ld)\n", jiffies );
read_file("/dev/loop0");
ret = mod_timer( &my_timer, jiffies + msecs_to_jiffies(3000) );
if(ret)
printk("Error in mod_timer\n");
}
int init_module( void )
{
int ret;
printk("Timer module installing\n");
setup_timer( &my_timer, my_timer_callback, 0 );
printk( "Starting timer to fire in 200ms (%ld)\n", jiffies );
ret = mod_timer( &my_timer, jiffies + msecs_to_jiffies(200) );
if(ret)
printk("Error in mod_timer\n");
return 0;
}
void cleanup_module( void )
{
int ret;
ret = del_timer( &my_timer );
if(ret)
printk("The timer is still in use...\n");
printk("Timer module uninstalling\n");
return;
}`enter code here`
MODULE_LICENSE("GPL");
My Make file:
obj-m := timer2.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Reading files is fairly complex, as there are many corner cases to handle. (What if the VM mappings need to be extended? What if you have to suspend the thread while waiting for the disk? etc.)
This article talks about what you should do instead: http://www.linuxjournal.com/article/8110
Unfortunately, the article gives some sample code for hacking around the problem which gives people hope. But the sample code ONLY works in the context of "user process calls into the kernel". In this case, the kernel can re-use the current user process context, but it's a hack.
In the general case (interrupts, timers, etch), you can't just "grab a random user context" because that will lead to massive problems.
Instead, you should make a user-space process that hands the kernel the data it needs.
Kernel timer functions should be atomic. File operations need a process context. Your crash is due to file operations present in you read operation.
Linux device drivers - chapter 7 should get you going on kernel timers.
来源:https://stackoverflow.com/questions/17391224/polling-a-loop-device-through-a-kernel-module