Очереди ожидания Linux ... имеет ли значение порядок? - PullRequest
0 голосов
/ 25 октября 2018

У меня есть драйвер устройства, где оборудование постоянно передает данные в кольцевой буфер в пространстве ядра.Когда пользователь вызывает read(), данные перемещаются из этого буфера в буфер вызывающего.Прерывание срабатывает, если оборудование заполняет дескриптор DMA (т. Е. Готово больше данных) или если оборудование обнаружило ошибку.В любом случае обработчик прерываний планирует выполнение работы в нижней половине.

В нижней половине выясняется, было ли прерывание вызвано аппаратным сбоем или доступностью данных.В любом случае он устанавливает некоторые флаги, чтобы системный вызов read() знал, что произошло.После установки указанных флагов нижняя половина вызывает wake_up_interruptible(&my_waitqueue);

В системном вызове read() я хочу заблокировать на некоторое время, если в буфере ядра нет данных.Если время ожидания истекло, я просто сообщаю звонящему, что данные недоступны.В результате я вызываю wait_event_interruptible_hrtimeout(my_waitqueue, (error || data_ready), my_timeout); По сути, я блокирую ожидание либо условия ошибки, либо доступности данных.

Мой вопрос касается того, упорядочены ли эти потоки (т. Е. Нижняя половина иread() вызов) имеет значение.В частности, мне интересно, всегда ли wait_event_interruptible_hrtimeout() ждет, когда кто-нибудь разбудит его?Что, если был предыдущий вызов wake_up_interruptible()?

Сказано иначе, я обеспокоен следующим сценарием:

  1. Прерывания из-за аппаратного сбоя.Помните, что передачи в циклический буфер происходят независимо от системного вызова read().
  2. Нижняя половина выполнения, помечает передачу как неудачную и вызывает wake_up_interruptible().Обратите внимание, что поскольку это аппаратный сбой, прерывания больше не будут срабатывать, и мы не будем запускать нижнюю половину снова, пока устройство не будет перезагружено.
  3. Пользовательский процесс хочет получить больше данных и вызывает read().Теперь мы попали в строку кода, содержащую wait_event_interruptible_hrtimeout().Блокируем ли мы ожидание, чтобы проснуться, или очередь ожидания знает о предыдущем вызове на wake_up_interruptible()?

В основном мне интересно, нужно ли мне сначала проверить условие, которое я передал в wait_event_interruptible_hrtimeout()(т.е. (error || data_ready)) перед вызовом wait_event_interruptible_hrtimeout().

1 Ответ

0 голосов
/ 26 октября 2018

Благодаря Цывареву я решил еще немного покопаться в исходном коде ядра.

Вот что я нашел:

#define wait_event_interruptible_hrtimeout(wq, condition, timeout)  \
({                                                                  \
    long __ret = 0;                                                 \
    might_sleep();                                                  \
    if (!(condition))                                               \
        __ret = __wait_event_hrtimeout(wq, condition, timeout,      \
                                       TASK_INTERRUPTIBLE);         \
    __ret;                                                          \
})

Сначала проверяется условие, что означает, чтоесли я получу данные или произойдет сбой оборудования, я не буду блокировать, так как это условие, которое я передаю этой функции.

...