28.1. IO-APIC

作者:

Ingo Molnar <mingo@kernel.org>

大多数(所有)符合 Intel-MP 标准的 SMP 主板都具有所谓的“IO-APIC”,这是一个增强型中断控制器。它使我们能够将硬件中断路由到多个 CPU 或 CPU 组。如果没有 IO-APIC,来自硬件的中断将仅传递到启动操作系统的 CPU(通常是 CPU#0)。

Linux 支持所有符合标准的 SMP 主板的变体,包括具有多个 IO-APIC 的主板。高端服务器使用多个 IO-APIC 来进一步分配 IRQ 负载。

在某些较旧的主板中存在(一些)已知的损坏,此类错误通常由内核解决。如果您的符合 MP 标准的 SMP 主板无法启动 Linux,请首先查阅 linux-smp 邮件列表存档。

如果您的机器在启用 IO-APIC IRQ 的情况下启动正常,那么您的 /proc/interrupts 将如下所示

hell:~> cat /proc/interrupts
           CPU0
  0:    1360293    IO-APIC-edge  timer
  1:          4    IO-APIC-edge  keyboard
  2:          0          XT-PIC  cascade
 13:          1          XT-PIC  fpu
 14:       1448    IO-APIC-edge  ide0
 16:      28232   IO-APIC-level  Intel EtherExpress Pro 10/100 Ethernet
 17:      51304   IO-APIC-level  eth0
NMI:          0
ERR:          0
hell:~>

一些中断仍然被列为“XT PIC”,但这不是问题;这些 IRQ 源都不是性能关键型的。

在不太可能的情况下,如果您的主板没有创建可用的 mp-table,您可以使用 pirq= 启动参数来“手动构建”IRQ 条目。但这并非易事,也无法自动化。一个示例 /etc/lilo.conf 条目

append="pirq=15,11,10"

实际数字取决于您的系统、您的 PCI 卡及其 PCI 插槽位置。通常,PCI 插槽在连接到 PCI 芯片组 IRQ 路由设施(传入的 PIRQ1-4 线)之前是“菊花链式”连接的

          ,-.        ,-.        ,-.        ,-.        ,-.
PIRQ4 ----| |-.    ,-| |-.    ,-| |-.    ,-| |--------| |
          |S|  \  /  |S|  \  /  |S|  \  /  |S|        |S|
PIRQ3 ----|l|-. `/---|l|-. `/---|l|-. `/---|l|--------|l|
          |o|  \/    |o|  \/    |o|  \/    |o|        |o|
PIRQ2 ----|t|-./`----|t|-./`----|t|-./`----|t|--------|t|
          |1| /\     |2| /\     |3| /\     |4|        |5|
PIRQ1 ----| |-  `----| |-  `----| |-  `----| |--------| |
          `-'        `-'        `-'        `-'        `-'

每个 PCI 卡都会发出 PCI IRQ,可以是 INTA、INTB、INTC 或 INTD

      ,-.
INTD--| |
      |S|
INTC--|l|
      |o|
INTB--|t|
      |x|
INTA--| |
      `-'

这些 INTA-D PCI IRQ 始终是“卡本地的”,它们的实际含义取决于它们所在的插槽。如果您查看菊花链连接图,插槽 4 中的卡发出 INTA IRQ,它将最终成为 PCI 芯片组的 PIRQ4 上的信号。大多数卡都发出 INTA,这会在 PIRQ 线之间创建最佳分配。(正确分配 IRQ 源不是必需的,可以随意共享 PCI IRQ,但是最好为了性能不共享中断)。插槽 5 应用于视频卡,它们通常不使用中断,因此它们也不会进行菊花链连接。

因此,如果您的 SCSI 卡(IRQ11)在插槽 1 中,Tulip 卡(IRQ9)在插槽 2 中,那么您必须指定此 pirq= 行

append="pirq=11,9"

以下脚本尝试从您的 PCI 配置中找出这样的默认 pirq= 行

echo -n pirq=; echo `scanpci | grep T_L | cut -c56-` | sed 's/ /,/g'

请注意,如果您跳过了一些插槽,或者您的主板没有进行默认的菊花链连接(或者 IO-APIC 以某种奇怪的方式连接了 PIRQ 引脚),则此脚本将不起作用。例如,如果在上述情况下,您的 SCSI 卡(IRQ11)在插槽 3 中,并且插槽 1 为空

append="pirq=0,9,11"

[值 “0” 是一个通用的 “占位符”,为空(或不发出 IRQ 的)插槽保留。]

一般来说,总是可以找出正确的 pirq= 设置,只需正确排列所有 IRQ 号码即可......但这需要一些时间。“不正确”的 pirq 行将导致启动过程挂起,或者设备无法正常工作(例如,如果它是作为模块插入的)。

如果您有 2 个 PCI 总线,那么您最多可以使用 8 个 pirq 值,尽管这样的主板往往具有良好的配置。

请做好准备,您可能需要一些奇怪的 pirq 行

append="pirq=0,0,0,0,0,0,9,11"

使用巧妙的试错技术来找出正确的 pirq 行...

祝你好运,如果您有本文件未涵盖的任何问题,请发送邮件至 linux-smp@vger.kernel.orglinux-kernel@vger.kernel.org