当前位置:网站首页>kernel hung_task死锁检测机制原理实现
kernel hung_task死锁检测机制原理实现
2022-08-04 22:50:00 【szembed】
1、实现原理分析
Linux的进程存在多种状态,可在include/linux/sched.h中查看。
-
/* Used in tsk->state: */
-
#define TASK_RUNNING 0x0000
-
#define TASK_INTERRUPTIBLE 0x0001
-
#define TASK_UNINTERRUPTIBLE 0x0002
-
#define __TASK_STOPPED 0x0004
-
#define __TASK_TRACED 0x0008
-
/* Used in tsk->exit_state: */
-
#define EXIT_DEAD 0x0010
-
#define EXIT_ZOMBIE 0x0020
-
#define EXIT_TRACE (EXIT_ZOMBIE | EXIT_DEAD)
-
/* Used in tsk->state again: */
-
#define TASK_PARKED 0x0040
-
#define TASK_DEAD 0x0080
-
#define TASK_WAKEKILL 0x0100
-
#define TASK_WAKING 0x0200
-
#define TASK_NOLOAD 0x0400
-
#define TASK_NEW 0x0800
-
#define TASK_STATE_MAX 0x1000
-
-
/* Convenience macros for the sake of set_current_state: */
-
#define TASK_KILLABLE (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE)
-
#define TASK_STOPPED (TASK_WAKEKILL | __TASK_STOPPED)
-
#define TASK_TRACED (TASK_WAKEKILL | __TASK_TRACED)
-
-
#define TASK_IDLE (TASK_UNINTERRUPTIBLE | TASK_NOLOAD)
-
-
/* Convenience macros for the sake of wake_up(): */
-
#define TASK_NORMAL (TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE)
-
-
/* get_task_state(): */
-
#define TASK_REPORT (TASK_RUNNING | TASK_INTERRUPTIBLE | \
-
TASK_UNINTERRUPTIBLE | __TASK_STOPPED | \
-
__TASK_TRACED | EXIT_DEAD | EXIT_ZOMBIE | \
-
TASK_PARKED)
其中有一种状态等待为TASK_UNINTERRUPTIBLE,称为D状态,处于该种状态下进程不接收信号,只能通过wake_up唤醒。处于这种状态的情况有很多,例如mutex锁就可能会设置进程于该状态,down信号量也有可能使进程处于该状态
-
static noinline
void __sched
-
__mutex_lock_slowpath(
struct mutex *
lock)
-
{
-
__mutex_lock(
lock, TASK_UNINTERRUPTIBLE,
0, NULL, _RET_IP_);
-
}
-
static noinline
void __sched
__down(
struct semaphore *sem)
-
{
-
__down_common(sem,
TASK_UNINTERRUPTIBLE,
MAX_SCHEDULE_TIMEOUT);
-
}
有时候进程在等待某种IO资源就绪时(wait_event机制)会设置进程进入该状态。一般情况下,进程处于该状态的时间不会太久,但若IO设备出现故障或者出现进程死锁等情况,进程就可能长期处于该状态而无法再返回到TASK_RUNNING态。因此,内核为了便于发现这类情况设计出了hung task机制专门用于检测长期处于D状态的进程并发出告警。本文分析内核hung task机制的源码并给出改进建议。
本文基于linux kernel 5.13.6版本源码为例进行分析,源代码位于kernel/hung_task.c。监控时间间隔通常为120s,在defconfig中进行定义CONFIG_DEFAULT_HUNG_TASK_TIMEOUT

2、代码解析
实现并不是很复杂,接下来我们对关键代码进行走读。


hung_task_call_panic用来控制是否触发panic复位,该配置默认为true。

3、总结
D状态死锁一般在底层驱动开发的过程中比较常见,如果代码规模比较庞大的话对于开发人员来讲不太容易定位,linux内核提供的这种hung task机制,开发人员只需要根据这些输出的定位信息就可以快速的进行定位。
不足:原生的hung_task也有自己的不足之处,因为在实际的应用中,我们对于不能kill掉的守护进程还是有需求的,比如通信相关进程、维测相关进程等,因此要想兼容此场景,就需要对原生hung_task机制进行改造,有两种方式:在检测时可以对指定的进程进行检查,或者对指定的进程不做检查。
附:
常见的进程状态有哪些?
R 是 Running 或 Runnable 的缩写,表示进程在 CPU 的就绪队列中,正在运行或者正在等待运行。
D 是 Disk Sleep 的缩写,也就是不可中断状态睡眠(Uninterruptible Sleep),一般表示进程正在跟硬件交互,并且交互过程不允许被其他进程或中断打断。
Z 是 Zombie 的缩写,它表示僵尸进程,也就是进程实际上已经结束了,但是父进程还没有回收它的资源(比如进程的描述符、PID 等)。
S 是 Interruptible Sleep 的缩写,也就是可中断状态睡眠,表示进程因为等待某个事件而被系统挂起。当进程等待的事件发生时,它会被唤醒并进入 R 状态。
I 是 Idle 的缩写,也就是空闲状态,用在不可中断睡眠的内核线程上。前面说了,硬件交互导致的不可中断进程用 D 表示,但对某些内核线程来说,它们有可能实际上并没有任何负载,用 Idle 正是为了区分这种情况。要注意,D 状态的进程会导致平均负载升高, I 状态的进程却不会。
边栏推荐
- 剑指Offer | 数值的整数次方
- Redis understanding
- the warmest home
- 单片机原理[一] 学好单片机必会的五张图
- SQL Server 调用 WebService
- Linux系统重启和停止Mysql服务教程
- 质量管理大师爱德华·戴明博士经典的质量管理14条原则
- 【2020】【Paper Notes】Metasurfaces: Multifunctional and Programmable——
- 字节跳动秋招提前批高频面试问题汇总!(内附答案!)
- Will we still need browsers in the future?(feat. Maple words Maple language)
猜你喜欢
随机推荐
ANT1.7 download and configuration method
Service Mesh落地路径
Qt中的常用控件
How to right use of WebSocket in project
Jbpm3.2 开发HelloWorld (简单请假流程)客户端
2022/8/4 树上差分+线段树
the warmest home
Controller层代码这么写,简洁又优雅!
边缘检测——(纯享版)
go语言的time包介绍
typeScript-闭包函数的使用
后排乘客不系安全带?事故瞬间被甩出
视频gif如何制作?试试这个视频制作gif神器
线上虚拟展馆展示具有哪些优势
Leaflets of three bouquet of roses
BUG | 接口返回异常数据
使用代理对象执行实现类目标方法异常
从“草原牛”到“数字牛”:蒙牛的数字化转型之道
postman接口测试
【游戏建模模型制作全流程】ZBrush蜥蜴模型雕刻教程








![Rt-thread [三] link.lds链接脚本详解](/img/80/d62360d0a281b89dcfff61cb2f21ce.png)

