Tofino时间戳机制

时间戳的作用

  1. 调试,例如确定硬件 pipeline 中某个部分的延迟
  2. 确定硬件 pipeline 的总延迟,然后通过 PTP 协议对交换机进行同步

Global Time Counter and Timestamp Information Available

Tofino 有一个全局 Time Counter,由两部分构成,分别是 48-bit Nanosecond component28-bit Fractional component

  • Tofino 芯片的全局时钟速度是 1.22GHz (TF1) 或 1.5GHz (TF2),以 TF1 为例,每个时钟对应约 0.819ns,该值称为 Global Time Counter Increment,会在每个时钟周期增加到 Fractional component Global Time Counter Increment 的默认值通过芯片运行速度自动计算得出,但也可以由用户通过控制面修改
  • 48-bit Nanosecond component 在 Tofino 上次 reset 时,从 0 开始计数;Fractional component 的整数部分每增加 1,Nanosecond component 就增加 1;约 3 天会 roll over 一次(约 78 小时) 时间戳也可以与现实世界的时间同步,但这需要额外硬件

全局 Time Counter 每 1ns 都会向 MAC, Parser 等硬件 block 分发时间信息,可以用来记录数据包在不同处理阶段的时间戳

  • 因此,Tofino 芯片中不同 pipe,不同硬件 block 的时间都是同步的

从 Global Time Counter 发出的时间信息可以在 7 个地方记录

Tofino逐包时间戳
Tofino逐包时间戳

不同 TS 的采样位置:

  • TS1(iTS) 和 TS6(eTS) 分别在 Ingress MAC 和 Egress MAC 采集,其差值代表了数据包在交换机内经历的总时长,用于更新 PTP 协议的 Correction Field 以实现更准确的时间同步
  • TS2 和 TS5 分别在 Ingress parser 和 Egress Parser 采集,与 TS3 / TS6 的差值代表了数据包在两处 Pipeline 中经历的时长
  • TS3 和 TS4 在进出 TM 时采集,代表数据包的排队时延,这部分时延是 P4 交换机中唯一会出现大幅变化的时延

时间戳获取方式

TS1-TS5 自动保存在数据包的 Intrinsic metadata 中,可以直接在 P4 程序中读取(也就是可以附加在数据包头中):

时间戳 类型 元变量 含义
TS1 / iTS ingress_intrinsic_metadata_t bit<48> ingress_mac_tstamp; IEEE 1588 timestamp (ns), taken upon arrival at ingress MAC.
TS2 ingress_intrinsic_metadata_from_parser_t bit<48> global_tstamp; Global timestamp (ns), taken upon arrival at ingress parser.
TS3 egress_intrinsic_metadata_t bit<18> enq_tstamp; // TF1
bit<32> enq_tstamp; // TF2
Global timestamp (ns), taken when the packet is enqueued in the TM.
TS4 (Derived) egress_intrinsic_metadata_t bit<18> deq_timedelta; // TF1
bit<32> deq_timedelta; // TF2
Time delta (ns) between the packet’s enqueue and dequeue in the TM. TS4 can be derived by adding TS3 and deq_timedelta.
TS5 egress_intrinsic_metadata_from_parser_t bit<48> global_tstamp; Global timestamp (ns), taken upon arrival at egress parser.

TS6 和 TS7 不会自动获取,也不能在 P4 程序中直接读取,它们需要通过特殊方式获取:

TS6 / eTS: 无法在 P4 和控制平面中直接读取,但可以在 P4 中通过设置以下 Intrinsic metadata 请求 Egress Mac 直接将值写入数据包:

元变量类型 元变量 含义
egress_intrinsic_metadata_for_output_port_t bit<1> update_delay_on_tx; Request for PTP delay update at egress MAC

设置完以上 metadata 后,获取 TS6 的流程:

  1. 在数据包前附加一个临时的头部用于向 Egress MAC 传参,MAC 会将 TS6 处理后写入数据包指定位置,并可选的更新校验和,最后去除临时头部

  2. 在 Egress Pipeline 中,于 Ethernet 头之前添加以下 Header(即必须是 Packet 的第一个 Header)(定义在 tofino.p4 中,不需要用户提供):

    1
    2
    3
    4
    5
    header ptp_metadata_t {
    bit<8> udp_cksum_byte_offset; // Byte offset at which the egress MAC needs to update the UDP checksum
    bit<8> cf_byte_offset; // Byte offset at which the egress MAC needs to re-insert ptp_sync.correction field
    bit<48> updated_cf; // Updated correction field in ptp sync message
    }
  3. PTP 的 correction field 用于记录目前为止产生的延迟,该 field 共有 64 位,其中高 48 位为 ns 级时间戳;进入交换机时该 field 具有初始值,Tofino 将在初始值上增加 eTS - iTS

    1. 由于 eTS 只能在 Egress MAC 中获取,P4 程序无法完成完整的 correction field 更新,因此实现逻辑应当如下:

      在 P4 程序中读取 correction field 初始值以及 iTS,两者相减后存入 ptp_metadata_t.updated_cf,最后 Egress MAC 将会计算 updated_cf + eTS,并将其存入 cf_byte_offset 指向的位置;

      如果 updated_cf 置为 0,则输出的结果就是 TS6 自身

      Egress MAC 向数据包写 correction field 时不会覆盖 offset 位置的已有数据,而是插入 8 字节新数据(高 6 字节为时间戳,低 2 字节全零)

      如果 correction field 位于 UDP 封装内,还需要更新 UDP 校验和;如果无需更新则设置 udp_cksum_byte_offset 为 0

  4. 注:完整的 PTP 时间戳有 64 位,Tofino 实现中高 16 位仅保留在控制面(控制面判断低 48 位是否 rollover,若发生则高 16 位增加 1),低 48 位体现在 Global Time Counter 中

TS7: 无法在 P4 中直接读取,但可以由控制面读取,通过在 P4 中设置以下 Intrinsic metadata 进行记录

元变量类型 元变量 含义
egress_intrinsic_metadata_for_output_port_t bit<1> capture_tstamp_on_tx; Request for packet departure timestamping at egress MAC for IEEE 1588

Egress Mac 会把 TS7 存入一个深度为 4 的 FIFO 队列中(每个出端口都有一个队列),可以在控制面通过 bf_port_1588_timestamp_tx_get() 接口获取值

由于涉及控制面,TS7 无法在高传输速率时准确获取(队列很快填满并溢出,控制面无法得知本次获取到的值属于哪个数据包)

TS7 的用例:日志、测试、PTP 同步

注:TS6 是数据包到达 Egress MAC 的时间戳,MAC 能够将其记入数据包;TS7 是数据包离开 Egress MAC 的时间戳,因此只能由控制面读取

不同时间戳的精度

TS1 / TS2 / TS5 三个时间戳都是 48 位,直接对应 Global time counter 中 Nanosecond componet 的值

  • 约 3 天(78 小时)会 roll over 一次

TS3 的低 18 或 32 位通过 enq_tstamp 读取,高 30 或 16 位可以通过读取 TS2 获得

  • 18 位的 enq_tstamp 每 262.1us rollover 一次;32 位的 enq_tstamp 每 4.3s rollover 一次
  • 如果 TS2 的低 18/32 位大于 enq_tstamp,则 enq_tstamp 发生 rollover,需要将高 30 或 16 位加 1

TS4 通过在 TS3 上加 deq_timedelta 计算获得

时间戳逻辑

时间戳逻辑
时间戳逻辑

控制面API

用户可以通过控制平面设置以下值:

API 默认值 含义
Global Time Counter 0 全局时钟的当前值
Global Timestamp Offset 平均 PCIe 写操作耗时 由于从控制面设置全局时钟涉及 PCIe 写,该 Offset 用于抵消这一误差
Global Time Counter Increment Tofino 每时钟周期的 ns 数 Tofino 每时钟周期添加到 fraction component 的 ns 数
Global Timestamp Snapshot Interval 1 ns 对全局时钟采样、将其与 Offset 相加、分发给各硬件模块的频率