При выполнении системного вызова в Linux происходит переключение контекста из пространства пользователя в пространство ядра (от ring3 до ring0). У каждого процесса есть связанный стек режимов ядра, который используется системным вызовом. Перед выполнением системного вызова регистры ЦП процесса сохраняются в его стеке пользовательского режима, этот стек отличается от стека режима ядра и является тем, который процесс использует для выполнения в пользовательском пространстве.
Когда процесс находится в режиме ядра (или в режиме пользователя), вызов функций того же режима не требует переключения контекста. Это то, на что ссылается первая цитата.
Вторая кавычка относится к стеку режима ядра, а не к стеку пользовательского режима.
Сказав это, я должен упомянуть оптимизацию Linux, когда не требуется никакого перехода в пространство ядра для выполнения системного вызова, то есть вся обработка, связанная с системным вызовом, выполняется в самом пользовательском пространстве (таким образом, no context switch
). vsyscall
и VDSO
являются такими приемами. Идея, стоящая за ними, довольно проста. Именно для отправки в пользовательское пространство данных, необходимых для выполнения соответствующего системного вызова. Более подробную информацию можно найти в этой статье LWN .
В дополнение к этому, были некоторые исследовательские проекты, в которых все исполнение происходит в одном кольце. Программы пользовательского пространства и код ОС находятся в same ring
. Идея состоит в том, чтобы избавиться от накладных расходов на кольцевые выключатели. Microsoft [singularity] [2] OS является одним из таких проектов.