PCIe 总线上的写入是原子的吗?
Are writes on the PCIe bus atomic?
我是 PCIe 的新手,所以这可能是个愚蠢的问题。这似乎是询问有关 PCIe 接口的相当基本的信息,但我找不到答案,所以我猜我遗漏了一些使答案显而易见的信息。
我有一个系统,其中有一个 ARM 处理器(主机)通过 PCIe(设备)与 Xilinx SoC 通信。 SoC 中的端点也是 ARM 处理器。
外部 ARM 处理器(主机)将通过 PCIe 写入 SoC 的 ARM 处理器(设备)的寄存器 space。这将命令 SoC 执行各种操作。该寄存器 space 对于 SoC(设备)将是只读的。外部 ARM 处理器(主机)将写入此寄存器 space,然后发出中断信号以向 SoC 指示已写入新参数并且它应该处理它们。
我的问题是:外部 ARM(主机)进行的写入是否保证相对于 SoC(设备)的读取是原子的?在传统的共享内存情况下,对单个字节的写入保证是一个原子操作(即,你永远不会遇到 reader 已经读取了字节的前 2 位,但在它读取最后 6 位,作者用新值替换它们,导致垃圾数据)。 PCIe也是这样吗?如果是这样,原子性的 "unit" 是多少?单个事务中的所有字节相对于整个事务是原子的,还是每个字节仅相对于自身是原子的?
这个问题有道理吗?
基本上我想知道在我的情况下需要多大程度的内存保护。如果可能的话,我想避免锁定内存区域,因为两个处理器都是 运行 RTOS,避免内存锁定会使设计更简单。
所以关于原子性的问题,PCIe 3.0规范(我只有一个)被提到了几次。
首先你有第 6.5 节锁定交易 这可能不是你需要的,但我还是想记录它。基本上这是您之前描述的最坏情况。
Locked Transaction support is required to prevent deadlock in systems that use legacy software
which causes the accesses to I/O devices
但是无论如何你都需要按照它的说明正确检查使用它。
If any read associated with a locked sequence is completed unsuccessfully, the Requester must
assume that the atomicity of the lock is no longer assured, and that the path between the
Requester and Completer is no longer locked
话虽如此,第 6.15 节原子操作 (AtomicOps) 更像是您感兴趣的内容。您可以使用 AtomicOps 指令执行 3 种类型的操作。
FetchAdd (Fetch and Add): Request contains a single operand, the “add” value
Swap (Unconditional Swap): Request contains a single operand, the “swap” value
CAS (Compare and Swap): Request contains two operands, a “compare” value and a “swap” value
阅读第 6.15.1 节,我们看到提到这些指令主要针对单个总线上存在多个 producers/consumers 的情况实施。
AtomicOps enable advanced synchronization mechanisms that are particularly useful when there are
multiple producers and/or multiple consumers that need to be synchronized in a non-blocking fashion. For example, multiple producers can safely enqueue to a common queue without any explicit locking.
搜索规范的其余部分,我发现除了与这些 AtomicOps 相关的部分之外,几乎没有提及原子性。这对我来说意味着规范仅在使用这些操作时确保此类行为,但是围绕为什么实施此操作的上下文表明他们仅在存在 multi producer/consumer 环境时才会出现此类问题,而您的环境显然不存在。
我建议最后回答你的问题的地方是第 2.4 节交易排序请注意,我相当确定交易的想法 "passing" 其他人才有意义中间有开关,因为这些开关可以做出这样的决定,一旦你把位放在总线上,就没有回头路了。所以这可能只适用于你在其中放置一个开关的情况。
您担心的是写入能否绕过读取。写被发布,读被非发布。
A3, A4 A Posted Request must be able to pass Non-Posted Requests to avoid deadlocks.
所以一般情况下允许写入绕过读取以避免死锁。
考虑到这个问题,我认为写入绕过您系统上的读取是不可能的,因为总线上没有设备可以执行此事务重新排序。因为你有 RTOS,所以我非常怀疑他们在发送之前查询 PCIe 事务并重新排序,尽管我没有亲自调查过。
我是 PCIe 的新手,所以这可能是个愚蠢的问题。这似乎是询问有关 PCIe 接口的相当基本的信息,但我找不到答案,所以我猜我遗漏了一些使答案显而易见的信息。
我有一个系统,其中有一个 ARM 处理器(主机)通过 PCIe(设备)与 Xilinx SoC 通信。 SoC 中的端点也是 ARM 处理器。
外部 ARM 处理器(主机)将通过 PCIe 写入 SoC 的 ARM 处理器(设备)的寄存器 space。这将命令 SoC 执行各种操作。该寄存器 space 对于 SoC(设备)将是只读的。外部 ARM 处理器(主机)将写入此寄存器 space,然后发出中断信号以向 SoC 指示已写入新参数并且它应该处理它们。
我的问题是:外部 ARM(主机)进行的写入是否保证相对于 SoC(设备)的读取是原子的?在传统的共享内存情况下,对单个字节的写入保证是一个原子操作(即,你永远不会遇到 reader 已经读取了字节的前 2 位,但在它读取最后 6 位,作者用新值替换它们,导致垃圾数据)。 PCIe也是这样吗?如果是这样,原子性的 "unit" 是多少?单个事务中的所有字节相对于整个事务是原子的,还是每个字节仅相对于自身是原子的?
这个问题有道理吗?
基本上我想知道在我的情况下需要多大程度的内存保护。如果可能的话,我想避免锁定内存区域,因为两个处理器都是 运行 RTOS,避免内存锁定会使设计更简单。
所以关于原子性的问题,PCIe 3.0规范(我只有一个)被提到了几次。
首先你有第 6.5 节锁定交易 这可能不是你需要的,但我还是想记录它。基本上这是您之前描述的最坏情况。
Locked Transaction support is required to prevent deadlock in systems that use legacy software which causes the accesses to I/O devices
但是无论如何你都需要按照它的说明正确检查使用它。
If any read associated with a locked sequence is completed unsuccessfully, the Requester must assume that the atomicity of the lock is no longer assured, and that the path between the Requester and Completer is no longer locked
话虽如此,第 6.15 节原子操作 (AtomicOps) 更像是您感兴趣的内容。您可以使用 AtomicOps 指令执行 3 种类型的操作。
FetchAdd (Fetch and Add): Request contains a single operand, the “add” value
Swap (Unconditional Swap): Request contains a single operand, the “swap” value
CAS (Compare and Swap): Request contains two operands, a “compare” value and a “swap” value
阅读第 6.15.1 节,我们看到提到这些指令主要针对单个总线上存在多个 producers/consumers 的情况实施。
AtomicOps enable advanced synchronization mechanisms that are particularly useful when there are multiple producers and/or multiple consumers that need to be synchronized in a non-blocking fashion. For example, multiple producers can safely enqueue to a common queue without any explicit locking.
搜索规范的其余部分,我发现除了与这些 AtomicOps 相关的部分之外,几乎没有提及原子性。这对我来说意味着规范仅在使用这些操作时确保此类行为,但是围绕为什么实施此操作的上下文表明他们仅在存在 multi producer/consumer 环境时才会出现此类问题,而您的环境显然不存在。
我建议最后回答你的问题的地方是第 2.4 节交易排序请注意,我相当确定交易的想法 "passing" 其他人才有意义中间有开关,因为这些开关可以做出这样的决定,一旦你把位放在总线上,就没有回头路了。所以这可能只适用于你在其中放置一个开关的情况。
您担心的是写入能否绕过读取。写被发布,读被非发布。
A3, A4 A Posted Request must be able to pass Non-Posted Requests to avoid deadlocks.
所以一般情况下允许写入绕过读取以避免死锁。
考虑到这个问题,我认为写入绕过您系统上的读取是不可能的,因为总线上没有设备可以执行此事务重新排序。因为你有 RTOS,所以我非常怀疑他们在发送之前查询 PCIe 事务并重新排序,尽管我没有亲自调查过。