问题现象和背景描述:
我司XX项目, 在进行Tiotest,memory 碎片化等专项测试过程中,出现定屏黑屏等现象,问题出现概率较高。
操作步骤:
手机开机运行memory专项测试相关apk, 启动后,手机静置,3-5分钟,手机出现定屏或者黑屏hang机现象,按power键,点击屏幕均无反应。
问题分析过程:
比较幸运,该问题比较容易复现,而且能够通过adb 进行现场调试,所以可以立刻着手分析。
1.使用TOP命令查看系统整体状态: top –d 3 –m 20
从TOP信息中,可以看到:
1>memory 充足,没有异常。
2>当前系统进程总数771,运行状态的进程1个。
3>当前user 用户空间CPU占用率686%, sys内核空间CPU占用率77%,结合下面的进程信息,发现
10643这个进程CPU占用率非常高,达到721%(8核CPU 占用率最高800%)。
2.使用TOP命令查看进程的状态: top –p 10643
pid 10643的进程 virt,res,shr 等内存信息正常,但是CPU的占用率高达725%
3. 查看系统平均负载: uptime
系统的平均负载在3分钟之内增加了超过一倍,并且还在不断增加,已经出现了明显异常。 到这里问题的初步原因应该比较明显了,系统平均负载已经严重过高。
4.如何理解平均负载:
平均负载:是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数,它和CPU使用率并没有直接关系。
可运行状态的进程:是指正在使用CPU或者等待CPU的进程,也就是ps命令可以看到的处于R(running)状态的进程
不可中断状态的进程:是指正处于内核态关键流程中的进程,并且这些流程不可打断,比如常见的I/O响应,也就是我们PS命令中看到的D(Disk sleep)状态的进程。
一般当平均负载高于CPU数量70%的时候,就应该排查负载高的问题,一旦负载过高可能导致进程响应变慢,进而影响服务的正常功能,我们这个异常的平均负载已经达到CPU数量的300%,非常明显的问题了。
5.查看系统虚拟内存统计: vmstat 3
1>si/so 接近0,说明虚拟内存从磁盘的读写操作很少,系统当前内存状态良好。
2>bi/bo: 接近0 ,说明当前i/o操作不频繁,不会影响系统负载。
3>in: 为0,说明每秒中中断次数为0。
4>cs:CPU上下文切换次数是减少的,说明CPU没有进行频繁的的上下文切换。
5>wa:说明I/O等待的时间为0。
6>id:CPU idle时间很小,说明CPU很忙,有进程一直占用CPU。
7>b:说明系统不可中断进程有6个,也就是D状态进程。
通过上述解析,可以明确下一步重点检查D状态进程。
6.查看D状态的进程信息: ps –A | grep “D”
查看调用栈1:
ufshcd resume 会调用ufshcd_set_dev_pwr_mode,发生block。
查看调用栈2:
ufshcd_err_handler 检测到 resume 失败的error。
查看调用栈3:
scsi 检测 scmd_eh_abort_handler : 发生commnd timeout 超时,从而产生 ufshcd abort 。
查看调用栈4:
f2fs 文件系统 writepage,发生block。
问题结论
至此,问题结论就比较明确了,ufs设备在 runtime resume时候调用 ufshcd_set_dev_pwr_mode,发 生异常,以及后面出现 cmd 超时等错误,导致系统进程发生严重阻塞,系统平均负载严重超标,从而出现定屏,黑屏等无相应问题。系统的分析过程就结束了,后面问题转给storage驱动工程师,结合kmsg log, 进一步分析ufs驱动报错原因。
延伸思考
-
定屏/hang机是工程师在项目debug过程中经常遇到的系统问题,如果没有触发dump,经常会无从下手, 这时平均负载的指标就非常有用,我们可以通过平均负载的指标一步步定位问题。
-
导致平均负载过高的因素很多,常见的如I/O,CPU 上下文切换频繁等因素,但是在本例中这些指标都正常,一定要记得 “D”状态进程,可能元凶就藏在里面。
-
我们要学会通过各种性能工具,先从宏观上明确问题方向(CPU占用率,平均负载,memory, I/O),再逐步定位细节,有时候反而能更快速定位问题。