在计时器处理函数中使用copy_to_user失败,为什么?

时间:2016-08-09 07:41:33

标签: 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 struct globalmem_dev{
        struct cdev cdev;
        unsigned char mem[GLOBAL_MEMSIZE];
    } Glo_dev, *Pglo_dev;

    Pglo_dev globalmem_devp;//global pointer

如果我把copy_to_user放在这里,我无法正确地将数据复制到用户

    /*Timeout handler function*/
    static void timer_func(unsigned long data)
    {
        int retc = 0;
        retc = copy_to_user((void __user *)data, globalmem_devp->mem, 8);
        if(retc)
        {
            printk("timer_func------->copy_to_user fail\n");
        }
        mod_timer(&mytimer, jiffies + 2*HZ);

    }


    /*file open function*/
    static int hello_open(struct inode *inode, struct file *file)
    {
        printk("hello open!\n");
        file->private_data = globalmem_devp;
        return 0;
    }
    /*file close function*/
    static int hello_release(struct inode *inode, struct file *file)
    {

        del_timer_sync(&mytimer);
        printk("hello closed\n");
        return 0;

    } 

copy_to_user在ioctl函数中正常工作

    /*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);

1 个答案:

答案 0 :(得分:4)

copy_to_user()将数据复制到当前用户空间进程的内存中,因此只能在从此类进程调用的某些代码中使用它。

中断处理程序可以随时运行,因此可能没有当前进程,或者更糟糕的是,当前进程是其他进程。