Виды IPI для архитектуры x86 в Linux - PullRequest
2 голосов
/ 28 мая 2020

Я хотел бы знать, какие типы IPI доступны для x86_64 в Linux. В частности, я хочу узнать о различных обработчиках прерываний для прерываний IPI.

В понимании ядра Linux, 3-е издание Дэниела П. Бове, Марко Чезати https://www.oreilly.com/library/view/understanding-the-linux/0596005652/ch04s06.html перечисляет три типа IPI:

CALL_FUNCTION_VECTOR
RESCHEDULE_VECTOR
INVALIDATE_TLB_VECTOR

Однако в последние ядра, я нахожу комментарий ниже в arch / x86 / include / asm / entry_arch.h.

 * This file is designed to contain the BUILD_INTERRUPT specifications for
 * all of the extra named interrupt vectors used by the architecture.
 * Usually this is the Inter Process Interrupts (IPIs)
 */

/*
 * The following vectors are part of the Linux architecture, there
 * is no hardware IRQ pin equivalent for them, they are triggered
 * through the ICC by us (IPIs)

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/arch/x86/include/asm/entry_arch.h?h=v5.6.15

Может ли кто-нибудь подтвердить, все эти векторы, перечисленные в файле, представляют собой разные типы IPI для x86_64. Для ARM я смог найти единый обработчик - handle_IPI () для всех IPI. Корпус переключателя используется, чтобы узнать, какой IPI.

1 Ответ

3 голосов
/ 30 мая 2020

На x86 любой вектор прерывания может быть запущен IPI, поэтому нет (или нет) назначенного вектора прерывания.

The IPI delivery mode and vector field

На изображении выше показан формат регистра, используемого для отправки IPI, в режиме Fixed используется поле Vector , чтобы целевые ЦП выполняли службу прерывания. процедура, связанная с этим вектором. Это похоже на выполнение инструкции int vector в целях.

Итак, Linux теоретически может напрямую вызывать любое прерывание на любом другом процессоре.
Однако модулям ядра часто требуется запускать функцию на указать c CPU; поэтому Linux имеет набор вспомогательных функций, таких как smp_call_function_single , которые облегчат жизнь программисту.
Эти функции реализованы с помощью механизма, который стоит отдельной главы, теперь я не Я знаю детали, но несложно представить основную идею, лежащую в основе: иметь глобальную очередь функций для выполнения и вектор прерывания, который после вызова выводит элемент из очереди и выполняет его.
Вызывая этот вектор прерывания с IPI Linux может заставить целевые ЦП выполнять данную функцию.

Для этого используются найденные вами векторы прерываний. Вы, вероятно, захотите взглянуть на их 64-битный аналог в entry_64.S и под защитой #ifdef CONFIG_SMP.
acpiinterrupt и acpiinterrupt3 - это просто макросы, которые определяют метку со вторым аргументом, вызовите interrupt_entry с первым аргументом (номер вектора) NOTted и вызовите функцию, указанную в третьем аргументе.
Будьте осторожны, 32-битный аналог выполняет некоторую неприятную префиксную конкатенацию с целью имя функции.

apicinterrupt CALL_FUNCTION_SINGLE_VECTOR call_function_single_interrupt smp_call_function_single_interrupt примерно эквивалентно определению функции:

;Metadata stuff (e.g. section placement)

call_function_single_interrupt:               ;<-- first arg
  push ~CALL_FUNCTION_SINGLE_VECTOR           ;<-- second arg
  call interrupt_entry

  ;other stuff (tracing, flags, etc)
  call smp_call_function_single_interrupt     ;<-- third arg

  ;other stuff (like above, plus returning)

Числа векторов определены в irq_vectors.h и, конечно же, также используется в idt. c для IDT.

Целевые функции (обработчики прерываний) в основном (все? Я не проверял) определены в smp. c и они, вероятно, наиболее близки к обработчику handle_IPI ARM.

Кажется, это единственные векторы, вызываемые через IPI.

...