Применяется ли привязка ЦП к системным вызовам?

Итак, если я установлю привязку процессора к процессу, используя:

sched_setaffinity()

а затем выполнить какой-либо другой системный вызов, используя этот процесс, гарантируется ли ТАКЖЕ выполнение этого системного вызова на том же ЦП, что и sched_setaffinity?

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

Спасибо!


person Roguebantha    schedule 14.04.2020    source источник
comment
Вероятно, это зависит от системного вызова. Например, чтение из файла или сокета заблокирует процесс, если ничего не буферизовано. Когда данные поступают с диска или из сети, прерывание будет обрабатываться любым доступным процессором, не обязательно тем, который ожидает данных.   -  person Barmar    schedule 15.04.2020
comment
Я согласен, что при нормальных обстоятельствах это было бы абсолютно верно. Мне любопытно, остается ли это верным после sched_setaffinity, или существует ли способ принудительного выполнения потока ядра, обрабатывающего прерывание, на том же процессоре, на котором выполняется аффинитизированный процесс.   -  person Roguebantha    schedule 15.04.2020
comment
Как он узнает, что прерывание связано с запросом на чтение от этого процесса, пока он не обработает данные? Диск и сетевая карта ничего не знают о процессах.   -  person Barmar    schedule 15.04.2020
comment
есть ли метод принудительного выполнения потока ядра, обрабатывающего прерывание, на том же ЦП, на котором выполняется аффинитизированный процесс - это не имеет особого смысла, обработчики прерываний не заботятся о процессах пользовательского пространства или даже взаимодействовать с ними вообще.   -  person Marco Bonelli    schedule 15.04.2020


Ответы (1)


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

Задача может быть вытеснена планировщиком и перемещена на другой ЦП, и это может произойти в середине кода обычного пользовательского режима или даже в середине системного вызова.

Установив привязку задачи к одному процессору с помощью sched_setaffinity(), вы устраните эту возможность, поскольку даже если задача будет вытеснена, у планировщика нет другого выбора, кроме как оставить ее на том же процессоре (конечно, он может изменить текущую выполняемую задачу, но когда ваша задача возобновится, она все равно будет на том же процессоре).

Итак, чтобы ответить на ваш вопрос:

Применяет ли тот же системный вызов код пространства ядра в этом контексте процесса, который также будет выполняться на том же ядре?

Да, это так.


Теперь, чтобы обратиться к комментарию @Barmar: в случае системных вызовов, которые могут "спать", это не означает, что задача может изменить ЦП, если сходство не позволяет этого.

Что происходит, когда системный вызов спит, так это то, что код системного вызова сообщает планировщику: «Эй, я чего-то жду, просто запусти другую задачу, пока я жду, и разбуди меня позже». Когда системный вызов возобновляется, он проверяет, доступен ли запрошенный ресурс (он может даже точно сообщить ядру, когда его нужно разбудить), и если нет, то либо ждет снова, либо возвращается к пользовательскому коду, говоря: "Извините, у меня ничего не получилось, попробуйте еще раз". Ресурс, конечно, может быть сделан доступным некоторым прерыванием, которое заставляет обработчик прерывания работать на другом процессоре, но это другая история, и это не имеет большого значения. Проще говоря: код прерывания вообще не запускается в контексте процесса. Что касается задачи, выполняющей системный вызов, ресурс просто волшебным образом появляется, когда выполнение возобновляется.

person Marco Bonelli    schedule 15.04.2020
comment
Отлично, спасибо, Марко, я верю, что это отвечает на мой вопрос. Я понимаю, что генерация этого прерывания на каком-то уровне просто поднимает ЦП до уровня Ring 0, одновременно перемещая ПК и SP в стек ядра — имело бы смысл, если бы все это происходило на одном ЦП. Но я хотел проверить, чтобы подтвердить. - person Roguebantha; 15.04.2020