В чем разница между не вытесняющими и вытесняющими ядрами при переходе в режим пользователя?
Я читаю "Понимание ядра Linux, 3-е издание", а в главе 5, раздел "Преобразование ядра", говорится:
Все переключатели процесса выполняются
switch_to
макро. Как в вытесняющих, так и в не вытесняющих ядрах переключение процессов происходит, когда процесс завершил какой-то поток активности ядра и вызван планировщик. Однако в невыдвижных ядрах текущий процесс не может быть заменен, если он не собирается переключаться в режим пользователя.
Я до сих пор не вижу здесь различий между не вытесняющими и вытесняющими ядрами, потому что в любом случае вам нужно ждать, пока текущий процесс переключится в режим пользователя.
Скажем, есть процесс p, работающий в режиме ядра, и чей квант времени истекает, тогда scheduler_tick()
называется, и это устанавливает NEED_RESCHED
флаг р. Но schedule()
вызывается только когда p переключается в пользовательский режим (верно?).
Так что, если p никогда не переключается в режим пользователя?
И если он переключился в режим пользователя, но это занимает "долгое" время между моментами scheduler_tick()
задавать NEED_RESCHED
и момент р фактически переключился в режим пользователя - тогда он использовал больше, чем его квант?
2 ответа
В не вытесняющем ядре schedule()
вызывается при возврате в пользовательское пространство (и везде, где блокируется системный вызов, также в задаче бездействия).
В вытесняющем ядре schedule()
также вызывается при возврате из любого прерывания, а также в нескольких других местах, например mutex_unlock()
медленный путь, при определенных условиях при получении сетевых пакетов,...
В качестве примера представим процесс A, который выдает системный вызов, который прерывается сгенерированным устройством прерыванием, которое затем прерывается прерыванием по таймеру:
process A userspace → process A kernelspace → device ISR → timer ISR
syscall device IRQ timer IRQ
Когда таймер ISR заканчивается, он возвращается к другому ISR, который затем возвращается в пространство ядра, которое затем возвращается в пространство пользователя. Упреждающее ядро проверяет, нужно ли перепланировать процессы при каждом возврате. Ядро без вытеснения проверяет это только при возврате в пользовательское пространство.
Есть два способа переключения процессов:
- Процесс дает процессор; или же
- Операционная система говорит процессу "все готово".
Первое происходит, когда процесс выполняет какое-либо действие, которое не позволяет ему продолжаться. Например, выполняет функцию типа SLEEP или выполняет ввод-вывод (например, на диск или на терминал и должен ждать ответа пользователя).
Второе происходит, когда внутренний таймер операционной системы отключается и как часть обработки прерывания таймера, O/S определяет, что должен выполняться другой процесс.
Ядро, которое обрабатывает только первый тип переключения контекста, не является вытесняющим. Ядро, которое обрабатывает оба типа переключений контекста, является преимущественным.
Обратите внимание, что сдача требует выполнения системной службы. Это требует запуска исключения для вызова обработчика системной службы режима ядра.
Вытеснение требовало прерывания. В большинстве систем, не принадлежащих Intel, исключения и прерывания обрабатываются одинаково (Intel предлагает несколько способов создания исключений). В большинстве систем процесс возврата из прерывания и исключения одинаков.
Переключение контекста в обоих случаях происходит ДО того, как процесс вернется в режим пользователя. Когда процесс возобновляет выполнение, первым делом возвращается из режима ядра в режим пользователя.
Однако в невыдвижных ядрах текущий процесс не может быть заменен, если он не собирается переключаться в режим пользователя.
Это качественное утверждение. Обычная последовательность урожая:
- Исключение триггера
- Войдите в режим ядра
- Отправка в системный сервисный обработчик
- Делать вещи
- Скажите O/S, чтобы уступить. Переключение контекста
- Происходит какое-то событие, сообщающее O/S, что процесс может быть запущен снова.
- ОС Возобновляет процесс в режиме ядра.
- Процесс Выходит из режима ядра
- Процесс возобновляется в веселом режиме в пользовательском режиме.
Утверждение книги состоит в том, что между #7 и #8 ничего или очень мало происходит. Обычно это так, но вполне возможно, что системная служба может поставить больше работы там. Просто так не бывает.