免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 20535 | 回复: 4
打印 上一主题 下一主题

驱动程序出现scheduling while atomic的提示 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-12-14 21:45 |只看该作者 |倒序浏览
设备结构定义如下:
typedef   struct   smschar_dev
{
    volatile   int   pending_messages; //! <   number   of   pending   messages   for   this   channel
   struct   cdev   cdev; //! <     Char   device   structure   -
   wait_queue_head_t   wtq; //! <   wait   queue   for   read   and   poll   to   block   on
   spinlock_t   lock; //! <   critical   section
   struct   list_head   pending_data; //! <   list   of   pending   data
}CharDev_ST;
在从一个缓冲区读取数据的函数中,代码大概如下
ssize_t   chr_read(struct   file   *   filp,   char   __user   *   buf,   size_t   count,   loff_t   *   f_pos)
{
        CharDev_ST   *dev   =   filp-> private_data;
        spin_lock(&dev-> lock);
      if(wait_event_interruptible(dev-wtq,!list_empty(&dev-> pending_data)))
   {
            spin_unlock(&dev-> lock);
          return   -ERESTARTSYS;
   }
///在这里读取数据
      spin_unlock(&dev-> lock);
}


下面是数据到达时,往该设备的缓冲区填充数据的函数,大概实现过程:


spinlock_t   global_read_ctrl_lock   =   SPIN_LOCK_UNLOCKED;

static   void   fill_buffer(u8*   buf,int   len)
{
        unsigned   long                       flags;
        spin_lock_irqsave(&global_read_ctrl_lock,flags);
        //在这里填充数据
        wake_up_interruptible   (&(pDev-> wtq));
spin_unlock_irqrestore(&global_read_ctrl_lock,flags);
}


        在运行的过程中,内核打印了BUG:   scheduling   while   atomic,的提示,而且每次读取一次数据,就打印一次。我的理解是,内核认为在chr_read函数中,会出现占用了dev-> lock的情况下由于wait_event_interruptible造成睡眠的情况。

        不知各位有没有好的解决这个问题的方法?把内核的“BUG:   scheduling   while   atomic”提示去掉,我尝试把chr_read函数的spin_lock和wait_event_interruptible进行对调,那个打印信息倒是去掉了,但是觉得这样有问题。请各位指点下啊

论坛徽章:
0
2 [报告]
发表于 2007-12-16 11:27 |只看该作者
为什么用自旋锁呢,应该用信号量,down_interruptable和up

论坛徽章:
0
3 [报告]
发表于 2007-12-18 11:23 |只看该作者
遇到同样的问题。目前也没有找出合适的解决方式。
我不明白的是在spin_lock完成之后,原子操作不就结束了吗?为什么还会出现此种BUG呢?

关注中……

论坛徽章:
0
4 [报告]
发表于 2007-12-20 21:31 |只看该作者
系统提示是,在获得锁之后由于wait_up_interutible可能会导致驱动休眠,可能进入死锁的状态。我的解决方法如下:
   spin_lock(&dev-> lock);
      if(wait_event_interruptible(dev-wtq,!list_empty(&dev-> pending_data)))
   {
            spin_unlock(&dev-> lock);
          return   -ERESTARTSYS;
   }
   while(lisg_empty(....))
{
     spin_unlock(...);
     wait_event_interruptible;
    spin_lock(....);
}
或者也可以用信号量,上面的朋友说的

论坛徽章:
0
5 [报告]
发表于 2007-12-21 09:58 |只看该作者
考虑多处理器吗?
否则应该使用down_interruptable和up
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP