【问题标题】:Atomicity of small PCIE TLP writes小型 PCIE TLP 写入的原子性
【发布时间】:2020-05-26 21:28:10
【问题描述】:

对于如何从软件进程的角度实现从针对常规内存的 PCIe 设备的卡主机写入,是否有任何保证,其中单个 TLP 写入完全包含在单个 CPU 高速缓存行中?

我想知道我的设备可能会写入一些数据字,后跟一个字节以指示结构现在有效(例如事件完成),例如:

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 次写入,首先写入数据,然后将其标记为有效,这没有任何明显的竞争条件,但当然会增加不必要的开销。

我在这个网站上看到的最相关的问题似乎是Are writes on the PCIe bus atomic?,尽管这似乎与 TLP 的相对顺序有关。

仔细阅读 PCIe 3.0 规范,我没有发现任何似乎明确涵盖了我的担忧的内容,我认为我并不特别需要 AtomicOps。鉴于我只关心与 x86-64 系统的交互,因此我还研究了英特尔架构指南,但也没有更清楚。

本能地,似乎应该有可能以原子方式感知这样的写入——尤其是当它被称为事务时——但同样,我在明确确认该观点的文档方式中找不到太多(我也不太确定我需要看什么,可能是 CPU 供应商?)。我还想知道这样的方案是否可以扩展到多个缓存线——即,如果有效位于从同一个 TLP 事务写入的第二个缓存线上,我可以确保第一个将不迟于第二个被感知吗?

【问题讨论】:

  • 您不一定需要保证原子性,只需发布​​排序以与获取负载同步。即某种保证最后一个字节最后或同时可见,而不是之前。我标记了这个[memory-order],不幸的是它是[memory-barriers] 的标记同义词。我不知道您的实际问题的答案:/
  • 谢谢,这似乎是合理的——我没有考虑过那个标签。

标签: x86-64 atomic memory-barriers pci-e


【解决方案1】:

写入可以分成更小的单元,小到 dwords,但如果是,则必须按地址递增顺序观察它们。

PCIe 第 4 版,第 2.4.3 节:

如果单个写入事务包含多个 DW 和 Relaxed 排序位清除被完成者接受,观察到的排序 完成者数据缓冲区中位置的更新必须是 在增加地址顺序。在 PCI 的情况下需要此语义 或沿路径的 PCI-X 桥接多个写入事务 进入单人。但是,观察到的更新粒度 到 Completer 的数据缓冲区不在此范围内 规范。

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

作为更新示例 排序和粒度,如果请求者将 QW 写入主机内存, 在某些情况下,从主机内存读取 QW 的主机 CPU 可以 观察第一个 DW 更新和第二个 DW 包含旧 价值。

我没有修订版 3 的副本,但我怀疑该语言也在该修订版中。为了帮助您找到它,第 2.4 节是“事务排序”,第 2.4.3 节是“写入事务提供的更新排序和粒度”。

【讨论】:

  • 谢谢,似乎同样的语言适用于 PCIe 3.0。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-04
  • 2011-02-03
  • 2011-09-30
  • 1970-01-01
  • 2017-08-12
相关资源
最近更新 更多