Mar*_*oom 11 io x86 cpu-architecture numa
MMIO,IO和PCI配置请求如何路由到NUMA系统中的正确节点?
每个节点都有一个“路由表”,但我认为操作系统应该不知道它。
如果操作系统无法更改“路由表”,该如何重新映射设备?
有关“路由表”(即源地址解码器(SAD))的正确介绍,请参阅Intel Xeon v3 / v4 CPU中的物理地址解码:补充数据表。
我将首先回顾一下我从论文和几乎未记录的数据表中收集到的内容。不幸的是,这将延长问题的时间,并且可能无法解决所有问题。
当请求传出LLC 1时,非核心需要知道将其路由到何处。
在工作站CPU上,目标是DRAM,PCIe根端口/集成设备或DMI接口。
由于iMC寄存器2或PCIe根端口3 /集成设备之一,该内核可以轻松判断出内存请求是否属于DRAM,并且最终将退回到DMI。
当然,这还包括MMIO,并且与端口映射的IO几乎相同(仅跳过DRAM检查)。
PCI配置请求(CFG)按照规范进行路由,唯一的警告是,总线0上的CFG请求(不针对集成设备)是通过DMI接口4发送的。
在服务器CPU上,物理地址的目标可以是未分配的。
表用于查找节点ID(NID)5。该表称为SAD。
实际上,SAD由两个解码器组成:DRAM解码器(使用表)和IO解码器6(由大多数固定范围和启用位组成,但也应包含表)。
如果需要,IO解码器将覆盖DRAM解码器。
DRAM解码器使用范围列表,每个范围与目标NID 7的列表相关联。如果内存,MMIO或PCIe内存映射配置请求(MMCFG)匹配范围,则非内核将沿着QPI / UPI路径将请求发送到所选目标(尚不清楚SAD是否可以将请求者节点本身作为目标)。
IO解码器可以使用具有固定目标的固定范围的启用位(例如,将旧版BIOS窗口回收到“ BIOS NID”),或者具有可变范围(其中部分地址用于索引目标列表)。
在映射为的表中查找端口映射的IO目的地IO[yyy]。
在名为的表中查找MMCFG IO目标PCI[zzz]。
CFG目标重用该PCI[zzz]表。并在
此处表示索引功能,即请求地址的一部分(是CFG的总线号)。 yyyzzzzzz
所有这些对我来说都很有意义,但是这些表未在数据表中记录,因此类似的符号PCI[zzz]可能实际上意味着完全不同的含义。
尽管关于这些解码器的文档很少甚至没有文档,但对于原始的心理模型来说已经足够了。
对于我来说还是不清楚的是,即使是将SAD用于目标为本地资源的请求,还是仅将其用于出口请求。
稍后将很重要。
假设当请求离开LLC时,SAD用于将其路由到组件(最终在同一套接字中),然后按照与工作站案例8类似的方式处理它。
只要不更改硬件配置,就可以通过固件来配置SAD,而OS可以完全与它们无关。
但是,如果操作系统重新映射位于节点本地PCIe链接后面的PCIe设备,会发生什么情况?
对于MMIO请求到达这样的设备,它必须首先到达设备的节点(因为它是与系统其余部分的唯一链接),但这只有在正确重新配置SAD的情况下才能发生。即使对于源自与设备9 相同的节点的请求,
也可能需要重新配置SAD 。但是操作系统应该不知道SAD,不是吗?
我有几个可能的答案:
1,例如由于未命中或由于是UC。
2,例如TOUM用于DRAM回收的最大物理地址,尽管它不是连续的块。
3它们是PCI到PCI(P2P)桥,并具有设置IO,可预取和不可预取内存窗口的寄存器。
4这就是PCH设备出现在总线0上的原因。服务器CPU具有两个“内部”总线,并且可以更改其编号。
5节点ID由套接字号和非核心组件ID组成。我知道可以作为目标的非核心组件是(在“ 框 ”命名法中的名称转换之后):第一个或第二个本地代理(iMC),系统代理和DMI链接。
6 IO解码器表分为IOS(IO小解码器)和IOL(IO大解码器)。这反映了两个表的硬件功能,IOS几乎是固定的,IOL是CAM。两者均与DRAM表并行查询,如果两者都匹配,IOS将覆盖IOL。
7范围自动在所有八个目标之间交错(即细分)。要使用少于八个目标,可以使用重复条目(例如,所有设置为相同目标的条目都与无交织相同)。
8我想知道,如果SAD将请求路由到非核心组件(例如iMC)但超出其回收范围,会发生什么情况?我猜它被丢弃了。
9参见上面的粗体部分,我不知道SAD如何处理针对本地资源的请求。
10个 Linux在UMA计算机中伪造了NUMA节点。在我的方框中,分配给节点的内存量包括 MMIO(分配的近10GiB与8GiB或DRAM)。似乎使用了E8020返回的整个范围。
此答案使用 Xeon 5500 和 7500 数据表中的元素(使用环和 Rbox 连接到系统的其余部分),但此答案讨论的是环总线架构类似于 IvB-EX Xeon e7 v2 的系统(使用 2 个环),但也适用于 Haswell-EX(使用 4 个环,在 2)SnB 和 Broadwell 之间互连。我假设每个环仍分为 4 个 32 字节的双向环:监听/无效、数据/块、请求/地址、确认环。
至强 e7 v2:
在复位信号的下降沿,该包会立即确定 NodeID 和相邻的 NodeID、x2APIC 集群 ID 和逻辑处理器 APIC ID(在台式机 CPU 上的 SnB 之前,它用于对输入引脚上的 MCH 信号进行采样以执行此操作;我不是确定自 SnB 以来的多插座)。在此之后,缓存和 TLB 被刷新,内核执行 BIST,然后多路MP 初始化算法发生. Xeon D-1500 vol2 显示了一个 CPUNODEID 寄存器;我不确定在更改有关正在进行的交易的重置后会出现什么样的行为。当其他内核上的 CPUNODEID 更改时,SAD 目标列表是否通过自动生成的写入更改,或者它是否触发 SMI 处理程序,或者这是程序员的任务?身份证。据推测,在更改 SAD 配置之前,所有代理都必须停顿以阻止他们访问 Cbo。
每个套接字都有一个缓存代理和一个归属代理(或 MCC/HCC 上的 2 个 CA 和 2 个 HA)。缓存代理的功能是跨 Cbo 切片地址散列的(在 SnB 之前,缓存代理是 Sbox 和 50% 与其关联的 Cbox 的组合,其中 Sbox 是获取 Cbox 消息的 QPI 接口从环上转换成QPI消息直接送到Rbox,Cbox是LLC slice和环总线的接口;在SnB之后,Cbo在上面实现Sbox和Cbox的功能,发送QPI/IDI消息一个环接口)。映射是在启动时设置的,因为那是设置监听模式的时候。在 Haswell-EX 上,监听模式可以在 BIOS 中在无监听、家庭监听、早期监听、源监听、HS w 之间切换。目录 + OSB + HitME 缓存或 COD,取决于 CPU;虽然我还没有看到任何与监听模式相关的 PCIe 配置寄存器的数据表。我不确定在重置后更改时进行中的交易会出现什么行为。当一个内核被 BIOS 禁用时,它不会影响继续运行的 Cbos。缓存代理是 Nehalem-EX 上的一个单独组件(参见 7500 数据表),但在后来的体系结构中,它被用来指代整个 Cbo。Haswell-EP 上引入的 COD(Cluster on Die)将缓存代理拆分为每个套接字 2 个 缓存代理是 Nehalem-EX 上的一个单独组件(参见 7500 数据表),但在后来的体系结构中,它被用来指代整个 Cbo。Haswell-EP 上引入的 COD(Cluster on Die)将缓存代理拆分为每个套接字 2 个 缓存代理是 Nehalem-EX 上的一个单独组件(参见 7500 数据表),但在后来的体系结构中,它被用来指代整个 Cbo。Haswell-EP 上引入的 COD(Cluster on Die)将缓存代理拆分为每个套接字 2 个
在每个缓存切片内都有一个缓存盒,它是一个控制器,也是 LLC 与系统其余部分(基本上是 LLC 控制器)之间的代理。Cbo 包含保存所有待处理事务的请求表。Cbo 支持三种类型的事务:1. 内核/IIO 发起的请求 2. 英特尔 QPI 外部监听 3. LLC 容量驱逐。每个事务在 TOR 中都有一个相关联的条目。TOR 条目保存 Cbo 所需的信息,以唯一标识请求(例如地址和交易类型)和跟踪交易当前状态所需的状态元素。
核心/PCIe 请求经过地址散列以选择 Cbo 进行转换并将请求放置到环上。该核心知道环上什么方向发送的最小时延的要求,因此将用相同的地址映射配置,并等待空位环上,以适应交易。
核心发起的请求使用 IDI 数据包接口。IDI(芯片内互连)显示在 Broadwell-EX 上。该图暗示核心仅使用 IDI 数据包,而 CBos 使用 QPI 和 IDI。至强 e7 v2 操作码如表 2-18所示,QPI 操作码如表 2-218 所示。这也可以防止 IIO 在解码之前声明地址,因为它只接受 QPI 操作码。在一些图表中,Ubox 与 IIO 共享一个停靠点;在其他方面,他们是分开的。
当空位到达时,它与 Cbo 共享的双向停止逻辑会将 32 字节的 flit 放入请求环中,如果 Cbo 需要同时向同一方向发送,那么具有正确目标的交易选择目标的极性,否则使用某种其他形式的仲裁。我假设核心可以在循环中向两个方向写入并且停止的 Cbo 可以从两个方向读取,或者 Cbo 和核心可以根据仲裁写入一个和读取一个。我会想象 IDI flit 的链路层标头包含源、目标 ID,允许更高层事务(传输层)被拆分并在环上出现空闲间隙时不连续到达,因此它知道是否继续缓冲事务并从环中移除 flit。(Ring IDI/QPI 与没有链路层源/目标的 QPI 不同,因为 QPI 是点对点的;而且 QPI 只有 80 位的 flit,很容易找到图表;而不是环总线的情况头)。Cbo 针对每个目的地实施 QPI 链路层贷方/借方方案,以阻止缓冲区溢出。这个请求可能只需要 1 次 flit,但缓存行提取需要 3 次。当 Cbo 看到相关操作码和地址范围内的地址时,它会进行解码。现在它必须解码地址以查看如何处理它。这个请求可能只需要 1 次 flit,但缓存行提取需要 3 次。当 Cbo 看到相关操作码和地址范围内的地址时,它会进行解码。现在它必须解码地址以查看如何处理它。这个请求可能只需要 1 次 flit,但缓存行提取需要 3 次。当 Cbo 看到相关操作码和地址范围内的地址时,它会进行解码。现在它必须解码地址以查看如何处理它。
在 Cbo 中,请求在分配到 TOR并发送到 LLC的同时通过 SAD 。非 LLC 消息类别类型在分配到 TOR 时也会通过 SAD。SAD 接收地址、地址空间、操作码和其他一些交易细节。为了帮助减少不同 DRAM 容量所需的解码器条目的数量,地址解码器有几个交错选项,在至强 7500 上分为 3 个解码器,优先级从高到低:I/O 小 (IOS) 解码器、I/O大(IOL)解码器,DRAM解码器。在至强 e7 v2 上,有 4 个解码器:DRAM、MMIO、Interleave、legacy。
这些解码器中的每一个都有一个地址并被并行访问。与其中一个解码器中的条目匹配的地址会导致解码器查找并生成 QPI 内存属性和 NodeID。每个解码器只允许一次匹配。高优先级解码器中的地址匹配将覆盖低优先级解码器中的同时匹配。
输入/输出解码器
这里给出了 8 个目标列表,PCI[]、MIOU[]、MIOL[]、FWH[]、APIC[]、IOH[]、CPU[]、IO[]。这些以及一些 I/O 解码器条目可通过 Cbo 设备下的 CSR进行配置,并且每个 Cbo 都有自己的 SAD。Local Cfg registers,它只是一个固定的MMIO区域,映射本地PCIe配置寄存器只有一个目标,本地socket,不需要任何目标列表(它总是会被路由到Ubox,所以NodeID将是 7500 上的本地 Ubox)。
英特尔至强处理器 E7 v2 产品系列实现了 4 位的 NodeID (NID)。英特尔至强处理器 E7 v2 产品系列在每个插槽中最多可支持 2 个 HA。同一套接字中的 HA 将通过
NID[2]. 在目标只有 3 位的情况下,NID[2]假定为零。因此,套接字 ID 将为NID[3,1:0]. 英特尔至强处理器7500系列工具5个比特,可以支持多达四个插座(通过选择NID[3:2]时NID[4]是零)。每个插槽中有四个设备 (NID[1:0]):英特尔® 7500 芯片组 (00)、B0/S0 (01)、Ubox (10)、B1/S1 (11)。B0/S0和B1/S1是两组HAs(Bboxes)和CAs(Sboxes)。
E7 v2 有 4 位 NodeID,这意味着它可以支持多达 8 个套接字和每个套接字 2 个 HA。如果一个套接字有 2 个 HA(MCC,HCC),它仍然有 2 个独立的 NodeID,无论它是否处于 COD 模式,缓存和 DRAM 局部性仍然可以被 NUMA 感知应用程序利用,使用半球位作为 CBos总是通过哈希算法与它们的套接字半(半球)中的 HA 相关联。例如,散列函数可能会导致addr[6]在核心中选择一个 CBo 半球,并且取决于该半球中有多少 (n) 个 CBo,addr[x:7] mod n选择 CBo。每个 CBo 处理特定范围的 LLC 集,其中套接字的 LLC 缓存覆盖整个地址范围。COD 改为创建 2 个缓存关联域(其中任一半球的 CBos 现在每个都覆盖完整的地址范围而不是地址范围的一半,因此成为他们自己的官方 NUMA 节点,具有完全跨越的缓存(而不是 2 个 NUCA 缓存),就像这样它自己的套接字——核心缓存访问现在永远不会穿过套接字的另一半,减少了延迟,但降低了命中率,因为缓存现在只有一半大小——你仍然可以获得相同级别的缓存延迟等等如果您仅访问与 NUCA/NUMA 节点关联的内存,则关闭 COD 的容量)。addr[6]用于选择 DRAM 解码器中的 HA。当有多个socket时,addr[8:6]选择一个HA,它可能在另一个socket上,所以它会使用一半addr[6]的CBos,但是如果`addr[8:7,CBo就会把LLCmiss发送给另一个socket上的家乡代理]如果 NUMA 调度程序不能正确地“关联”进程和内存,则不使用它们关联的家乡代理。
这是它出现的 I/O 解码器列表的释义。该表包括 IOS 和 IOL 解码器条目。属性,例如CFG,是从中选择操作码的输出操作码类。
DRAM解码器
在至强 7500 上,DRAM 解码器由两个阵列组成,一个 CAM 阵列和一个有效载荷阵列。DRAM 解码器在每个阵列中有 20 个条目,用于 20 个不同区域,最小 256MiB,具有 8 个子区域(交错)。DRAM 解码器条目还可用于定义相干、MMIO、MMCG 和 NXM 空间。如果需要多个 PCI 段,则使用 DRAM 解码器条目将其配置在 DRAM 顶部以上,但与 4G 以下的普通 PCIe 条目不同,这些条目不应交错,因此多个目标将需要多个 SAD 条目,并且需要将这些相同的 SAD 条目放入每个套接字。CAM 阵列具有特殊的比较逻辑来计算地址是否小于或等于每个条目的区域限制,以允许任何区域大小为 256 MiB 的倍数。区域限制地址位 [43: 28] 存储在条目的 CAM 数组中(意味着 256MiB 粒度)。负载数组 (tgtlist–attr) 每个条目有 42 位。
您希望看到这些 SAD DRAM 解码器条目的 20 个 64 位(保留 6 位)配置寄存器(并且似乎只有一组 SAD 规则供套接字上的所有 SAD 使用),尽管这是针对 5500,而且我认为在较新的 CPU 上,所有 CBo SAD 仍然只有一组寄存器。
在 5500 上,您为 [19:6] 中的规则设置 PA[39:26] 并设置索引生成方法,SAD_DRAM_RULE_0然后SAD_INTERLEAVE_LIST_0将目标列表放入其中——这将设置解码器字段,并且可能设置了其他字段。必须有设置条目的半球位的寄存器(但它不是在数据表上所示),它告诉它异或NID的第一位与列表CboxID[2](HA它属于什么-一样NID[1]的当前 Cbox 的 HA,即addr[6])当前 Cbox。这个想法是 NID 1在目标列表中总是被设置为 0,这样与当前 Cbox 的异或CboxID[2]会导致它选择属于 Cbox 的家乡代理(这就是为什么你不需要为每个个人 CBox)。
目标列表条目在 Xeon 5500 Nehalem-EP (Gainestown) 上为 2 位,属于 DP(双处理器)服务器系列,因此最多只有 2 个插槽(只有 2 个 QPI 链接,1 个用于 IOH,一个用于互CPU),因此最多 4 个 HA。在 7500(4x QPI)(4 个插槽,每个插槽有 2 个 HA:8 个)上将是 3 位,扩展到 4 位以包含一个冗余的NID[4]. SAD 和 DRAM 解码入口配置肯定必须在所有套接字上设置相同。
8 个节点 (HA) 的交织是addr[8:6]在地址上完成的,这些节点从发送到目标 HA 的地址中删除(排除),因为它知道自己的 ID。上表针对 7500,其中addr[6]标识NodeID[1]了套接字上的HA ( )。
有两种类型的请求:
非相干请求要么是映射到非相干地址空间(如 MMIO)的数据访问,要么是非内存请求,如 IO 读/写、中断/事件等。当 NC 请求访问 NC 内存时,它们被发送到就像连贯的请求一样,根据地址的哈希计算 Cbo。不以内存为目标的 NC 请求被发送到连接到生成请求的核心的 Cbo。
MMIO
与特定地址相关的事务由 Cbo 接收,通过 I/O 和 DRAM 解码器,存储在 TOR 中,但如果 IDI 操作码不可缓存(例如 PRd),则不发送到 LLC 切片,内核根据内存发送该操作码在 L1 访问中输入 PAT/MTRR 读取,WCiL 除外,我认为这会使其他内核和缓存代理中的别名无效。它将在 MMIO 区域之一的 I/O 解码器条目中匹配。某些 CPU 上将有 8 个 IOAPIC(不在 Xeon 7500 上,因为它谈论 ICH/IOH,它是 Beckton(Nehalem-EX),所以这是环形总线的第一个实现;但是当在 Nehalem Ibex Peak 上引入 PCH 时,它已集成在 IIO 模块中)。FECX_(yyyx)XXXh (so bit [15:13]) 中的 yyy 将用于为 NodeID 索引到 APIC[] 表中。这意味着在 64KiB 的连续区域中每个 IOAPIC 有 8KiB。SAD 输出 NodeID 和要使用的操作码 (NcRd)。至强 3400 手册谈到将“节点 ID”分配给 IIO,也许这是“芯片组/IOH”节点 ID,但 E7 v2 没有这个,所以也许有一个隐藏的扩展可以在 IIO 和 Ubox 之间进行选择,或者也许QPI 请求附加了一个单独的 ID,Cbos 也有一个 ID。然后,IIO 将根据集成的 IIO 和 PCI 桥寄存器路由 MMIO 访问并减法解码到 DMI。所以也许有一个隐藏的扩展可以在 IIO 和 Ubox 之间进行选择,或者可能有一个单独的 ID 附加到 QPI 请求并且 Cbos 也有一个 ID。然后,IIO 将根据集成的 IIO 和 PCI 桥寄存器路由 MMIO 访问并减法解码到 DMI。所以也许有一个隐藏的扩展可以在 IIO 和 Ubox 之间进行选择,或者可能有一个单独的 ID 附加到 QPI 请求并且 Cbos 也有一个 ID。然后,IIO 将根据集成的 IIO 和 PCI 桥寄存器路由 MMIO 访问并减法解码到 DMI。
此外,MMIO BAR 有 2 个区域 MMIOL 和 MMIOH。根据 PCIEXBAR 的值(如果 PCIEXBAR 为 2GiB,则 MMIOLL 将不存在),最后 7 个插槽中最多有 256MiB 的 MMIOLL 交错,前 7 个插槽中最多有 256MiB MMIOLU 交错。7500 数据表说 MMIOH 需要每个套接字单独的 I/O 解码器条目。
一般服务器CPU内存布局是这样的:
有一个 SCA_PCIE 子区域,它占用 256MiB 配置空间的前 8MiB,该区域必须在 4GiB 以下的 256MiB 区域中。当事务中的地址在本地集群地址范围内(每个套接字 1MiB 集群)时,则覆盖正常的 PCIe 解码,并将 NodeID 视为 PhysicalAddr[22:20]。请注意,1MiB 是总线 0(32 dev * 8 func)——所有套接字的总线 0 对所有其他套接字都是可见的。然后 NodeID 将被放入一个带有 NcCfgRd 操作码和 NodeID 目的地的 QPI 事务中,并且 flit 被放置在请求环上;然后,这将被识别该 NID 范围的 QPI 链接吸收,一旦在目标套接字上,它将被路由到 Ubox(在 SnB 上,IIO 似乎根据 Xeon 3400 vol2 5.8.1 处理 NcCfg 请求),它将执行配置读取;Ubox 在 7500 上有一个唯一的 NodeID,因此它将无缝路由到它(在 e7 v2 上,我们假设这些插入数据包中有一个隐藏的 ID)。Cbo 可能在 QPI 数据包中插入请求者 NodeID、请求者 CBo ID 和事务 ID;Ubox 缓冲并跟踪事务(我假设在确认环上发送一个确认),并在处理完成后将结果(成功/失败)发送回数据环上 QPI 数据包中的源 NodeID,它将传播通过 QPI 链接返回。CBo 完成交易并在数据环上向Core 返回IDI 数据包。请求者 CBo ID 和交易 ID;Ubox 缓冲并跟踪事务(我假设在确认环上发送一个确认),并在处理完成后将结果(成功/失败)发送回数据环上 QPI 数据包中的源 NodeID,它将传播通过 QPI 链接返回。CBo 完成交易并在数据环上向Core 返回IDI 数据包。请求者 CBo ID 和交易 ID;Ubox 缓冲并跟踪事务(我假设在确认环上发送一个确认),并在处理完成后将结果(成功/失败)发送回数据环上 QPI 数据包中的源 NodeID,它将传播通过 QPI 链接返回。CBo 完成交易并在数据环上向Core 返回IDI 数据包。
如果地址位于 8MiB 区域之外但位于 256 PCIe 配置空间中,则它将匹配 I/O 解码器列表中的顶部条目。zzz 位(显然是第 27-25 位)用于索引目标列表以选择节点。我们知道这显然是总线编号的前 3 位。这必须表明,假设索引 = 交错列表中的套接字号,套接字 0 分配将从总线 8 开始(总线 0 作为总线 0),套接字 1 将从总线 32(总线 0 作为总线 1)开始,套接字 2 在总线 64(总线 0 作为总线 2),96 处的套接字 3(总线 3 处的总线 0)(并且在发送到套接字 3 的请求中,我假设它删除了 NodeID 位,这样它就会看到总线 1 而不是 96 (或者可能是总线 0,如果它别名而不是添加 1))。从这个 PCIEXBAR 配置空间访问将一个段中的总线数量限制为 32,因此需要分配专用于每个段的完整 256MiB 别名(在 DRAM 解码器中,您可以通过将目标列表设置为仅包含套接字上的 NodeID 来设置针对特定套接字的 MMCFG 条目)并且对该范围的任何访问都是指向那个插座。PCI[zzz] 的意思似乎是:索引到 PCI 目标列表中以选择一个 NodeID 并为请求提供属性类的操作码(基于 TOR 详细信息的 NcCfgRd/Wr),Cbo 还将地址转换为总线/设备/功能编号 BIOS 必须读取此配置寄存器才能为 PCIe 端口上的 PCI 到 PCI 桥输入正确的从属设备编号。
在 I/O 解码器上还有条目 LclCSRs(本地配置)、Glb IOH CSRs(IOH Cfg)、Glbl CPU CSRs(CPU Cfg)、lcl clump CSRs(本地集群 CPU 配置)。这些是在不使用 PCIEXBAR 的情况下访问 PCIe 配置空间寄存器 (CSR) 的固定 MMIO 别名。
输入输出
所有套接字都有固定的 IO 端口,并且可以在将 Memory Space Indicator 设置为 IO 空间的 BAR 中设置。
IO 请求由 Cbo 接收并在 IO 表中查找。IDI 列表上似乎没有单独的 IO 操作码,也没有 UC 的写对应项PRd,可能有一个未记录的操作码,或者将其编码为WCiL.
IO 请求可以是 IO-PCIE 或 IO-SCA 或非 PCIe-IO。如果地址与底行中的模式匹配并且设置了 IO 位且地址为 CF8/CFC,则在地址 [11:8] 中插入 4 个零(内核只能发出 8 位寄存器索引),使得CONFIG_ADDRESS 函数编号 LSB 从第 12 位而不是第 8 位开始,总线编号 MSB 位于第 27 位,现在与底部第 3 行进行比较。如果前 5 个总线位匹配,则 NodeID 由 [22:20] 确定,并向该 NodeID 发送 NcCfgRd/Wr。如果它不是 CF8/CFC,那么目标 NodeID 是通过使用 IO_Addr[15:13] 查找目标列表条目来确定的——因此是 IO 端口的 3 个最高有效位。这意味着每个套接字有 8KiB 的 I/O 空间,并且必须在套接字的范围内设置变量 I/O。对于固定 I/O 访问,如果您将前 3 位设为套接字的前 3 位,那么理论上它们可以在比赛中被 Cbo 移除;因此,为了访问套接字 1 上的 20h,您将使用 2020h。
其他
可以通过操作码匹配解码器条目的核心发出的请求是: • IntA、Lock、SplitLock、Unlock、SpCyc、DbgWr、IntPriUp、IntLog、IntPhy、EOI、FERR、Quiesce。它们在 TOR 中分配但不发送到 LLC。当硬件锁定操作跨越 2 个缓存行时使用 SplitLock。锁定过去由 Cbo 定向到 Ubox 以停顿所有代理以执行原子操作,但这是不必要的开销,因为它可以在缓存一致性协议中实现。因此,要么 Lock RFO 现在被 Cbo 拾取,它会使其他副本无效并做出响应,并且核心在此之前无法读取该行(大概 LLC 中有一个指示,表明该行已锁定在侦听中指示的核心中)筛选)。
连贯请求是访问映射到连贯地址空间的内存地址的请求。它们通常用于以缓存线粒度传输数据和/或更改缓存线的状态。最常见的连贯请求是数据和代码读取、RFO、ItoM 和回写驱逐 (WbMtoI)/回写 (WbMtoE) 到 LLC(仅包含缓存)。Coherent 请求由保存指定地址的 LLC 切片的 Cbo 提供服务,由散列函数确定。
如果地址解码为 DRAM 区域,并且附加到该 Cbo 的最后一级缓存切片指示套接字内的内核拥有该行(对于一致读取),则 Cbo 将请求监听到该本地内核(这显然是在谈论通过来自其他内核的访问,在 LLC 切片中具有监听过滤器位的包容性 L3;请注意,在 SKL 服务器网格互连(不是桌面,因为它仍然使用环)上,L3 是非包容性的;在包容性缓存中,如果它是在 2 个内核中有效,则 LLC 副本有效)。
如果该行不在缓存中(假设使用目录 (ecc) + OSB + HitME 缓存的 COD/HS 模式),则请求缓存行的缓存代理不会广播监听。相反,它根据 SAD 解码器规则将 QPI 中的请求转发到拥有地址的 HA NodeID,然后它会向可能拥有该线路的其他缓存代理发送监听。转发到主节点会增加延迟。但是,HA 可以在 DRAM 的 ECC 位中实现一个目录以提高性能。该目录用于过滤对远程套接字或节点控制器的监听;成功监听响应后,它将在目录缓存中分配一个条目。该目录编码 3 个状态:不存在于任何节点中,在 1 个节点中修改(需要回写和降级,并且该位可能指示它在哪一半节点中进行目标广播),在多个节点中共享(意味着不需要窥探);如果不支持目录,我认为它必须在每次 DRAM 访问时监听所有套接字,同时访问正在进行。Haswell-EP 还包括目录缓存 (HitMe) 以加速目录查找。但是,每个 HA 只有 14 KiB,这些缓存非常小。因此,HitMe 缓存中只存储节点之间频繁传输的缓存行。目录缓存存储 8 位向量,这些向量指示 8 个节点(Haswell-EP 上最多 3*2 个逻辑 COD 节点)中的哪一个具有缓存行的副本。当请求到达主节点时,会检查目录缓存。如果它包含所请求行的条目,按照目录缓存的指示发送监听。如果请求在目录缓存中未命中,则HA从内存中的地址中获取并读取目录位并在某些套接字中对其进行修改时相应地发送窥探,或者如果不需要窥探并且不进行窥探则直接发送从内存中获取的数据'不分配条目。[3]
E7 v2 HA 实现了一个 128-entry In flight Memory Buffer(Home tracker),一个 512-entry Tracker(Backup Tracker)。进入 HA 的所有家庭信道消息都将通过 BT(如果启用了 BT)。BT 维护一组 FIFO 以对等待进入 HT 的请求进行排序,以便在 HT 条目变得可用时将其分配给最旧的等待请求。它还有一个归属代理数据缓冲区(一组数据缓冲区,用于在环和内存控制器之间传输数据。它有 128 个条目,每个归属跟踪器一个)。HA 需要从地址解码相应的 DRAM 通道。这个过程称为“目标地址解码”。每个 HA 的 TAD 规则都可以通过 CSR 进行配置;规则由要匹配的内存范围和交错模式组成,即addr[8:6]要索引到 DRAM 通道列表中的截断地址。由于 TAD 包含匹配的地址范围,因此允许为 I/O 解码器被盗范围回收内存:配置 SAD DRAM 解码器以解码某个回收范围并将其配置在 TAD 条目中。(工作站 CPU 使用 TOLUD 和 REMAPBASE 等;这些寄存器的设置会改变从中读取的 Cbo 解码器)。在目标通道解码后,请求被转发到相应的 BGF(气泡生成器 fifo)。读取时,数据将从 iMC 返回并转发到 HADB。写入时,数据将从环下载到 HADB 并转发到 iMC。服务器处理器上的 iMC 连接到每个插槽的 2 个 SMI2 端口,用于通常带有 12 个 DIMM 和可扩展内存缓冲区(例如 Jordan Creek)的转接卡。
不匹配
如果地址不匹配任何范围,或匹配地址空洞(不存在的内存属性),则目标默认为套接字的 Ubox,并且消息被编码为 NcRdPtl 或 NcWrPtl 操作码,长度为零或全零字节使能, 分别。Ubox 将消息视为错误;错误可以配置为返回错误响应或正常完成(返回所有读取的数据或阻止写入的数据更新),有或没有 MCA。此机制用于防止在某些初始化序列期间从外部路由任何非法访问。7500 系列缓存代理不会在访问标记为不存在内存 (NXM) 的 SAD 地址区域时发出 MCA,除非访问是具有回写 (WB) 内存属性的存储。
经典 PCIe 开关图上的总线编号非常错误。我的 GPU 实际上在总线 1 上(因为它在 PCIe 端口上)。似乎集成 PCIe 交换机对软件不可见,端口只是作为总线 0 上的单个 PCIe 控制器/PCI-to-PCI 桥出现,而连接到端口的设备点对点出现在新的总线上(以太网总线 2 上的控制器和总线 3 上的 WLAN 控制器)。
实际上,PCI 到 PCI 桥接器 1 不存在,因为它需要一个从属总线,而我的系统中不存在该总线。要么它在我的系统上不存在,而是具有 2 个集成的 PCI 到 PCI 桥,如下所示:
或者它确实存在,但具有程序员不可见的寄存器,这些寄存器根据从属 PCI 到 PCI 桥的内容而改变,从属总线 no 必须为 0(而不是图中的 1)(这不会通过使 2 个总线编号相同来搞乱路由,因为对面的接口不是总线 0,而是直接连接到 PCH 逻辑,因此对于设备来说,事务总是来自 PCI-to-PCI 桥 1,如如果它是根复合体,除此之外别无他物)。该图呈现了一个非常具有误导性的 PCH;PCIe 接口并不像那样纯粹,并且在必要时由芯片组分解和接口(将所有集成 PCH 桥接器和控制器作为端口上单独的点对点 PCIe 设备太昂贵了)。
CPU 和 PCH 用作具有逻辑子设备的单个物理 PCIe 设备。Ubox 拦截 NcCfgRd/NcCfgWr。IIO+PCH (CPUBUSNO(0)) 设备实际上可以有一个单独的总线编号到内核 (CPUBUSNO(1))。如果总线编号是 CPUBUSNO(1) 或 CPUBUSNO(0) 但低于特定设备编号,则它将直接处理请求。如果它在 CPUBUSNO(0) 上并且设备号高于特定设备号,则它将类型 0 配置 TLP 路由到 DMI 接口,其中逻辑 PCI 桥之外的任何设备响应其功能/设备号(它的作用类似于一个逻辑桥,就好像它的从属编号是该总线编号一样,尽管在同一条总线上)。如果总线 no>CPUBUSNO(0),则它会在 DMI 上生成类型 1 配置 TLP,该 TLP 将被具有该从属总线编号的逻辑桥接器吸收。
| 归档时间: |
|
| 查看次数: |
331 次 |
| 最近记录: |