sem_timedwait_sem_timedwait() 阻塞导致网口单通故障分析

这几天遇到一个网口单通故障,最后定位发现是 sem_timedwait() 阻塞导致,现记录下定位过程。

故障现象

在测试过程中发现,使用 SGMII 对接的两个设备,设备 D1 上的端口显示为 link down,而设备 D2 上的端口显示为 link up,出现了单通的现象。

故障分析

1、为什么会出现单通现象?

对于使用背板实现的 SGMII 接口,出现单通现象的概率极低,首先需要排查的是两边设备是否准确地获取到了端口的 link 状态。通过比较两边设备源码发现,设备 D2 获取端口状态时是直接读取交换芯片的寄存器,而设备 D1 获取端口状态时是读取保存在交换芯片 SDK 中的软件变量。各个端口的 link 状态是通过一个线程定时从硬件读取并保存在上述软件变量中的。

于是在设备 D1 上手动调用交换芯片 SDK 中直接读取端口底层 SerDes 状态的 API,结果确实是 link up 的。也就是说,在底层 SerDes 层面,两边的端口都是 link up 的。由此可见,是设备 D1 的软件层面保存的状态与硬件 SerDes 状态不同步,导致出现了单通的「假象」。

2、为什么硬件状态没有同步到软件变量中?

上述的端口 link 状态同步线程,会每隔 250 ms 将底层 SerDes 状态同步到软件变量中,应用系统在调用相应的 API 获取端口状态时,就是直接返回软件变量中保存的对应端口的 link 状态等信息。从第 1 步的分析可知,在出现故障时,这个线程并没有成功把底层 SerDes 状态同步到软件变量中。

查看 SDK 源码可知,link 状态同步线程在循环中通过调用 sal_sem_take() 获取一个信号量,并设置了 250ms 的超时时间,可能有两种结果:假如在这 250ms 之内,其它线程调用了修改端口速率、接口模式等 API 导致端口状态改变而进一步调用 sal_sem_give() 释放了信号量,则 link 状态同步线程立即获取到信号量并继续执行将状态有变化的端口的最新状态同步到软件变量中,以此识别本端的状态变化。

假如在这 250ms 之内都没有线程调用 sal_sem_give() 做释放信号量操作,则 250ms 之后,sal_sem_take() 将以超时的形式返回,并主动获取底层 SerDes 状态并与保存的状态比较,有变化则相应地更

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值