C 使用“复制到用户”计时器处理程序函数失败,为什么?
如果我在ioctl函数中使用copy_to_user,我可以将数据复制到用户空间,但是如果我将copy_to_user放入超时处理程序函数中,那么copy_to_user将无法成功。为什么?C 使用“复制到用户”计时器处理程序函数失败,为什么?,c,linux-kernel,copy,C,Linux Kernel,Copy,如果我在ioctl函数中使用copy_to_user,我可以将数据复制到用户空间,但是如果我将copy_to_user放入超时处理程序函数中,那么copy_to_user将无法成功。为什么? #include <linux/init.h> ... #define GLOBAL_MEMSIZE 0x1000//4K ... static struct timer_list mytimer; ... typedef struc
#include <linux/init.h>
...
#define GLOBAL_MEMSIZE 0x1000//4K
...
static struct timer_list mytimer;
...
typedef struct globalmem_dev{
struct cdev cdev;
unsigned char mem[GLOBAL_MEMSIZE];
} Glo_dev, *Pglo_dev;
Pglo_dev globalmem_devp;//global pointer
在ioctl函数中,copy_to_用户可以正常工作
/*ioctl*/
static long int globalmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
/*if(copy_to_user((void __user *)arg, globlmem_devp->mem, 8))
{
printk("copy_to_user fial\n");
}*/
setup_timer(&mytimer, timer_func, arg);
mytimer.expires = jiffies + HZ;
add_timer(&mytimer);
return 0;
}
static struct file_operations hello_ops = {
...
};
/*init function*/
static int __init hello_init(void)
{
...
globalmem_devp = kmalloc(sizeof(Glo_dev), GFP_KERNEL);//
if(NULL == globalmem_devp)
{
return -ENOMEM;
}
...
return 0;
}
static void __exit hello_exit(void)
{
...
}
MODULE_LICENSE("GPL");
MODULE_AUTHOR("test");
module_init(hello_init);
module_exit(hello_exit);
copy_to_user将数据复制到当前用户空间进程的内存中,因此它只能用于从该进程调用的某些代码中
中断处理程序可以随时运行,因此可能没有当前进程,或者更糟糕的是,当前进程是其他进程。此外,复制到用户可以睡眠,这在中断处理程序中是不允许的。
/*ioctl*/
static long int globalmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
/*if(copy_to_user((void __user *)arg, globlmem_devp->mem, 8))
{
printk("copy_to_user fial\n");
}*/
setup_timer(&mytimer, timer_func, arg);
mytimer.expires = jiffies + HZ;
add_timer(&mytimer);
return 0;
}
static struct file_operations hello_ops = {
...
};
/*init function*/
static int __init hello_init(void)
{
...
globalmem_devp = kmalloc(sizeof(Glo_dev), GFP_KERNEL);//
if(NULL == globalmem_devp)
{
return -ENOMEM;
}
...
return 0;
}
static void __exit hello_exit(void)
{
...
}
MODULE_LICENSE("GPL");
MODULE_AUTHOR("test");
module_init(hello_init);
module_exit(hello_exit);