You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Ubuntu 22.04.3中RealTek RTL8125网卡IEEE-1588/PTP硬件时间戳支持问题及ptp4l崩溃解决求助

Ubuntu 22.04.3中RealTek RTL8125网卡IEEE-1588/PTP硬件时间戳支持问题及ptp4l崩溃解决求助

我有一台搭载技嘉B650 AORUS ELITE AX主板的台式机,安装了Ubuntu 22.04.3系统,想把它作为IEEE-1588(Precision Time Protocol,PTP)主时钟,在一个仅包含非管理交换机和一台待同步设备的小型局域网中使用。

初始问题:无硬件时间戳支持,软件模式稳定性不足

启动ptp4l时我发现系统中没有/dev/ptpX节点,用ethtool -T检查网卡接口后,发现它似乎不支持硬件时间戳;而软件时间戳模式下,同步稳定性完全达不到我的需求——偏移量无法稳定在1000ns以内,还经常出现±100000ns的大幅跳变:

$ ethtool -T enp8s0

Time stamping parameters for enp8s0:

Capabilities:
software-transmit
software-receive
software-system-clock
PTP Hardware Clock: none
Hardware Transmit Timestamp Modes: none
Hardware Receive Filter Modes: none

通过lspci确认网卡型号为RealTek RTL8125 2.5GbE控制器:

$ lspci | grep Ethernet
08:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8125 2.5GbE Controller (rev 05)

根据RealTek的官方资料,这款网卡应该支持PTP硬件时间戳,于是我尝试了官方提供的2.5G/5G Linux驱动(r8125版本9.012.04)。虽然官方标注该驱动仅支持到内核6.4,但我当前内核是6.5.0-15-generic,还是尝试编译安装了——编译时我在Makefile中开启了PTP支持,安装后ethtool -T确实显示硬件时间戳功能已启用:

ethtool -T enp8s0

Time stamping parameters for enp8s0:

Capabilities:
hardware-transmit
software-transmit
hardware-receive
software-receive
software-system-clock
hardware-raw-clock
PTP Hardware Clock: 0
Hardware Transmit Timestamp Modes:
off
on
Hardware Receive Filter Modes:
none
ptpv2-l4-event
ptpv2-l4-sync
ptpv2-l4-delay-req
ptpv2-event
ptpv2-sync
ptpv2-delay-req

新问题:ptp4l启动后直接崩溃

但当我启动ptp4l时,进程直接被杀死,内核日志中出现了空指针解引用的错误:

$ sudo ptp4l -i enp8s0 -p /dev/ptp0 -m
ptp4l[2665.771]: selected /dev/ptp0 as PTP clock
Killed

查看dmesg的错误日志片段:

[ 2891.569055] BUG: kernel NULL pointer dereference, address: 0000000000000000
[ 2891.569059] #PF: supervisor instruction fetch in kernel mode
[ 2891.569061] #PF: error_code(0x0010) - not-present page
...(省略中间栈追踪及模块信息)
[ 2891.915727] note: ptp4l[7502] exited with irqs disabled

尝试过的其他方案

我发现apt仓库中有r8125-dkms包,但这个版本(9.007.01)默认未开启PTP支持,安装后ethtool -T依然显示无硬件时间戳。我尝试修改/usr/src/下的Makefile并重新用dkms安装,但没有效果——而且该版本和RealTek官方的9.012.04差异很大,由于内核PTP相关结构体已变更,直接添加PTP支持会导致编译失败。

当前排查进展

目前我还没找到完整解决方案,但排查中发现了关键线索:内核的ptp_clock_info结构体移除了adjfreq成员,替换为adjfine。RealTek官方的9.012.04驱动确实没有设置adjfreq,但也没有实现新的adjfine等必要成员函数,而现在内核的ptp_clock_adjtime函数会调用adjfine

static int ptp_clock_adjtime(struct posix_clock *pc, struct __kernel_timex *tx)
{
struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
struct ptp_clock_info *ops;
...
ops = ptp->info;
...
} else if (tx->modes & ADJ_FREQUENCY) {
long ppb = scaled_ppm_to_ppb(tx->freq);
if (ppb > ops->max_adj || ppb < -ops->max_adj)
return -ERANGE;
err = ops->adjfine(ops, tx->freq);
ptp->dialed_frequency = tx->freq;
}
...
return err;
}

我尝试用空函数“伪造”这些未实现的函数,但ptp4l会卡在port 1: assuming the grand master role步骤无法继续。看起来我要么需要修改tx->modes的使用逻辑(目前不知道具体操作方法),要么就得正确实现驱动中的这些函数。目前我已经联系了驱动维护团队,但还未收到回复。

希望有人能帮我解决这个问题,不管是通过调整ptp4l配置、打驱动补丁还是其他方法。我最核心的需求是实现稳定的PTP同步,当然能用上硬件时间戳是最优选择。

备注:内容来源于stack exchange,提问作者Douglas B

火山引擎 最新活动