如何正确唤醒中断处理程序中的进程

时间:2012-03-21 16:48:21

标签: linux-kernel linux-device-driver atomic

简单地说,在一个read方法中,我检查一个变量是否为0,如果我将当前进程置于睡眠状态:

static ssize_t soc2e_read(struct file *filp, char __user *buf,
                          size_t count, loff_t * ppos)
{
    ...
    struct soc2e_dev *soc2e = (struct soc2e_dev *)filp->private_data;

    if (soc2e->bytes == 0)
    {
        if (wait_event_interruptible(soc2e->wlist, (soc2e->bytes > 0)))
            return -ERESTARTSYS;
    }
    ...
 }

我必须在中断处理程序中唤醒进程:

static irqreturn_t soc2e_irq_handler(int irq, void *dev)
{
   ...
   struct soc2e_dev *soc2e = dev;
   ...
   soc2e->bytes += read_bytes;

   wake_up_interruptible(&soc2e->wlist);
   return IRQ_HANDLED;
}

我认为(并且还证实)这可能是原子性问题。如果在if (soc2e->bytes == 0)方法readwait_event_interruptible调用之间发生中断,会发生什么情况。也许这个过程在下次中断之前不会被唤醒。解决此问题的最佳方法是什么?

1 个答案:

答案 0 :(得分:3)

wait_event_interruptible宏已经非常小心避免你描述的种族。事实上,您不需要对bytes成员进行初步检查 - 您只需用read方法撰写:

  if (wait_event_interruptible(soc2e->wlist, soc2e->bytes > 0))
          return -ERESTARTSYS;

因为如果条件为真,wait_event_interruptible()实际上不会进入睡眠状态(或者在进入睡眠状态时变为真)。