如何在ARM Cortex-A7处理器的多个核心之间分配L2缓存?

4

上下文和目标

我想在我的 Olimex A20 Lime 平台上运行两个完全独立的应用程序,它们在一个运行 ARM Cortex-A7 的处理器核心上。目标是将每个应用程序分配给一个处理器核心。到目前为止还好。

现在我想按以下方式在处理器核心之间划分 L2 缓存:

       L2 cache (256KB)
---------------------------
|    CPU0    |    CPU1    |
|   (128KB)  |   (128KB)  |
---------------------------

因此,每个核心只能访问他私有的128KB L2高速缓存。
问题:
如何在ARM Cortex-A7上将L2高速缓存分配给核心?
据我了解,在以前的SoC上,通常使用外部缓存控制器,例如PL310。现在,像Cortex-A15和Cortex-A7这样的新型SoC使用集成缓存控制器。该控制器与SCU组件集成在一起。
我在CP15系统中找到了一些与缓存相关的寄存器,例如CSSELR、CCSIDR、CLIDR等,甚至是系统控制寄存器(SCTLR)。但是,没有一个似乎可以让我为每个核心配置大小。这还有可能吗?
感谢您的帮助。
这里所说的“独立应用程序”,实际上是指Linux操作系统。因此,目标是将一个核心专门用于一个操作系统。因此,每个操作系统在下面运行(看到)一个单处理器系统。整个框架已经在运行,目前为止还不错。
感谢我收到的答案,我现在明白了,即使它们是独立的操作系统,也可以让核心都使用L2,即使它们不使用相同的虚拟映射。实际上,这与两个进程拥有自己的虚拟地址空间是相同的。
然而,最后困扰我的事情是安全方面:

如果两个核心共享整个L2缓存,一个核心是否可以技术上访问另一个核心的缓存数据?

参考资料


你通过这样做想要解决什么问题? - unixsmurf
1
这可能取决于L2缓存PL310或PL4xx的配置,但正如unixsmurf所示,这可能并不有用。 假设任务1受到内存限制,而任务2受到CPU限制,则希望L2适用于第一个任务。 因此,虽然可能是可能的(在给定不同AXI总线接口到L2的情况下),但可能没有好处。 也许有更好的方法来利用你的努力使系统变得更好... - artless noise
1
想一想 - 如果且仅如果两个操作系统实例访问相同的物理地址,它们可能会命中相同的缓存条目 - 如果对两个不同的物理地址的访问能够返回相同的数据,则缓存将从根本上被破坏。如果您真的关心隔离性,请在板上运行SMP Linux与KVM,然后运行单核应用程序VM钉住每个主机CPU。 - Notlikethat
1
你是否正在使用 [tag:trustzone]?L2 感知到了 TrustZone 并会尝试保持 L2-secure 锁定,不被普通世界的 L2 活动所驱逐(L1 同理)。就像 Colin Percival 的 cache miss with hyper-threading 所述,存在远程信息泄漏的风险;但是在 TrustZone 中这更加困难,因为上下文切换的粒度更大。如果您不使用 TrustZone,则任何一个操作系统都可以映射物理内存,而缓存只是其中最小的问题。 - artless noise
1
HDL是硬件描述语言。ARM为L2逻辑提供代码,供厂商设置此缓存的参数。他们可能有两个AXI总线接口到L2,并且在这些数据上有某种优先级;但并非所有PL310都具有此功能,因为它是一个参数。在PL310接口中有特征寄存器来确定使用了哪些参数。 - artless noise
显示剩余4条评论
2个回答

4
不使用相同物理内存的两个代码不会引起任何缓存冲突,因为在A7处理器上(带有虚拟化扩展的任何ARM处理器)缓存是物理标记的。在A7上,缓存行也被VM ID标记。因此,如果您想强制执行在两个核心上运行的代码之间的分离,可以为每个核心设置第二级页表,并使用不同的VM ID进行标记。EL0/1违反地址空间的任何行为都会导致陷入EL2(Hypervisor)。这与EL1如何强制实现EL0地址空间的分离非常相似。
要配置这个,您必须要有访问引导代码的权限。通常从安全的EL1/EL3引导代码直接切换到非安全的EL1模式。您将需要修改此流程并改为切换到EL2模式。在EL2模式下,为每个核心设置和启用不相交的第二级页表。还要设置一个EL2向量表以捕获第二级MMU异常。
这将导致性能略微下降。这比使用KVM更有效(上次我检查时,KVM不太适合ARM v7,并且由于设计原因会导致很多开销)。 XEN更适合ARM,但需要您进行大量设置。
如果您不打算使用虚拟化扩展/第二级页表/SMP,则还可以关闭ACTLR.SMP位。这可能会在性能方面带来一些提升,因为L1缓存并发块将被关闭。
注意:本答案适用于编辑后的问题。

谢谢,关于PL分离和ACTLR.SMP位的信息很有用。您能否对此标志再具体一些?对于我的用例来说似乎很有前途,因为我确实不会使用虚拟化扩展。 - cid
1
@cid,恐怕这在A7上行不通。我仔细查看了TRM,基本上缓存将被禁用,并且任何缓存/TLB维护操作或LDREX/STREX操作如果设置了SMP位将会导致中止。A15 TRM似乎暗示禁用SMP位的限制较小,可能可以实现所需的结果(我相信这是两个处理器之间L2缓存架构差异的原因)。这在A15上可能是一个值得尝试的实验,但对于A7来说不是。很抱歉给你带来了错误的性能提升希望。 - Arun Valiaparambil

1
除了作为高速缓存外,L2缓存还有助于不同核心的L1缓存之间的缓存一致性。如果您设法实现(每个核心有私有的L2缓存),则会丢失SMP特性。此外,L2缓存控制器已经负责将所有核心使用的数据/代码加载到缓存中,这比在启动时静态划分缓存更好。

但实际上我不想要任何SMP特性。事实上,我需要相反的东西。它更对应于AMP架构:我希望每个应用程序都能看到并在自己的核心上运行。我理解你关于L2将缓存所有核心使用的数据/代码的观点。然而,它如何处理每个核心都使用自己的虚拟映射的情况呢? - cid
根据手册,Cortex-A7的L2是物理索引、物理标记的,因此没有虚拟别名问题。考虑到一个SMP操作系统运行多个单线程用户进程——每个核心将花费大部分时间在自己的地址空间中运行隔离的应用程序,这听起来很熟悉吧?就我个人而言,除非你有数据证明缓存污染是唯一损害应用程序性能的原因,而且你不可能通过重新设计代码来解决它,否则我会忘记这个问题。如果没有这些,它似乎更像是一个纯粹想象出来的“问题”。 - Notlikethat
@Notlikethat,这可能是一个简单的答案;只需使用不会L2哈希到同一行(每个CPU相邻的128kB物理块)的地址。至少,他可以这样做并查看是否会大幅提高性能。我也相当确定有一种方法可以分区L2缓存,但这取决于实现者设置的HDL参数。 - artless noise

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接