TDA4时间同步4 网卡添加虚拟时间戳
软件时间戳实现原理
一、内核软件时间戳的整体架构
Linux 网络栈的时间戳分为硬件时间戳和软件时间戳两条路径:
用户态 ptp4l / sock
↓ SO_TIMESTAMPING 标志
内核协议栈
↓
┌─────────────────────────────────────┐
│ TX 路径:skb_tx_timestamp() │ ← 软件TX时间戳
│ RX 路径:net_timestamp() │ ← 软件RX时间戳
├─────────────────────────────────────┤
│ 硬件时间戳:通过 PHC 驱动获取 │
│ (CPTS/AM65-CPTS) │
└─────────────────────────────────────┘
↓
sock 错误队列 / 控制消息
↓
用户态读取
二、关键数据结构
ethtool_ts_info — 声明网卡的时间戳能力:
struct ethtool_ts_info {
u32 so_timestamping; // 支持的时间戳类型位掩码
int phc_index; // 关联的 PHC 设备索引,-1 表示无
...
};
SOF_TIMESTAMPING_* 标志位(定义在 linux/net_tstamp.h):
| 标志 | 含义 |
|---|---|
SOF_TIMESTAMPING_TX_SOFTWARE | 支持 TX 软件时间戳 |
SOF_TIMESTAMPING_RX_SOFTWARE | 支持 RX 软件时间戳 |
SOF_TIMESTAMPING_SOFTWARE | 系统软件时间戳引擎可用 |
这三者是软件时间戳的最小声明集合。如果还支持硬件时间戳,则会额外设置 SOF_TIMESTAMPING_TX_HARDWARE、SOF_TIMESTAMPING_RX_HARDWARE、SOF_TIMESTAMPING_RAW_HARDWARE 等。
三、TX 软件时间戳的工作流程
1. 用户态请求时间戳
应用程序通过 setsockopt 启用时间戳:
int val = SOF_TIMESTAMPING_TX_SOFTWARE | SOF_TIMESTAMPING_SOFTWARE;
setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING, &val, sizeof(val));
内核在 sock 结构中记录此标志。
2. 发送路径记录时间戳
vport_ndo_xmit 中(第1954行):
done_tx:
skb_tx_timestamp(skb); // ← 这里
netdev_tx_sent_queue(netif_txq, pkt_len);
...
skb_tx_timestamp() 的内部逻辑(net/core/timestamp.c):
skb_tx_timestamp(skb)
├── 检查 sock->tsflags 是否包含 SOF_TIMESTAMPING_TX_SOFTWARE
│ ↓ 否则直接返回,零开销
├── 检查 skb->sk 是否存在
│ ↓ 无关联sock则返回
└── __skb_tstamp_tx(skb, SKBTX_SW_TSTAMP)
├── 调用 ktime_get_real() 获取 CLOCK_REALTIME 当前时间
├── 构造 scm_timestamping 结构(3个时间戳槽位,slot[0]填软件时间戳)
├── 通过 sock_queue_err_skb() 将时间戳放入 sock 错误队列
└── 触发 SKB_FCLONE_TIMEFLAG 标记,防止 skb 在完成前被释放
关键点:
- 软件时间戳在
skb_tx_timestamp()调用点取的是 CLOCK_REALTIME,不是 PHC - 调用位置在数据推入 DMA 之前,记录的是"即将发送"的时刻
- 如果
skb->sk为空或未设置SOF_TIMESTAMPING_TX_SOFTWARE,函数立即返回,开销极小
3. 用户态读取时间戳
发送后,应用程序通过 recvmsg() 从 sock 错误队列读取:
struct msghdr msg;
struct iovec iov;
char ctrl[512];
struct cmsghdr *cmsg;
msg.msg_control = ctrl;
msg.msg_controllen = sizeof(ctrl);
recvmsg(fd, &msg, MSG_ERRQUEUE); // 从错误队列读取
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SO_TIMESTAMPING) {
struct scm_timestamping *ts = (void *)CMSG_DATA(cmsg);
// ts->ts[0] = 软件时间戳 (CLOCK_REALTIME)
// ts->ts[1] = 硬件时间戳 (若支持)
// ts->ts[2] = 原始硬件时间戳 (若支持)
}
}
四、RX 软件时间戳的工作流程
RX 软件时间戳由内核网络栈在接收路径自动处理,不需要驱动显式调用。
网卡接收 → DMA完成 → NAPI poll → vport_rx_packets()
↓
napi_gro_receive()
↓
netif_receive_skb() / netif_receive_skb_list()
↓
__netif_receive_skb_core()
↓
net_timestamp(skb) ← 内核自动调用
├── 检查 NETIF_F_RXHASH 等特征
├── 如果 sock 需要 RX 软件时间戳
└── ktime_get_real() → skb->tstamp
↓
送往协议栈 → sock 控制消息
驱动本身不需要在 RX 路径做任何额外工作。只要 ethtool_ts_info 声明了 SOF_TIMESTAMPING_RX_SOFTWARE,内核协议栈会自动处理。
五、get_ts_info 回调的作用
static int vport_get_ts_info(struct net_device *ndev,
struct ethtool_ts_info *info)
{
info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
SOF_TIMESTAMPING_RX_SOFTWARE |
SOF_TIMESTAMPING_SOFTWARE;
info->phc_index = -1;
return 0;
}
这个回调的作用是向用户态声明能力。没有它,ethtool -T eth2 会显示不支持任何时间戳,ptp4l 也不会尝试使用软件时间戳模式:
# 修改前
$ ethtool -T eth2
Time stamping parameters for eth2:
Capabilities:
(无)
# 修改后
$ ethtool -T eth2
Time stamping parameters for eth2:
Capabilities:
software-transmit
software-receive
software
phc_index = -1 表示没有关联的 PTP 硬件时钟(PHC),这是 proxy client 驱动的正确设置——它无法直接访问 CPTS 硬件,因为 CPSW 硬件由 R5F EthFw 服务器管控。
六、软件时间戳 vs 硬件时间戳对比
软件时间戳 硬件时间戳
时间源 CLOCK_REALTIME (系统时钟) PHC (精确硬件时钟)
取戳位置 skb_tx_timestamp() (驱动层) 硬件在帧离开MAC时打戳
取戳时刻 "即将提交DMA" "帧实际发送到线路"
误差来源 系统调度延迟、中断延迟 仅PHY/MAC内部延迟
典型精度 ~10-100 μs ~10-100 ns
需要PHC 否 是
需要phc2sys 否 是(同步PHC与系统时钟)
驱动修改量 约10行(get_ts_info + 头文件) 需要CPTS驱动集成
七、本驱动的特殊性
cpsw-proxy-client 是代理客户端,CPSW 硬件由 R5F EthFw 服务器控制。这意味着:
- 无法直接获取硬件时间戳 — CPTS 寄存器在 R5F 侧,A72 Linux 无法访问
skb_tx_timestamp()已存在 — TI 主线代码已在第1954行调用,说明原始设计就预留了软件时间戳的支持- 缺少的只是能力声明 —
get_ts_info未注册,导致用户态工具无法发现这个能力。本次修改补上了这个缺口
如果将来 EthFw 服务器支持通过 RPMsg 返回硬件时间戳,理论上可以实现硬件时间戳路径,但需要:
- EthFw 在发送完成通知中附带 CPTS 时间戳
- 驱动在 TX 完成回调中解析并调用
skb_hwtstamp_tx() - 声明
SOF_TIMESTAMPING_TX_HARDWARE并绑定 PHC 设备
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)