Системный вызов без переключения контекста? - PullRequest
6 голосов
/ 16 января 2012

Я просто читал о том, как работает linux в моей OS-книге, когда натолкнулся на это ..

[...] ядро ​​создается в виде одного монолитного двоичного файла. Основной причиной является повышение производительности. Поскольку весь код ядра и структуры данных хранятся в одном адресном пространстве, переключение контекста не требуется, когда процесс вызывает функцию операционной системы или когда доставляется аппаратное прерывание.

Это звучит довольно удивительно для меня, конечно, он должен хранить контекст процесса перед тем, как перейти в режим ядра, чтобы обработать прерывание ... Но хорошо, я куплю это сейчас. На нескольких страницах, описывая контекст планирования процесса, говорилось:

Этот стек используется как системными вызовами, так и прерываниями, происходящими во время выполнения процесса.

«этот стек» - это место, где ядро ​​хранит регистры процесса и тому подобное.

Не является ли это прямым противоречием первой цитате? Я что-то неправильно истолковываю?

Ответы [ 3 ]

5 голосов
/ 16 января 2012

Я думаю, что первая цитата относится к различиям между монолитным ядром и микроядром .

Linux является монолитным, все его компоненты ядра (драйверы устройств, планировщик, менеджер виртуальных машин) работают на ring 0 . Поэтому при выполнении системных вызовов и обработке прерываний переключение контекста не требуется.

Контрастное микроядро, в котором такие компоненты, как драйверы устройств и поставщики IPC, работают в пользовательском пространстве вне кольца 0. Следовательно, эта архитектура требует дополнительных переключений контекста при выполнении системных вызовов (поскольку исполняющий модуль может находиться в пространство пользователя) и обработка прерываний (для передачи прерываний драйверам устройств).

3 голосов
/ 13 ноября 2012

«Переключение контекста» может означать одну из двух важных вещей: (1) переключение из режима пользователя в режим ядра для обработки системного вызова или принудительное переключение в режим ядра для обработки прерывания в стеке прерываний, или (2) переключение на запуск другого пользовательского процесса в пространстве пользователя с переходом к пространству ядра между ними.

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

Так, по крайней мере, вы говорите о 2-3 стеках или местах для хранения «контекста»: аппаратным прерываниям нужен стек уровня ядра, чтобы сказать, к чему возвращаться; вызовы пользовательских методов / подпрограмм используют стандартный стек для достижения этой цели. И т.д.

Исходные ядра Unix - и модель для этой части теперь не так уж и отличается - запускали системные вызовы, как повар быстрого приготовления, обрабатывающий заказы на завтрак: переместите это на плиту, чтобы освободить место для заказа бекона, который только что прибыл, запустить бекон, вернуться к первому заказу. Все в контексте переключения ядра. Не было огромным приложением для мониторинга, которое, вероятно, приводило в бешенство разработчиков программного обеспечения IBM и DEC.

1 голос
/ 09 июля 2016

При выполнении системного вызова в Linux происходит переключение контекста из пространства пользователя в пространство ядра (от ring3 до ring0). У каждого процесса есть связанный стек режимов ядра, который используется системным вызовом. Перед выполнением системного вызова регистры ЦП процесса сохраняются в его стеке пользовательского режима, этот стек отличается от стека режима ядра и является тем, который процесс использует для выполнения в пользовательском пространстве.

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

Вторая кавычка относится к стеку режима ядра, а не к стеку пользовательского режима.

Сказав это, я должен упомянуть оптимизацию Linux, когда не требуется никакого перехода в пространство ядра для выполнения системного вызова, то есть вся обработка, связанная с системным вызовом, выполняется в самом пользовательском пространстве (таким образом, no context switch). vsyscall и VDSO являются такими приемами. Идея, стоящая за ними, довольно проста. Именно для отправки в пользовательское пространство данных, необходимых для выполнения соответствующего системного вызова. Более подробную информацию можно найти в этой статье LWN .

В дополнение к этому, были некоторые исследовательские проекты, в которых все исполнение происходит в одном кольце. Программы пользовательского пространства и код ОС находятся в same ring. Идея состоит в том, чтобы избавиться от накладных расходов на кольцевые выключатели. Microsoft [singularity] [2] OS является одним из таких проектов.

...