Как правильно разбудить процесс внутри обработчиков прерываний - PullRequest
2 голосов
/ 21 марта 2012

Вкратце, в методе 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) в read методе и вызовом wait_event_interruptible.Возможно, процесс не проснется до следующего прерывания.Как лучше всего решить эту проблему?

1 Ответ

3 голосов
/ 22 марта 2012

Макрос wait_event_interruptible уже довольно осторожен, чтобы избежать гонки, которую вы описываете. На самом деле, вам не нужна первоначальная проверка вашего bytes участника - вы можете просто написать в вашем read методе:

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

потому что wait_event_interruptible() на самом деле не будет спать, если условие истинно (или становится истинным, когда он находится в середине сна).

...