How correctly wake up process inside interrupt handlers

假装没事ソ 提交于 2021-02-10 07:12:27

问题


Briefly, in a read method i check if a variable is 0 and if it's i put the current process to sleep:

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;
    }
    ...
 }

I must wake up the process in an interrupt handler:

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;
}

I think (and also verified) that here could be a problem of atomicity. What happen if interrupt comes between if (soc2e->bytes == 0) in read method and the call to wait_event_interruptible. Maybe the process won't be waked up until next interrupt. What is the best way to resolve this issue?


回答1:


The wait_event_interruptible macro is already pretty careful about avoiding the race you describe. In fact, you don't need the initial check of your bytes member -- you could just write in your read method:

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

because wait_event_interruptible() will not actually go to sleep if the condition is true (or becomes true while it's in the middle of going to sleep).



来源:https://stackoverflow.com/questions/9809140/how-correctly-wake-up-process-inside-interrupt-handlers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!