日期:2014-05-16  浏览次数:20966 次

内核自旋锁spin_lock,获取已锁住的锁时Linux死机
写了一个驱动程序,read/write函数实现如下,number是一个全局变量,读/写该变量之前都加上锁。程序大意是为了保证每次读完了才能继续写或者每次写结束以后才能继续读,但是我为了测试并发,在读函数中增加了一个10秒的延时,先执行一个程序A去读,在这段读延时期间,打开终端再运行一个应用程序B,调用write函数。

按我的理解,实现现象是这样的:由于进程A处在延时期间,还没有解锁,那么进程B应该会阻塞在那里不停“自旋”,等到10秒延时结束,A进程放开自旋锁,B进程才可以继续写……但实际情况是一执行B,整个Linux就死掉了……要重启才行。我想问下这是为什么?
C/C++ code

ssize_t my_read(struct file *flip,char __user *buff,size_t cnt,loff_t *off_t)
{
    spin_lock_irqsave(&my_spinlock,flag);
        /* 变量number是要保护的数据*/
    if(copy_to_user(buff,&number,sizeof(int)))
    {
        spin_unlock_irqrestore(&my_spinlock,flag);
        return -EFAULT;
    }
    /*延时10秒,为并发创造条件*/
        ssleep(10);
    spin_unlock_irqrestore(&my_spinlock,flag);
    return 0;
}
ssize_t my_write(struct file *flip,const char __user *buff,size_t cnt,loff_t *off_t)
{
    spin_lock_irqsave(&my_spinlock,flag);

    if(copy_from_user(&number,buff,sizeof(int)))
    {
        spin_unlock_irqrestore(&my_spinlock,flag);
        return -EFAULT;
    }
    spin_unlock_irqrestore(&my_spinlock,flag);
    return 0;
}




------解决方案--------------------
在原子上下文中(中断上下文、持有自旋锁的上下文)不能睡眠,否则有可能导致死锁