Отключение прерываний для синхронизации в коде ядра

#linux #operating-system #synchronization #interrupt

#linux #операционная система #синхронизация #прерывание

Вопрос:

Зачем вам нужно отключать прерывания при синхронизации кода в ядре?

Например, в следующем коде, взятом из функции linux schedule():

 need_resched:
prev = current;
rq = this_rq();

**spin_lock_irq(amp;rq->lock);** //disables interrupts

switch (prev->state) {
case TASK_INTERRUPTIBLE:
    if (unlikely(signal_pending(prev))) {
        prev->state = TASK_RUNNING;
        break;
    }
default:
    deactivate_task(prev, rq);
case TASK_RUNNING:
    ;
}
 

Функция spin_lock_irq() отключает прерывания, но зачем она нужна?
Предположим, я не отключаю прерывания, и возникает прерывание, поэтому я просто справлюсь с этим, вернусь к планировщику и возобновлю то, что я делал.

Комментарии:

1. Ошибка — что делать, если прерывание запрашивает запуск планировщика при выходе?

2. @Martin Какое прерывание вызывает планировщик?

3. Любое прерывание, которое должно сделать поток готовым сразу после выхода, например. прерывание сетевого адаптера, которое считывает данные в буфер, ожидаемый потоком с вызовом read() — поток должен быть готов / запущен сразу после завершения прерывания, чтобы он мог работать и обрабатывать данные.

Ответ №1:

Это необходимо, потому что планировщик может быть введен как через программные, так и аппаратные прерывания.

Программные прерывания, например, вызовы sleep() и вызовы связи между потоками (например, семафор, condvar или сигнал события), могут изменить набор запущенных потоков и, следовательно, запросить запуск планировщика. Эти вызовы имеют контекст потока / процесса и происходят всякий раз, когда они обращаются к ядру.

Аппаратные прерывания, например. KB, мышь, диск, сетевой адаптер вызывают запуск драйверов, и драйвер вполне может захотеть изменить набор запущенных потоков, запустив планировщик, например. чтобы подготовить поток, который был заблокирован в ожидании чтения с диска. Аппаратные прерывания не имеют контекста потока / процесса и могут возникать в любое время, пока включены прерывания.

Существуют разделы кода / данных планировщика, которые не являются реентерабельными. Если прерывания не будут временно отключены для этих разделов, начнется хаос, когда планировщик будет прерван аппаратным обеспечением и повторно включен из драйвера.