Прерывания От Внешних Устройств В Системе X86. Часть 2. Параметры Загрузки Ядра Linux

В предыдущая часть мы рассмотрели эволюцию доставки прерываний от устройств в системах x86 (PIC → APIC → MSI), общую теорию и все необходимые термины.

В этой практической части мы рассмотрим, как откатиться к использованию устаревших методов доставки прерываний в Linux, а именно рассмотрим варианты загрузки ядра:

  • PCI=номси
  • ноапический
  • ноляпический
Мы также рассмотрим порядок, в котором ОС просматривает таблицы маршрутизации прерываний (ACPI/MPtable/$PIR), и какое влияние на нее окажет добавление параметров загрузки:
  • pci=ноакпи
  • acpi=нуарк
  • акпи=выкл.

Возможно, вы пробовали комбинации всех этих вариантов, когда устройство не работало из-за сбоя.

Давайте посмотрим, что именно они делают и как меняют вывод /proc/interrupts.

Скачать без дополнительных опций

В этой статье мы рассмотрим прерывания на специальной плате с процессором Intel Haswell i7 и чипсетом lynxPoint-LP. основная загрузка .

Информацию о прерываниях мы будем отображать через команду

  
  
  
  
  
  
  
  
  
  
  
   

cat /proc/interrupts

Вывод при загрузке без дополнительных опций:

CPU0 CPU1 CPU2 CPU3 0: 15 0 0 0 IO-APIC-edge timer 1: 0 1 0 1 IO-APIC-edge i8042 8: 0 0 0 1 IO-APIC-edge rtc0 9: 0 0 0 0 IO-APIC-fasteoi acpi 12: 0 0 0 1 IO-APIC-edge 23: 16 247 7 10 IO-APIC-fasteoi ehci_hcd:usb1 56: 0 0 0 0 PCI-MSI-edge aerdrv,PCIe PME 57: 0 0 0 0 PCI-MSI-edge aerdrv,PCIe PME 58: 0 0 0 0 PCI-MSI-edge aerdrv,PCIe PME 59: 0 0 0 0 PCI-MSI-edge aerdrv,PCIe PME 60: 0 0 0 0 PCI-MSI-edge aerdrv,PCIe PME 61: 0 0 0 0 PCI-MSI-edge aerdrv,PCIe PME 62: 3118 1984 972 3454 PCI-MSI-edge ahci 63: 1 0 0 0 PCI-MSI-edge eth59 64: 2095 57 4 832 PCI-MSI-edge eth59-rx-0 65: 6 18 1 1309 PCI-MSI-edge eth59-rx-1 66: 13 512 2 1 PCI-MSI-edge eth59-rx-2 67: 10 61 232 2 PCI-MSI-edge eth59-rx-3 68: 169 0 0 0 PCI-MSI-edge eth59-tx-0 69: 14 14 4 205 PCI-MSI-edge eth59-tx-1 70: 11 491 3 0 PCI-MSI-edge eth59-tx-2 71: 20 19 134 50 PCI-MSI-edge eth59-tx-3 72: 0 0 0 0 PCI-MSI-edge eth58 73: 2 1 0 152 PCI-MSI-edge eth58-rx-0 74: 3 150 2 0 PCI-MSI-edge eth58-rx-1 75: 2 34 117 2 PCI-MSI-edge eth58-rx-2 76: 153 0 2 0 PCI-MSI-edge eth58-rx-3 77: 4 0 2 149 PCI-MSI-edge eth58-tx-0 78: 4 149 2 0 PCI-MSI-edge eth58-tx-1 79: 4 0 117 34 PCI-MSI-edge eth58-tx-2 80: 153 0 2 0 PCI-MSI-edge eth58-tx-3 81: 66 106 2 101 PCI-MSI-edge snd_hda_intel 82: 928 5657 262 224 PCI-MSI-edge i915 83: 545 56 32 15 PCI-MSI-edge snd_hda_intel NMI: 0 0 0 0 Non-maskable interrupts LOC: 4193 3644 3326 3499 Local timer interrupts SPU: 0 0 0 0 Spurious interrupts PMI: 0 0 0 0 Performance monitoring interrupts IWI: 290 233 590 111 IRQ work interrupts RTR: 3 0 0 0 APIC ICR read retries RES: 1339 2163 2404 1946 Rescheduling interrupts CAL: 607 537 475 559 Function call interrupts TLB: 163 202 164 251 TLB shootdowns TRM: 48 48 48 48 Thermal event interrupts THR: 0 0 0 0 Threshold APIC interrupts MCE: 0 0 0 0 Machine check exceptions MCP: 3 3 3 3 Machine check polls ERR: 0 MIS: 0

Файл /proc/interrupts содержит таблицу количества прерываний на каждом процессоре в следующем виде:
  • Первый столбец: номер прерывания
  • Столбцы CPUx: счетчики прерываний на каждом процессоре.

  • Следующий столбец: тип прерывания:
    • IO-APIC-edge — прерывание по фронту контроллера APIC ввода-вывода
    • IO-APIC-fasteoi — прерывание уровня контроллера APIC ввода-вывода
    • PCI-MSI-edge — прерывание MSI
    • XT-PIC-XT-PIC — прерывание PIC-контроллера (увидим позже)
  • Последний столбец: устройство, связанное с этим прерыванием.

Итак, как и положено в современной системе, они используются для устройств и драйверов, поддерживающих прерывания MSI/MSI-X. Остальные прерывания маршрутизируются через APIC ввода-вывода.

Упрощенную схему маршрутизации прерываний можно нарисовать так (красным отмечены активные пути, черным — неиспользуемые пути).



Прерывания от внешних устройств в системе x86. Часть 2. Параметры загрузки ядра Linux

Поддержка MSI/MSI-X устройством должна быть обозначена как соответствующая возможность в пространстве конфигурации PCI. Чтобы подтвердить это, мы предоставляем небольшой фрагмент вывода lspci для устройств, которые обозначены как использующие MSI/MSI-X. В нашем случае это SATA-контроллер (прерывание ahci), 2 Ethernet-контроллера (прерывания eth58* и eth59*), графический контроллер (i915) и 2 контроллера HD Audio (snd_hda_intel).



lspci -v



00:02.0 VGA compatible controller: Intel Corporation Haswell-ULT Integrated Graphics Controller (rev 09) (prog-if 00 [VGA controller]) .

Capabilities: [90] MSI: Enable+ Count=1/1 Maskable- 64bit- Capabilities: [d0] Power Management version 2 Capabilities: [a4] PCI Advanced Features Kernel driver in use: i915 00:03.0 Audio device: Intel Corporation Haswell-ULT HD Audio Controller (rev 09 .

Capabilities: [60] MSI: Enable+ Count=1/1 Maskable- 64bit- Capabilities: [70] Express Root Complex Integrated Endpoint, MSI 00 Kernel driver in use: snd_hda_intel 00:1b.0 Audio device: Intel Corporation 8 Series HD Audio Controller (rev 04) .

Capabilities: [60] MSI: Enable+ Count=1/1 Maskable- 64bit+ Capabilities: [70] Express Root Complex Integrated Endpoint, MSI 00 Capabilities: [100] Virtual Channel Kernel driver in use: snd_hda_intel 00:1f.2 SATA controller: Intel Corporation 8 Series SATA Controller 1 [AHCI mode] (rev 04) (prog-if 01 [AHCI 1.0]) .

Capabilities: [80] MSI: Enable+ Count=1/1 Maskable- 64bit- Capabilities: [70] Power Management version 3 Capabilities: [a8] SATA HBA v1.0 Kernel driver in use: ahci 05:00.0 Ethernet controller: Intel Corporation I350 Gigabit Network Connection (rev 01) .

Capabilities: [50] MSI: Enable- Count=1/1 Maskable+ 64bit+ Capabilities: [70] MSI-X: Enable+ Count=10 Masked- Capabilities: [a0] Express Endpoint, MSI 00 Kernel driver in use: igb 05:00.1 Ethernet controller: Intel Corporation I350 Gigabit Network Connection (rev 01) .

Capabilities: [50] MSI: Enable- Count=1/1 Maskable+ 64bit+ Capabilities: [70] MSI-X: Enable+ Count=10 Masked- Capabilities: [a0] Express Endpoint, MSI 00 Kernel driver in use: igb

Как мы видим, на этих устройствах есть строка «MSI: Enable+» или «MSI-X: Enable+».

Начнем деградировать систему.

Во-первых, давайте загрузимся с опцией pci=nomsi.

PCI=номси

С этой опцией MSI прерывания станут IO-APIC/XT-PIC в зависимости от используемого контроллера прерываний.

В данном случае у нас еще есть приоритетный контроллер прерываний APIC, поэтому картина будет такой:

Прерывания от внешних устройств в системе x86. Часть 2. Параметры загрузки ядра Linux

Вывод из /proc/interrupts:

CPU0 CPU1 CPU2 CPU3 0: 15 0 0 0 IO-APIC-edge timer 1: 0 1 0 1 IO-APIC-edge i8042 8: 0 0 1 0 IO-APIC-edge rtc0 9: 0 0 0 0 IO-APIC-fasteoi acpi 12: 0 0 0 1 IO-APIC-edge 16: 1314 5625 342 555 IO-APIC-fasteoi i915, snd_hda_intel, eth59 17: 5 0 1 34 IO-APIC-fasteoi eth58 21: 2882 2558 963 2088 IO-APIC-fasteoi ahci 22: 26 81 2 170 IO-APIC-fasteoi snd_hda_intel 23: 23 369 8 8 IO-APIC-fasteoi ehci_hcd:usb1 NMI: 0 0 0 0 Non-maskable interrupts LOC: 3011 3331 2435 2617 Local timer interrupts SPU: 0 0 0 0 Spurious interrupts PMI: 0 0 0 0 Performance monitoring interrupts IWI: 197 228 544 85 IRQ work interrupts RTR: 3 0 0 0 APIC ICR read retries RES: 1708 2349 1821 1569 Rescheduling interrupts CAL: 520 554 509 555 Function call interrupts TLB: 187 181 205 179 TLB shootdowns TRM: 102 102 102 102 Thermal event interrupts THR: 0 0 0 0 Threshold APIC interrupts MCE: 0 0 0 0 Machine check exceptions MCP: 2 2 2 2 Machine check polls ERR: 0 MIS: 0

Все прерывания MSI/MSI-X исчезли, как и ожидалось.

Вместо этого устройства теперь используют прерывания вида IO-APIC-fasteoi. Обратите внимание, что до того, как эта опция была включена, у eth58 и eth59 было по 9 прерываний! А теперь только по одному.

Ведь, как мы помним, без MSI для одной функции PCI доступно только одно прерывание! Некоторая информация от dmesg по инициализации контроллеров Ethernet: — загрузка без опции pci=nomsi:

igb: Intel(R) Gigabit Ethernet Network Driver - version 5.0.5-k igb: Copyright (c) 2007-2013 Intel Corporation. acpi:acpi_pci_irq_enable: igb 0000:05:00.0: PCI INT A -> GSI 16 (level, low) -> IRQ 16 igb 0000:05:00.0: irq 63 for MSI/MSI-X igb 0000:05:00.0: irq 64 for MSI/MSI-X igb 0000:05:00.0: irq 65 for MSI/MSI-X igb 0000:05:00.0: irq 66 for MSI/MSI-X igb 0000:05:00.0: irq 67 for MSI/MSI-X igb 0000:05:00.0: irq 68 for MSI/MSI-X igb 0000:05:00.0: irq 69 for MSI/MSI-X igb 0000:05:00.0: irq 70 for MSI/MSI-X igb 0000:05:00.0: irq 71 for MSI/MSI-X igb 0000:05:00.0: irq 63 for MSI/MSI-X igb 0000:05:00.0: irq 64 for MSI/MSI-X igb 0000:05:00.0: irq 65 for MSI/MSI-X igb 0000:05:00.0: irq 66 for MSI/MSI-X igb 0000:05:00.0: irq 67 for MSI/MSI-X igb 0000:05:00.0: irq 68 for MSI/MSI-X igb 0000:05:00.0: irq 69 for MSI/MSI-X igb 0000:05:00.0: irq 70 for MSI/MSI-X igb 0000:05:00.0: irq 71 for MSI/MSI-X igb 0000:05:00.0: added PHC on eth0 igb 0000:05:00.0: Intel(R) Gigabit Ethernet Network Connection igb 0000:05:00.0: eth0: (PCIe:5.0Gb/s:Width x1) 00:15:d5:03:00:2a igb 0000:05:00.0: eth0: PBA No: 106300-000 igb 0000:05:00.0: Using MSI-X interrupts. 4 rx queue(s), 4 tx queue(s) acpi:acpi_pci_irq_enable: igb 0000:05:00.1: PCI INT B -> GSI 17 (level, low) -> IRQ 17 igb 0000:05:00.1: irq 72 for MSI/MSI-X igb 0000:05:00.1: irq 73 for MSI/MSI-X igb 0000:05:00.1: irq 74 for MSI/MSI-X igb 0000:05:00.1: irq 75 for MSI/MSI-X igb 0000:05:00.1: irq 76 for MSI/MSI-X igb 0000:05:00.1: irq 77 for MSI/MSI-X igb 0000:05:00.1: irq 78 for MSI/MSI-X igb 0000:05:00.1: irq 79 for MSI/MSI-X igb 0000:05:00.1: irq 80 for MSI/MSI-X igb 0000:05:00.1: irq 72 for MSI/MSI-X igb 0000:05:00.1: irq 73 for MSI/MSI-X igb 0000:05:00.1: irq 74 for MSI/MSI-X igb 0000:05:00.1: irq 75 for MSI/MSI-X igb 0000:05:00.1: irq 76 for MSI/MSI-X igb 0000:05:00.1: irq 77 for MSI/MSI-X igb 0000:05:00.1: irq 78 for MSI/MSI-X igb 0000:05:00.1: irq 79 for MSI/MSI-X igb 0000:05:00.1: irq 80 for MSI/MSI-X igb 0000:05:00.1: added PHC on eth1 igb 0000:05:00.1: Intel(R) Gigabit Ethernet Network Connection igb 0000:05:00.1: eth1: (PCIe:5.0Gb/s:Width x1) 00:15:d5:03:00:2b igb 0000:05:00.1: eth1: PBA No: 106300-000 igb 0000:05:00.1: Using MSI-X interrupts. 4 rx queue(s), 4 tx queue(s)

- загрузка с опцией pci=nomsi

igb: Intel(R) Gigabit Ethernet Network Driver - version 5.0.5-k igb: Copyright (c) 2007-2013 Intel Corporation. acpi:acpi_pci_irq_enable: igb 0000:05:00.0: PCI INT A -> GSI 16 (level, low) -> IRQ 16 igb 0000:05:00.0: added PHC on eth0 igb 0000:05:00.0: Intel(R) Gigabit Ethernet Network Connection igb 0000:05:00.0: eth0: (PCIe:5.0Gb/s:Width x1) 00:15:d5:03:00:2a igb 0000:05:00.0: eth0: PBA No: 106300-000 igb 0000:05:00.0: Using legacy interrupts. 1 rx queue(s), 1 tx queue(s) acpi:acpi_pci_irq_enable: igb 0000:05:00.1: PCI INT B -> GSI 17 (level, low) -> IRQ 17 igb 0000:05:00.1: added PHC on eth1 igb 0000:05:00.1: Intel(R) Gigabit Ethernet Network Connection igb 0000:05:00.1: eth1: (PCIe:5.0Gb/s:Width x1) 00:15:d5:03:00:2b igb 0000:05:00.1: eth1: PBA No: 106300-000 igb 0000:05:00.1: Using legacy interrupts. 1 rx queue(s), 1 tx queue(s)

Из-за уменьшения количества прерываний на одно устройство включение этой опции может привести к существенному ограничению производительности драйверов (при этом не учитывается тот факт, что согласно исследованиям Intel Уменьшение задержки прерывания за счет использования прерываний, сигнализируемых сообщениями прерывания через MSI в 3 раза быстрее, чем через IO-APIC, и в 5 раз быстрее, чем через PIC).



ноапический

Эта опция отключает APIC ввода-вывода.

Прерывания MSI по-прежнему могут поступать на все процессоры, но прерывания устройства могут поступать только на CPU0, поскольку PIC подключен только к CPU0. Но LAPIC работает, и другие процессоры могут работать и обрабатывать прерывания.



Прерывания от внешних устройств в системе x86. Часть 2. Параметры загрузки ядра Linux



CPU0 CPU1 CPU2 CPU3 0: 5 0 0 0 XT-PIC-XT-PIC timer 1: 2 0 0 0 XT-PIC-XT-PIC i8042 2: 0 0 0 0 XT-PIC-XT-PIC cascade 8: 1 0 0 0 XT-PIC-XT-PIC rtc0 9: 0 0 0 0 XT-PIC-XT-PIC acpi 12: 172 0 0 0 XT-PIC-XT-PIC ehci_hcd:usb1 56: 0 0 0 0 PCI-MSI-edge aerdrv, PCIe PME 57: 0 0 0 0 PCI-MSI-edge aerdrv, PCIe PME 58: 0 0 0 0 PCI-MSI-edge aerdrv, PCIe PME 59: 0 0 0 0 PCI-MSI-edge aerdrv, PCIe PME 60: 0 0 0 0 PCI-MSI-edge aerdrv, PCIe PME 61: 0 0 0 0 PCI-MSI-edge aerdrv, PCIe PME 62: 2833 2989 1021 811 PCI-MSI-edge ahci 63: 0 1 0 0 PCI-MSI-edge eth59 64: 301 52 9 3 PCI-MSI-edge eth59-rx-0 65: 12 24 3 178 PCI-MSI-edge eth59-rx-1 66: 14 85 6 2 PCI-MSI-edge eth59-rx-2 67: 17 24 307 1 PCI-MSI-edge eth59-rx-3 68: 70 18 8 10 PCI-MSI-edge eth59-tx-0 69: 7 0 0 23 PCI-MSI-edge eth59-tx-1 70: 15 227 2 2 PCI-MSI-edge eth59-tx-2 71: 18 6 27 2 PCI-MSI-edge eth59-tx-3 72: 0 0 0 0 PCI-MSI-edge eth58 73: 1 0 0 27 PCI-MSI-edge eth58-rx-0 74: 1 22 0 5 PCI-MSI-edge eth58-rx-1 75: 1 0 22 5 PCI-MSI-edge eth58-rx-2 76: 23 0 0 5 PCI-MSI-edge eth58-rx-3 77: 1 0 0 27 PCI-MSI-edge eth58-tx-0 78: 1 22 0 5 PCI-MSI-edge eth58-tx-1 79: 1 0 22 5 PCI-MSI-edge eth58-tx-2 80: 23 0 0 5 PCI-MSI-edge eth58-tx-3 81: 187 17 70 7 PCI-MSI-edge snd_hda_intel 82: 698 1647 247 129 PCI-MSI-edge i915 83: 438 135 16 59 PCI-MSI-edge snd_hda_intel NMI: 0 0 0 0 Non-maskable interrupts LOC: 1975 2499 2245 1474 Local timer interrupts SPU: 0 0 0 0 Spurious interrupts PMI: 0 0 0 0 Performance monitoring interrupts IWI: 132 67 429 91 IRQ work interrupts RTR: 3 0 0 0 APIC ICR read retries RES: 1697 2178 1903 1541 Rescheduling interrupts CAL: 561 496 534 567 Function call interrupts TLB: 229 254 170 137 TLB shootdowns TRM: 78 78 78 78 Thermal event interrupts THR: 0 0 0 0 Threshold APIC interrupts MCE: 0 0 0 0 Machine check exceptions MCP: 2 2 2 2 Machine check polls ERR: 0 MIS: 0

Как видите, все прерывания IO-APIC-* стали XT-PIC-XT-PIC, и эти прерывания направляются только на CPU0. Прерывания MSI остаются неизменными и передаются всем CPU0-3.

ноляпический

Отключает ЛАПИК.

Прерывания MSI не могут работать без LAPIC, APIC ввода-вывода не может работать без LAPIC. Поэтому все прерывания от устройств будут поступать на PIC, а он работает только с CPU0. А без LAPIC остальные CPU в системе даже работать не будут.

Прерывания от внешних устройств в системе x86. Часть 2. Параметры загрузки ядра Linux

Вывод из /proc/interrupts:

CPU0 0: 6416 XT-PIC-XT-PIC timer 1: 2 XT-PIC-XT-PIC i8042 2: 0 XT-PIC-XT-PIC cascade 3: 5067 XT-PIC-XT-PIC aerdrv, aerdrv, PCIe PME, PCIe PME, i915, snd_hda_intel, eth59 4: 32 XT-PIC-XT-PIC aerdrv, aerdrv, PCIe PME, PCIe PME, eth58 5: 0 XT-PIC-XT-PIC aerdrv, PCIe PME 6: 0 XT-PIC-XT-PIC aerdrv, PCIe PME 8: 1 XT-PIC-XT-PIC rtc0 9: 0 XT-PIC-XT-PIC acpi 11: 274 XT-PIC-XT-PIC snd_hda_intel 12: 202 XT-PIC-XT-PIC ehci_hcd:usb1 15: 7903 XT-PIC-XT-PIC ahci NMI: 0 Non-maskable interrupts LOC: 0 Local timer interrupts SPU: 0 Spurious interrupts PMI: 0 Performance monitoring interrupts IWI: 0 IRQ work interrupts RTR: 0 APIC ICR read retries RES: 0 Rescheduling interrupts CAL: 0 Function call interrupts TLB: 0 TLB shootdowns TRM: 0 Thermal event interrupts THR: 0 Threshold APIC interrupts MCE: 0 Machine check exceptions MCP: 1 Machine check polls ERR: 0 MIS: 0



Комбинации:

На самом деле для новой опции есть только одна: «noapic pci=nomsi».

Все прерывания от устройств могут поступать только в CPU0 через PIC. Но LAPIC работает, и другие процессоры могут работать и обрабатывать прерывания.

Во-первых, потому что с «nolapic» ничего совместить нельзя, т.к.

эта опция уже сделает I/O APIC и MSI недоступными.

Так что если вы когда-либо указывали параметры загрузки «noapic nolapic» (или самый распространенный вариант «acpi=off noapic nolapic»), то, видимо, вы набрали лишние буквы.

Итак, что же будет от опции «noapic pci=nomsi»:

Прерывания от внешних устройств в системе x86. Часть 2. Параметры загрузки ядра Linux

Вывод из /proc/interrupts:

CPU0 CPU1 CPU2 CPU3 0: 5 0 0 0 XT-PIC-XT-PIC timer 1: 2 0 0 0 XT-PIC-XT-PIC i8042 2: 0 0 0 0 XT-PIC-XT-PIC cascade 3: 5072 0 0 0 XT-PIC-XT-PIC i915, snd_hda_intel, eth59 4: 32 0 0 0 XT-PIC-XT-PIC eth58 8: 1 0 0 0 XT-PIC-XT-PIC rtc0 9: 0 0 0 0 XT-PIC-XT-PIC acpi 11: 281 0 0 0 XT-PIC-XT-PIC snd_hda_intel 12: 200 0 0 0 XT-PIC-XT-PIC ehci_hcd:usb1 15: 7930 0 0 0 XT-PIC-XT-PIC ahci NMI: 0 0 0 0 Non-maskable interrupts LOC: 2595 2387 2129 1697 Local timer interrupts SPU: 0 0 0 0 Spurious interrupts PMI: 0 0 0 0 Performance monitoring interrupts IWI: 159 90 482 135 IRQ work interrupts RTR: 3 0 0 0 APIC ICR read retries RES: 1568 1666 1810 1833 Rescheduling interrupts CAL: 431 556 549 558 Function call interrupts TLB: 124 184 156 274 TLB shootdowns TRM: 116 116 116 116 Thermal event interrupts THR: 0 0 0 0 Threshold APIC interrupts MCE: 0 0 0 0 Machine check exceptions MCP: 2 2 2 2 Machine check polls ERR: 0 MIS: 0



Таблицы маршрутизации прерываний и параметры «acpi=noirq», «pci=noacpi», «acpi=off»

Как операционная система получает информацию о маршрутизации прерываний от устройств? BIOS подготавливает информацию для ОС в виде:
  • Таблицы ACPI (методы _PIC/_PRT)
  • _MP_ таблицы (MPtable)
  • Таблицы $PIR
  • Регистрирует пространство конфигурации устройства PCI 0x3C/0x3D.
Следует отметить, что BIOS не нужно делать ничего дополнительно для обозначения прерываний MSI; вся вышеуказанная информация необходима только для линий прерываний APIC/PIC. Таблицы в списке выше перечислены в порядке приоритета.

Давайте посмотрим на это более подробно.

Допустим, биос предоставил все эти данные и мы загружаемся без каких-либо дополнительных опций:

  • ОС находит таблицы ACPI
  • ОС выполняет метод ACPI «_PIC» и передает ему аргумент, необходимый для загрузки в режиме APIC. Здесь код метода обычно сохраняет выбранный режим в переменной (скажем, PICM=1).

  • Чтобы получить данные прерывания, ОС вызывает метод ACPI «_PRT».

    Он внутренне проверяет переменную PICM и возвращает маршрутизацию для случая APIC.

В случае, если мы загружаем опцию ноапический :
  • ОС находит таблицы ACPI
  • ОС выполняет метод ACPI «_PIC» и передает ему аргумент, необходимый для загрузки в режиме PIC. Здесь код метода обычно сохраняет выбранный режим в переменной (скажем, PICM=0).

  • Чтобы получить данные прерывания, ОС вызывает метод ACPI «_PRT».

    Он внутренне проверяет переменную PICM и возвращает маршрутизацию для случая PIC.

Если таблица ACPI отсутствует или функция маршрутизации прерываний через ACPI отключена с помощью опций acpi=нуарк или pci=ноакпи (или ACPI полностью отключен с помощью акпи=выкл.

), то ОС просматривает таблицу MPtable (_MP_) для маршрутизации прерываний:

  • ОС не находит/просматривает таблицы ACPI
  • ОС находит таблицу MPtable (_MP_)
Если таблица ACPI отсутствует или функция маршрутизации прерываний через ACPI отключена с помощью опций acpi=нуарк или pci=ноакпи (или ACPI полностью отключен с помощью акпи=выкл.

) и если MPtable (_MP_) отсутствует (или передана опция загрузки ноапический или ноляпический ):

  • ОС не находит/просматривает таблицу ACPI
  • ОС не находит/просматривает таблицу MPtable (_MP_)
  • ОС находит таблицу $PIR
Если таблицы $PIR нет или она неполная, то операционная система будет просматривать значения регистров 0x3C/0x3D пространства конфигурации устройства PCI, чтобы угадать прерывания.

Подытожим все вышесказанное следующей картинкой:

Прерывания от внешних устройств в системе x86. Часть 2. Параметры загрузки ядра Linux

Следует помнить, что не каждый BIOS предоставляет все 3 таблицы (ACPI/MPtable/$PIR), поэтому если вы передали загрузчику опцию отказа от использования ACPI или ACPI и MPtable для маршрутизации прерываний, то далеко не факт, что ваша система загрузится.

Примечание 1 : если мы попробуем загрузиться в режиме APIC с опцией acpi=noirq и без наличия MPtable, то картина прерывания будет такая же, как и в случае обычной загрузки с единственной опцией noapic. Сама операционная система перейдет в режим прерывания PIC. Если мы попытаемся загрузиться вообще без таблиц ACPI (acpi=off) и без предоставления MPtable, то картина будет такой:

CPU0 0: 6 XT-PIC-XT-PIC timer 1: 2 XT-PIC-XT-PIC i8042 2: 0 XT-PIC-XT-PIC cascade 8: 0 XT-PIC-XT-PIC rtc0 12: 373 XT-PIC-XT-PIC ehci_hcd:usb1 16: 0 PCI-MSI-edge PCIe PME 17: 0 PCI-MSI-edge PCIe PME 18: 0 PCI-MSI-edge PCIe PME 19: 0 PCI-MSI-edge PCIe PME 20: 0 PCI-MSI-edge PCIe PME 21: 0 PCI-MSI-edge PCIe PME 22: 8728 PCI-MSI-edge ahci 23: 1 PCI-MSI-edge eth59 24: 1301 PCI-MSI-edge eth59-rx-0 25: 113 PCI-MSI-edge eth59-tx-0 26: 0 PCI-MSI-edge eth58 27: 45 PCI-MSI-edge eth58-rx-0 28: 45 PCI-MSI-edge eth58-tx-0 29: 1280 PCI-MSI-edge snd_hda_intel NMI: 2 Non-maskable interrupts LOC: 24076 Local timer interrupts SPU: 0 Spurious interrupts PMI: 2 Performance monitoring interrupts IWI: 2856 IRQ work interrupts RTR: 0 APIC ICR read retries RES: 0 Rescheduling interrupts CAL: 0 Function call interrupts TLB: 0 TLB shootdowns TRM: 34 Thermal event interrupts THR: 0 Threshold APIC interrupts MCE: 0 Machine check exceptions MCP: 2 Machine check polls ERR: 0 MIS: 0

Это происходит потому, что без таблиц ACPI MADT ( Таблица описаний нескольких APIC ) и необходимую информацию из MPtable, операционная система не знает APIC ID для других процессоров и не может с ними работать, но LAPIC основного процессора работает, так как мы его не запрещали, и на него могут приходить MSI-прерывания.

То есть это будет так:

Прерывания от внешних устройств в системе x86. Часть 2. Параметры загрузки ядра Linux

Заметка 2 : В целом маршрутизация прерываний при использовании ACPI в случае APIC аналогична маршрутизации прерываний через MPtable. А маршрутизация прерываний через ACPI в случае использования PIC совпадает с маршрутизацией прерываний через $PIR. Таким образом, результаты /proc/interrupts не должны отличаться.

Однако в процессе исследования я заметил одну странную вещь.

При маршрутизации через MPtable почему-то на выходе появляется каскадное прерывание «XT-PIC-XT-PIC cascade».



CPU0 CPU1 CPU2 CPU3 0: 15 0 0 0 IO-APIC-edge timer 1: 2 0 0 0 IO-APIC-edge i8042 2: 0 0 0 0 XT-PIC-XT-PIC cascade 8: 0 1 0 0 IO-APIC-edge rtc0 9: 0 0 0 0 IO-APIC-edge acpi .



Немного странно, что так происходит, но.

документация ядра вроде говорят, что это нормально.



Заключение:

В заключение еще раз обрисуем рассмотренные варианты.

Варианты выбора контроллера прерываний:

  • PCI=номси - Прерывания MSI станут IO-APIC/XT-PIC в зависимости от используемого контроллера прерываний.

  • ноапический — Отключает APIC ввода-вывода.

    Прерывания MSI по-прежнему могут поступать на все процессоры, другие прерывания от устройств могут поступать только на PIC, и они работают только с CPU0. Но LAPIC работает, и другие процессоры могут работать и обрабатывать прерывания.

  • ноапический PCI = номси — Все прерывания от устройств могут идти только на PIC, и он работает только с CPU0. Но LAPIC работает, и другие процессоры могут работать и обрабатывать прерывания.

  • ноляпический — Отключает LAPIC. Прерывания MSI не могут работать без LAPIC, APIC ввода-вывода не может работать без LAPIC. Все прерывания от устройств будут поступать на PIC, а он работает только с CPU0. А без LAPIC остальные ЦП работать не будут.
Варианты выбора таблицы маршрутизации приоритетных прерываний:
  • нет вариантов — маршрутизация через APIC с использованием таблиц ACPI
  • ноапический - маршрутизация через PIC с использованием таблиц ACPI
  • acpi=нуарк ( pci=ноакпи / акпи=выкл.

    ) — маршрутизация через APIC с использованием таблицы MPtable

  • acpi=нуарк ( pci=ноакпи / акпи=выкл.

    ) ноапический ( ноляпический ) — маршрутизация через PIC с использованием таблицы $PIR

В следующей части мы увидим, как coreboot настраивает чипсет для маршрутизации прерываний.

Теги: #linux #установка Linux #Системное программирование #MSI #BIOS #acpi #apic #pic #irq #interrupts

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.