Skip to content

OCI Command DMA-id 选择器

本页中的所有地址均适用于来自 libtpu-0.0.40-cp314 wheel 的 libtpu.so(构建 libtpu_lts_20260413_b_RC00,build-id md5 89edbbe81c5b328a958fe628a9f2207d)。该镜像剥离;已反混淆的 C++ 符号名按原文逐字引用。.text VMA 等于文件偏移(.text 基址 0xe63c000.rodata 基址 0x84a0000);.data.rel.ro 带有 0x200000 的 VMA→文件增量。所有地址均为 VMA。其他版本会不同。

摘要

一个 OCI command(off-chip-interconnect command)是单个 device trace event,其中携带最多三个嵌入式 DMA 事务,而不是一个。线上 OCI read/write command 记录保留三个 trace_id_header slot(cmd0 / cmd1 / cmd2),每个 slot 命名一个 DMA 事务的身份,另有一个 index_valid bitmask 表示三个 slot 中哪些是有效的。当 profiler 从这些 command 重建 DMA timeline 时,它必须对每个事务回答一个问题:这个事务由哪个 38-bit dma_id 作为 key,这样 command 的 begin event(例如 OciCommonReadCmdIssuedFromEngine,id 22)才能通过共享 dma_id 与它的 completion event(OciCommonCompletedInTcs,id 96)配对。

这个问题由 CmdDmaIdFromEntry<T> 选择器回答:六个字节相同的模板实例化(每个 OCI command message type T 一个)接收 command message 和一个 int selector(事务索引 0..2),根据 index_valid bitmask 对选择进行门控,读取 trace_id_header_cmd{selector},并从该 header 的 {transaction_id, core_id, chip_id} 组合出 38-bit 复合 dma_id。分发器 TraceEntryWrapper<pxc>::GetDmaId(int) 读取线上 trace_point_id,验证 command 的 protobuf oneof 判别值,并把六个 OCI command id(22、23、26、54、55、96)路由到匹配的 helper;而所有其他(单 header)trace id 会落入一个无 selector 的尾部,从一个内联 trace_id_header 组合出相同的 38-bit 布局。

本页负责三件事,重新实现者必须全部做对:

  • 六个 CmdDmaIdFromEntry<T> 选择器:每个服务哪个 OCI command,int selector → trace_id_header_cmd{0,1,2} 映射(cpp offset msg + 0x18 + 8·selector)、index_valid bit-selector 门控、到 TraceIdHeader_globals_ 默认实例的 null-pointer fallback,以及按字节精确的 38-bit dma_id 组合。
  • OCI command 携带的三个 header bandtrace_id_header_cmd0/1/2(三个嵌入事务的身份 key,位于 cpp +0x18/+0x20/+0x28)、逐事务 index_valid 有效 bitmask(+0x30),以及逐事务 id_index0/1/2+0x34/+0x38/+0x3c),它们来自嵌入式 FileDescriptorProto 池和 parse-table FieldEntry cpp offset。
  • id → routing 绑定GetDmaId(int) 分发(trace_point_id → oneof check → helper)、作为 routing key 的 38-bit dma_id,以及 consumer ConvertTpuTraceToXPlane<pxc> 如何以它为 key 在 absl::flat_hash_map<uint64, DmaTransfer> 中配对 begin/end,形成一个 DMA timeline span。consumer 调用 GetDmaId(0),即只用 selector 0 / cmd0

范围 — 四个 id 的 ICR Node-Fabric DMA band decode(ids 48/50/51/91,egress/ingress span 重建)见 ../routing/icr-node-fabric-dma.md,这里只链接,不复制。那些 command 暂存的片内描述符见 intra-chip-descriptor.md。本页负责 OCI command DMA-id 选择器、command 携带的三个 header band,以及 id→routing 绑定

选择器xprof::tpu::CmdDmaIdFromEntry<…pxc::profiler::OciCommon…> — 六个实例化
选择器 VA0xf69a500 / 0xf69a560 / 0xf69a5c0 / 0xf69a620 / 0xf69a680 / 0xf69a6e0(字节相同)
分发器TraceEntryWrapper<…pxc::profiler::TraceEntry>::GetDmaId(int) @ 0xf699ca0
OCI command id22, 23, 26, 54, 55, 96(线上 trace_point_id
Header bandtrace_id_header_cmd0/1/2 @ cpp +0x18/+0x20/+0x28(最多 3 个嵌入事务)
有效门控index_valid(uint32,proto f4,cpp +0x30)— 必须设置 bit selector
dma_id 宽度38 bits = transaction_id[0:21] | (core_id&7)<<21 | (chip_id&0x3fff)<<24
默认 fallback…pxc::profiler::TraceIdHeader_globals_(全零 → dma_id == 0
ConsumerConvertTpuTraceToXPlane<pxc>GetDmaId(0) @ 0xf26c8d9flat_hash_map<uint64, DmaTransfer>
证据等级可重新实现级 / 已确认(按字节锚定于 IDA 反编译 + FDP 池)

1. OCI command 作为带嵌入 DMA 事务的 command 记录

OCI command band 是 deepsea read/write COMMAND trace:由一个引擎向 off-chip interconnect 发出的 command,在其旅程中的多个点被观测到(issued from engine、accepted at the memory node、completed at the TensorCore Sequencer)。关键结构事实是:一个 command event 编码一到三个 DMA 事务,每个事务由自己的 trace_id_header 标识。

六个 OCI command message 类共享一个 protobuf schema;该 schema 在六者之间按字节完全一致,并已同时对照 FileDescriptorProto 字段列表和 parse-table FieldEntry cpp offset 交叉检查:

proto #字段名类型cpp offwire tag角色
1trace_id_header_cmd0message0x180x0a嵌入式 DMA 事务 #0 身份(band 0)
2trace_id_header_cmd1message0x200x12嵌入式 DMA 事务 #1 身份(band 1)
3trace_id_header_cmd2message0x280x1a嵌入式 DMA 事务 #2 身份(band 2)
4index_validuint320x300x20逐事务有效 bitmask(bit N = cmdN live)
5id_index0uint320x340x28事务 #0 id-index(线上 17-bit)
6id_index1uint320x380x30事务 #1 id-index
7id_index2uint320x3c0x38事务 #2 id-index
8node_typeenum0x400x40command 端点类别(NodeTypeValues

Message 布局:vtable @0InternalMetadata @0x8,hasbits @0x10,三个 submessage pointer cmd0/cmd1/cmd2 @0x18/0x20/0x28index_valid @0x30id_index0/1/2 @0x34/0x38/0x3cnode_type @0x40。dtor 精确释放 +0x18/+0x20/+0x28 处的三个 submessage pointer(每个都是 TraceIdHeader);ctor 将 0x10..0x43 清零,因此三个 pointer 起始为 null。这些 offset 正是选择器的读取位置(§2)。

三个 trace_id_header_cmd0/1/2 是本页负责的三个 header band。每一个都是 command 触发的一个 DMA 事务的身份。index_valid bitmask 表示三个 band 中哪些已填充:发出单个 DMA 的 command 只设置 bit 0;扇出到三个事务的 command 设置 bit 0、1、2。id_index0/1/2 是 17-bit 逐事务索引(它们的确切作用是 queue slot、descriptor-ring pointer 还是 re-order tag,不属于 dma_id key;见 §6)。

1.1 嵌入式 TraceIdHeader(逐事务身份)

三个 header band 中每个都是一个 TraceIdHeader submessage。它的三个字段是 38-bit dma_id 的唯一来源:

proto #字段名类型cpp offwire tagdma_id bits
1transaction_iduint320x180x08[0:21]
2core_idenum0x1c0x10[21:24] (& 7)
3chip_iduint320x200x18[24:38] (& 0x3fff)

core_idTraceIdHeaderCoreIdValues(pxc / BarnaCore 代际):0=RESERVED, 1=NONCORE, 2=TC0, 3=TC1, 4=BC0, 5=BC1, 6=BC2, 7=BC3。SparseCore 代际会用 SC0..SC3 替换 BC0..BC3(跨代重命名);字段宽度和 & 7 mask 不变。

node_typeNodeTypeValues,即 command 端点类别:

text
0 = NODE_TYPE_TCS   1 = NODE_TYPE_BC    2 = NODE_TYPE_CMQ   3 = NODE_TYPE_HBMQ
4 = NODE_TYPE_UHI   5 = NODE_TYPE_ICR   6 = NODE_TYPE_QNM
```text

> **注意 —** `node_type` 标记 command 的端点(哪个片上 node 类发出/接收它),是 payload 字段,**不是** `dma_id` key 的一部分,也**不会**被选择器读取。同一个枚举也出现在 OCI-message band 上;见 [`../routing/icr-node-fabric-dma.md`](../routing/icr-node-fabric-dma.md) §2.2。

---

## 2. 六个 `CmdDmaIdFromEntry<T>` 选择器

每个 OCI command message type `T` 都有一个 `CmdDmaIdFromEntry<T>(const T& msg, int selector)` 模板实例化。所有六个函数体都**按字节相同**:同一个 C++ 模板被发出六次,差异只在模板名 relocation 和每个 type 的 `*_globals_` 默认实例地址。选择器回答的问题是:*“如果该事务有效,请给出此 command 的第 `selector` 个嵌入式 DMA 事务的 `dma_id`。”*

| selector VA | template type `T`(OCI command message) | 线上 id | `oneof`(proto f,位于 `entry+0x28`) |
|-------------|------------------------------------------|------------|------------------------------------|
| `0xf69a500` | `OciCommonReadCmdIssuedFromEngine` | 22 | 15 |
| `0xf69a560` | `OciCommonMemReadReqFromEngine` | 23 | 16 |
| `0xf69a5c0` | `OciCommonWriteCmdAcceptedAtMn` | 26 | 19 |
| `0xf69a620` | `OciCommonOciWriteCommand` | 54 | 35 |
| `0xf69a680` | `OciCommonOciReadCommand` | 55 | 36 |
| `0xf69a6e0` | `OciCommonCompletedInTcs` | 96 | 53 |

> 六个反编译函数体逐字节相同。函数体如下(展示 selector `0xf69a500`;其他五个仅 `T` 和 `*_globals_` 地址不同):

```c
// CmdDmaIdFromEntry<…OciCommonReadCmdIssuedFromEngine>(a1 = const T& msg, a2 = int selector)
unsigned __int64 CmdDmaIdFromEntry(__int64 a1, unsigned int a2)
{
  // index_valid (uint32 @msg+0x30) >> selector
  unsigned __int64 v3 = (unsigned __int64)*(unsigned int *)(a1 + 48) >> a2;
  unsigned __int64 result = 0;                       // present = 0 (absent)
  if ( a2 <= 2 && (v3 & 1) != 0 )                    // selector in 0..2 AND index_valid bit set
  {
    // trace_id_header_cmd{selector} pointer @ msg + 0x18 + 8*selector
    TraceIdHeader **v5 = *(TraceIdHeader ***)(a1 + 8LL * a2 + 24);
    if ( !v5 )
      v5 = &TraceIdHeader_globals_;                  // null submessage → all-zero default instance
    return  ((_DWORD)v5[3]        & 0x1FFF00)        // transaction_id[8:21]  (header +0x18)
          | (( *((_DWORD *)v5 + 7) & 7u)   << 21)    // core_id[0:3]   << 21  (header +0x1c)
          | ((unsigned __int64)((_DWORD)v5[4] & 0x3FFF) << 24)  // chip_id[0:14] << 24 (header +0x20)
          |  (unsigned __int8)*((_DWORD *)v5 + 6);   // transaction_id[0:8]   (header +0x18)
  }
  return result;                                     // selector > 2 OR bit clear → present = 0
}

结果会包装在 std::optional<unsigned long> 中:组合出的 38-bit 值加上 presence bit(组合路径上 dl = 1,absent 路径上为 0)。absent 结果会导致 consumer 丢弃该 entry(它不是 DMA 配对事件)。

2.1 selector → trace_id_header 映射

int selector事务索引。它通过对 message 做简单 pointer arithmetic 来索引三个 header band:

selector选择字段proto #cpp offset (msg + 0x18 + 8·sel)含义
0trace_id_header_cmd0f1msg + 0x18第 1 个嵌入式 DMA 事务
1trace_id_header_cmd1f2msg + 0x20第 2 个嵌入式 DMA 事务
2trace_id_header_cmd2f3msg + 0x28第 3 个嵌入式 DMA 事务
≥ 3(越界)返回 absent(present = 0

边界 a2 <= 2 会在使用索引前拒绝 0..2 以外的任何 selector,因此 8·selector 索引只能访问三个 header slot。

2.2 index_valid 门控

text
rsi = msg.index_valid (uint32 @ msg+0x30)
rsi >>= selector
if (rsi & 1) == 0  →  return absent (present = 0)
```text

`index_valid`(proto f4)是逐事务有效 bitmask:bit N 表示“事务 N 存在,且 `trace_id_header_cmd{N}` 有意义”。携带一个 DMA 的 command 设置 bit 0;扇出到三个事务的 command 设置 bit 0/1/2。如果请求的 `selector` 对应 bit 未置位,选择器返回 absent,事务被丢弃,即使 command 记录在物理上为全部三个 header slot 预留了空间。

### 2.3 null-pointer fallback

如果 `index_valid` bit `selector` *已*设置,但 `cmd{selector}` submessage pointer 为 null(`msg[+0x18 + 8·sel] == 0`),选择器会替换为 proto-runtime 默认实例 `…pxc::profiler::TraceIdHeader_globals_`。该块全为零,因此组合出的 `dma_id` 为 0(且 `present = 1`)。实践中,置位的 valid-bit 意味着已构造 submessage;这是 protobuf 默认实例安全路径,用来保证读取是全函数的。

> **注意 —** 选择器会**两次**读取 header 的 `transaction_id` 来跨字节边界组装 21-bit 字段:`(transaction_id & 0x1FFF00)` 覆盖 bits `[8:21]`,`(uint8)transaction_id` 覆盖 bits `[0:8]`。朴素地读一次 `transaction_id & 0x1FFFFF` 是等价且更简单的;二进制中的两次读取形式是编译器产物,不是语义差异。重新实现者应把 `transaction_id` 当成一个单独的 21-bit 字段。

---

## 3. 38-bit 复合 `dma_id`(routing key)

选择器从选中的 header 的三个字段组合出一个 38-bit 标识符。这个复合值是 **routing key**,即决定事务落入哪个 timeline slot、从而决定哪个 begin event 与哪个 end event 配对的值。

```text
dma_id = (transaction_id & 0x1FFFFF)            // bits [0:21]   21-bit per-transaction txn id
       | ((core_id  & 0x7)    << 21)            // bits [21:24]   3-bit core_id enum
       | ((chip_id  & 0x3FFF) << 24)            // bits [24:38]  14-bit chip id
present = 1
字段来源(header offset)maskshiftid bits
transaction_id+0x180x1FFFFF0[0:21]
core_id+0x1c0x721[21:24]
chip_id+0x200x3FFF24[24:38]

chip-id 字段在这个 pxc build 中宽 14 bits(& 0x3FFF);早期代际使用更窄的(12-bit)chip id,后续硅片扩大到 14 bits。完整结果为 38 bits。这与 ICR Node-Fabric DMA band 对其单 header dma_id 提取使用的 bit 布局相同:OCI command 选择器和 NF-band 提取器会收敛到一种复合 ID 格式,因此一个事务的 id 可以跨两个 band 比较。

按字节精确的组合出现在两个地方:每个 CmdDmaIdFromEntry<T> 选择器(§2 函数体),以及用于单 header trace id 的 GetDmaId(int) 无 selector 尾部(LABEL_172,§4)。二者都读取 header +0x18 处的 transaction_id+0x1c 处的 core_id+0x20 处的 chip_id,并发出相同的 0x1FFF00 | (core_id&7)<<21 | (chip_id&0x3fff)<<24 | (uint8)transaction_id 表达式。


4. 分发器:GetDmaId(int)(id → selector → routing key)

TraceEntryWrapper<…pxc::profiler::TraceEntry>::GetDmaId(int) @ 0xf699ca0 是把一个 live trace entry 转换为 dma_id 的入口。它解引用 wrapper 到达底层 TraceEntryv2 = *(entry + 0x10)),从 trace header(+0x18)读取线上 trace_point_id,并对其 switch(0x96 arm jump table,经过 ≤ 0x95 边界检查,default → return 0)。

这个 switch 有两类 arm:

(a) 六个 OCI command arm。 对 id 22/23/26/54/55/96,arm 会验证 protobuf oneof 判别值(*(v2 + 0x28) == <oneof>),加载 live command-payload submessage pointer(v2 + 0x20),或在 oneof 不匹配时使用该 command 的 *_globals_ 默认实例,然后尾调用匹配的 CmdDmaIdFromEntry<T> 选择器,把原始 int 参数作为 selector 转发:

c
case 22:  // OciCommonReadCmdIssuedFromEngine
  if ( *(_DWORD *)(v2 + 40) == 15 )                 // oneof case 15 active?
    v7 = *(...*)(v2 + 32);                           // live command payload  (entry+0x20)
  else
    v7 = &OciCommonReadCmdIssuedFromEngine_globals_; // default instance
  return CmdDmaIdFromEntry<…OciCommonReadCmdIssuedFromEngine>(v7, a2 /* selector */);

case 55:  // OciCommonOciReadCommand
  if ( *(_DWORD *)(v2 + 40) == 36 )
    v9 = *(...*)(v2 + 32);
  else
    v9 = &OciCommonOciReadCommand_globals_;
  return CmdDmaIdFromEntry<…OciCommonOciReadCommand>(v9, a2);
// …id 23 (oneof 16), id 26 (oneof 19), id 54 (oneof 35), id 96 (oneof 53) identical shape
```text

**(b) 单 header 尾部。** 每个*其他* trace id(OCI/UHI/CMQ/ICI/NF 单 header event,以及 ICR band id 48/50/51/91)都在 entry-submessage 的 `+0x18` 处携带正好一个内联 `TraceIdHeader`。这些 arm 会加载该 header(或每个 id 对应的 `*_globals_`,或最终在 null 时使用 `TraceIdHeader_globals_`),然后落入公共尾部 `LABEL_172`,组合出与 §3 **相同**38-bit 布局。该尾部是选择器组合的无 selector twin。

```c
LABEL_172:
  v3 = *((_DWORD *)v6 + 6);                          // transaction_id  (header +0x18)
  v4 =  ((unsigned int)v3 & 0x1FFF00)
      | ((*((_DWORD *)v6 + 7) & 7) << 21)            // core_id         (header +0x1c)
      | ((unsigned __int64)((_DWORD)v6[4] & 0x3FFF) << 24);  // chip_id  (header +0x20)
  return v4 | (unsigned __int8)v3;

线上 id → oneof 映射(id 22 → 15,23 → 16,26 → 19,54 → 35,55 → 36,96 → 53)精确匹配 OCI command oneof 字段号,并且每个 arm 都把 entry+0x20(live payload)/ *_globals_(fallback)转发到选择器。default arm 返回 0(absent)。


5. id → routing 绑定(consumer)

GetDmaId(int) 在该单元中只有一个调用者ConvertTpuTraceToXPlane<…pxc::profiler::TraceEntry> @ 0xf26c8d9,这一点由完整 .text rel32 扫描证明。调用者以 selector 0 调用它:

c
DmaId = TraceEntryWrapper<…pxc::profiler::TraceEntry>::GetDmaId(v14, 0);  // selector 0 = cmd0
// test presence bit; if absent → drop (not a DMA-pairing event)
// else: DmaId is the key into flat_hash_map<uint64, DmaTransfer>
```text

38-bit `dma_id` 作为 key 进入 `absl::flat_hash_map<unsigned long, xprof::tpu::(anon)::DmaTransfer>`(policy `FlatHashMapPolicy<unsigned long, DmaTransfer>`;通过 `PrepareInsertSmallNonSoo` / `PrepareInsertLarge` 插入;key 由 `Hash<long>` 哈希)。共享同一 `dma_id` 的 begin 和 end event 会落入**同一个** `DmaTransfer` slot,生成一个 begin/end span。该 map 随后由 `MergeOverlappingTransfers` → `ConvertDmaTransfersToXPlane` 排空为 device XEvent。

这就是 *routing*:`dma_id` 把 command 的事务路由到单个 timeline slot,从而:

```text
OciCommonReadCmdIssuedFromEngine (id 22)  ── begin marker ─┐
                                                            ├─ same dma_id → one DmaTransfer span
OciCommonCompletedInTcs          (id 96)  ── end marker ───┘

已确认-部分 — consumer 只以 cmd0 为 key。GetDmaId(int) 在这里恰好从唯一调用点被调用,且始终使用 selector = 0。selector 模板支持 selector 1/2(可提取第 2/第 3 个嵌入事务的 dma_id),但该单元中没有 consumer 请求它们:multi-transaction OCI command 是否曾由不同 pass(或更新代际 builder)拆成多个 timeline span,在该二进制中未验证。pxc DMA timeline 以第一个嵌入事务的 dma_id 配对。

5.1 这里与 ICR Node-Fabric band 的差异

OCI command band(本页)和 ICR Node-Fabric DMA band(../routing/icr-node-fabric-dma.md)是进入同一个 flat_hash_map<uint64, DmaTransfer> 机制的两条不同路径,但它们由不同代码读取:

OCI command band(本页)ICR Node-Fabric DMA band
Trace ids22, 23, 26, 54, 55, 9648, 50, 51, 91
每个 event 的 header 数最多 3 个(cmd0/1/2,由 index_valid 门控)正好 1 个(内联 trace_id_header
dma_id 提取器CmdDmaIdFromEntry<T>(msg, selector)GetDmaId 每 id arm → 单 header 尾部
Begin/end 配对command issued (22/26) ↔ completed (96),相同 dma_iddescriptor (91) / egress-msg (50);ICI first/last packet (48)
负责内容command DMA-id 选择器 + 3 个 header band + id→routing48/50/51/91 payload decode + egress/ingress span

二者使用完全相同的 38-bit dma_id 布局(§3)和相同的 flat_hash_map policy,因此无论一个事务是在 command band 还是 NF band 上被观测到,它的 id 都是同一个值;这正是让两个 band 中属于同一事务的 event 能够归并的原因。


6. 选择器不决定什么

注意 — 选择器只读取所选 header 的 {transaction_id, core_id, chip_id}index_valid 门控。OCI command 记录上的其他所有内容都会被 selector 路径丢弃:

  • id_index0/1/2+0x34/+0x38/+0x3c 处的 17-bit 逐事务索引)会被解码进 proto,但不是 dma_id key 的一部分。它们的语义角色,即 command-queue slot、descriptor-ring pointer,还是区别于 transaction_id 的 re-order tag,在这里为 LOW / unverified;没有定位到将其作为 timeline key 读取的 consumer。
  • node_type+0x40)标记端点类别,但不选择 lane,也不作为 slot 的 key。
  • DmaTransfer 配对内部的 begin/end 判别,即哪个 trace_point_id 标记一个 span 的 begin(id 22/26)与 end(id 96),以及 MergeOverlappingTransfers 如何折叠相同 dma_id 的 event,是 DmaTransfer 结构自身的逻辑,不是选择器的逻辑;它随 band decode 记录,而不是记录在这里。

这些六个选择器的逐代(vfc/vlc/glc/gfc)等价物不在范围内:这里的 GetDmaId(int) 是 pxc-template 实例化;新代际是否发出自己的 CmdDmaIdFromEntry<gen::profiler::OciCommon…> 选择器(带原生 14-bit chip id 和 SparseCore core_id 重命名),或以不同方式折叠 command DMA band,均未验证;这里没有搜索逐代选择器符号。


7. 参考偏移

OCI command messageOciCommonOciReadCommand 及其五个 sibling,schema 相同):vtable @0InternalMetadata @0x8,hasbits @0x10trace_id_header_cmd0 @0x18 / cmd1 @0x20 / cmd2 @0x28(submessage ptr),index_valid @0x30id_index0/1/2 @0x34/0x38/0x3cnode_type @0x40。dtor 释放三个 cmd* submessage(每个都是 TraceIdHeader,alloc 0x28 B);ctor 将 0x10..0x43 清零(三个 ptr 起始为 null)。

TraceIdHeader(pxc):transaction_id @0x18 · core_id @0x1c · chip_id @0x20。默认 prototype …pxc::profiler::TraceIdHeader_globals_(全零 → dma_id == 0)。

**关键位置:**六个选择器 0xf69a500 / 0xf69a560 / 0xf69a5c0 / 0xf69a620 / 0xf69a680 / 0xf69a6e0(字节相同)· 分发器 GetDmaId(int) 0xf699ca0(jump table 0x96 arms,bound 0x95,default-drop)· 分发器内的 OCI command arm:id 22(oneof 15)、id 23(16)、id 26(19)、id 54(35)、id 55(36)、id 96(53)· 单 header 尾部 LABEL_172 · consumer ConvertTpuTraceToXPlane<pxc> GetDmaId(0) 调用点 0xf26c8d9(单一调用者)· flat_hash_map<uint64, DmaTransfer> insert PrepareInsertSmallNonSoo / PrepareInsertLarge

dma_id 布局: transaction_id[0:21] (0x1FFFFF) | core_id[21:24] (&7 <<21) | chip_id[24:38] (&0x3fff <<24) → 38 bits。


交叉引用

  • ../routing/icr-node-fabric-dma.md — 四个 id 的 ICR Node-Fabric DMA band(48/50/51/91):共享相同 38-bit dma_idflat_hash_map<uint64, DmaTransfer> 机制的 payload decode 与 egress/ingress span 重建。
  • ../routing/nf-descriptor.md — cross-chip 事务暂存的线上 Node-Fabric DMA 描述符记录。
  • intra-chip-descriptor.md — 片内 OciDescriptorCommonIssuedFromTcs 描述符:OCI command 的事务所引用的片上 DMA。
  • rolled-strided-general.md — 填充这些描述符的 rolled / strided / general 传输体发射器。
  • host-device-dma.md — host↔device DMA 路径(MemcpyH2D / MemcpyD2H lane),一个 sibling timeline band。
  • uhi-host-interface.md — UHI host-interface band(NODE_TYPE_UHI),另一个 OCI 端点类别。