小型PCIE TLP写入的原子性

问题描述 投票:1回答:1

从软件进程的角度来看,一个TLP写入完全包含在一个CPU缓存线中,那么PCIe设备针对常规内存的卡对主机写入是如何实现的,有什么保证吗?

我想知道一种情况,例如我的设备可能会写一些数据字数,后面跟着一个字节来表示结构现在是有效的(例如一个事件完成)。

struct PCIE_COMPLETION_T {
    uint64_t  data_a;
    uint64_t  data_b;
    uint64_t  data_c;
    uint64_t  data_d;
    uint8_t   valid;
} alignas(SYSTEM_CACHE_LINE_SIZE);

我是否可以用一个单一的TLP来写这个结构,这样当软件看到有效成员变为1(之前被软件清零)时,其他数据成员是否也会反映出我所写的值,而不是之前的值?

目前我是进行了2次写入,第一次写入数据,第二次将数据标记为有效,这没有任何明显的竞赛条件,当然也增加了不必要的开销。

我在这个网站上能看到的最相关的问题似乎就是 PCIe总线上的写入是原子的吗? 虽然这似乎与TLP的相对顺序有关。

遍览PCIe 3.0规范,我没有找到任何似乎明确涵盖我所关心的问题的内容,我认为我并不特别需要AtomicOps。鉴于我只关心与x86-64系统的交互,我也翻阅了英特尔架构指南,但也没有找到更明确的内容。

直觉上看来,这样的写应该是可以被原子化地感知的--尤其是据说是一个事务--但同样我也找不到什么文档明确地确认这个观点(我也不太清楚我需要看什么,可能是CPU厂商?我也想知道这样的方案是否可以扩展到多个缓存--也就是说,如果有效的卡位于从同一个TLP事务中写入的第二个缓存上,我是否可以保证第一个缓存不会比第二个缓存晚被察觉?

x86-64 atomic memory-barriers pci-e tlp
1个回答
1
投票

写入可能会被分解成更小的单位,小到dword,但如果是这样,它们必须按照增加地址的顺序来观察。

PCIe修订版4,2.4.3节。

如果一个包含多个DW和RelaxedOrdering位Clear的单次写事务被补全器接受,补全器数据缓冲区内位置更新的观察顺序必须是递增地址顺序。这种语义在沿路径的PCI或PCI-X桥将多个写事务合并为一个事务的情况下是必需的。然而,观察到的补全器数据缓冲区更新的粒度不在本规范的范围内。

虽然本规范没有要求,但强烈建议主机平台保证当PCIExpress写更新主机内存时,主机CPU观察到的更新粒度不会小于DW。

作为更新顺序和粒度的一个例子,如果Required向主机内存写入一个QW,在某些情况下,主机CPU从主机内存中读取该QW时,可能会看到第一个DW被更新,第二个DW包含旧值。

我没有修订版3的副本,但我怀疑这个语言也在那个版本中。为了帮助你找到它,2.4节是 "事务排序",2.4.3节是 "写事务提供的更新排序和粒度"。

© www.soinside.com 2019 - 2024. All rights reserved.