HI3559A系统卡死问题-修复

结论:

1 rtsp_client绑定了cpu3核心,cpu3被占满了,导致vdec线程轮到cpu3执行的时间会变长,导致vdec_get方法不及时,导致vdec缓冲区满了,导致vdec_send失败,导致vdec的vb视频帧vpss增加,如果打开IA,那么VB就不够用了。
2 卡顿的原因,我认为是vdec线程获取视频流时,会调用linux中断或系统调用,当跑到cpu3时,就会变得异常卡顿,返回很慢或不返回,进而导致任何与此进程有关的其他进程也卡顿,比如ps、top等命令
3 尝试解决,设想可以通过把vdec线程绑核心cpu2解决,失败,get_frame仍然有很慢的情况,我估计海思底层的进程在cpu3执行的时候卡住了。
4 彻底解决,问题确定是由于recvfrom失败后的无限循环导致的,在晓熙的帮助下,在live555中找到了释放接口,在recvfrom失败时候调用此接口。

排查比较麻烦,具体如下:

1 第一次问题发生在2020.01.17,当时的rtsp_client用的是老版本,丢帧严重。

(1)内存泄漏,由于系统卡死,ia结果出的非常慢,通常几秒一次,视频缓存的datacenter不断增大,其实不是泄漏,应该是把缓存吃没了
(2)卡死原因,当时因为设备重启,可分析资源不多,从log分析,确实rtsp_client丢了很多帧,所以判断,可能是一些异常帧把海思底层搞挂了,导致系统卡死
(3)海思内存不足,我创建了一个导致海思还存不够的环境,从log来看跟问题设备完全不一样,系统也不卡死,所以当时我就排除了海思的内存不足,我认为是问题(2)的卡死导致海思底层出故障了,
(4)当时的结论,rtsp_client丢帧验证导致海思底层崩溃,更新了rtsp_client继续验证。由于出问题的设备带狗,设备重启了, 留下的可分析资源有限,而且也不能复现,所以只能暂时这样判断,等待复现。

2 2020.02.15,问题复现。

(1)分析日志和当时的日志如出一辙,证明是相同问题。
(2)本次设备不带狗,设备未重启。
(3)经过排查,发现前端相机出流异常卡顿,有时候1S一帧,有时候几秒一帧,系统在不断的重连和等待,我怀疑是这个过程导致了异常。
(4)把配置文件考出,在我自己设备上跑,果然,又出了,问题源头找到。
(5)但是不管它怎样卡,设备不应该挂才对,继续排查,通过日志,我发现我们的帧率监控timer不断的往海思底层设置帧率信息,logmpp有src<dst帧率的错误日志,我怀疑是这个把海思搞挂了。
注掉此timer,果然没有这个日志了,不过跑了一会,又出了。但是程序还是要加上src<dst帧率的判断。
(6)ia的send、detect、posequality、filter等模块打印帧数信息,看不出异常。
(7)hw_vdec的busy_count打印出来,也是正常,感觉是ia的视频帧,并没有泄露,查看vb,我发现一个现象,就是resize以后的帧并没有泄露,原图泄露了,由于两个帧的释放地方相同,再加上前面的打印,
我判定ia模块并没有泄漏内存帧,那到底是哪里泄漏了海思底层的内存,百思不得其解。
(8)继续排查vb,我发现ia使用的视频帧的所有者是user,而还有一些视频帧的所有者是vpss,问题会不会是出在了这个vpss。找到老化正常的设备,果然所有者是vpss的视频帧为0或者为个数,不过刷几下就没了。
查看代码,没有其他使用vpss的模块,我们用的视频帧只有user,那为什么会vpss泄漏视频帧?
(9)梳理下整个流程,视频是vdec->vpss->user,如果没有其他模块使用vpss,那么就是这个环节的vpss泄漏了,但是是绑定的为什么会泄漏,这时候我做了一个大胆的假设,因为前端的视频源非常差每秒<1帧,会不会vdec→vpss后,vpss做了缓存,由于帧不连续,vpss判断此帧不完整,而自己缓存了。下一步验证此假设。
(10)只跑1路视频,打印出vdec_send帧的帧序号和总数,打印出user_get的帧序号和总数。对于单路的情况,vpss并没有缓存的现象,所以我怀疑是不是某一路视频异常,经过排查,发现,是异常视频和正常视频同时存在的时候有这个现象。
但是中午吃过饭后,又出现个奇怪的现象,我中午跑了3路异常视频,1路正常视频,经过一个中午,系统则卡死了,但是这个问题跟16路时候不同,因为VB还有164个剩余,也就是VB还有剩余的时候,系统依然会卡死,我怀疑,问题是正常路的视频,长时间没取一直往通道里面发送导致的。
(11)修改了两处,VDEC线程加打印,且视频帧获取后不送IA,直接释放。发现,系统依然会卡顿、卡死,这个时候vb内存还有剩余,但是前面说的VPSS占用的VB依然很高,说明,系统卡死不是VB不够了导致的。那卡死是不是因为vdec_send失败了导致?
(12)vpss_get的线程注掉,这样vdec_send一会就会返回失败,观察了很久,没有发现卡顿问题,但是我发现一个现象,就是rtsp_client线程把cpu3给占满了。
(13)排查为什么rtsp_client把cpu3占满了,把vdec_send注掉,发现问题依然存在,继续修改代码,把16路视频变成1路,问题依然存在,故此,问题定位。

小结:

解决过程一波三折,一开始定位的是rtsp_client,复现后调试信息增多,觉得不是,是ia的问题,再接着排查vdec,花费了大量时间,依然没有找到根源。不过功夫不负有心人,终于从蛛丝马迹中,最终又定位到rtsp_client把cpu3占满了。
(14)接下来就是分析live555,由于以前没怎么看过源码,分析起来也是比较慢,多亏晓熙提示,使用在windows端加断点的方式分析,加快了速度,下面是我对rtsp和live555的一些总结:
在这里插入图片描述
问题就出在了红色环节,出现了死循环调用recvfrom。过程是这样的,网络环境较差,我们从DS相机中拉的视频流出现了问题,流断了,而且相机使用了linger选项,这就导致我们的select异常了,进而导致recv认为一直有数据,但是由于连接断了,也收不出来数据,继续返回错误,无限循环,耗满了一个cpu核。而对于没有linger选项的视频流,我试了下,不会进入此异常。下面的优化可以解决此问题。一开始我担心外部释放改为内部释放后会不会导致泄漏,或者有其他影响,从代码分析来看,不会重复释放,理论上没有影响,后续进行老化验证。
在这里插入图片描述
(15)老化再次出问题,定位发现是DS相机的流异常断开后,我们重连成功,有小概率视频通道0的视频流发送到了信令通道1中,再次造成不收流的死循环,这个问题我暂时不想规避,不是这边的问题,先看DS那边的处理结果。

发布了12 篇原创文章 · 获赞 1 · 访问量 5381

猜你喜欢

转载自blog.csdn.net/kakasxin/article/details/104718503