当前位置:网站首页>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 状态的进程却不会。
边栏推荐
猜你喜欢
【字符串函数内功修炼】strcpy + strcat + strcmp(一)
【字符串函数内功修炼】strncpy + strncat + strncmp(二)
备战9月,美团50道软件测试经典面试题及答案汇总
【3D建模制作技巧分享】ZBrush如何设置笔刷快捷键
使用cpolar优化树莓派上的网页(1)
历史上的今天:PHP公开发布;iPhone 4 问世;万维网之父诞生
视频gif如何制作?试试这个视频制作gif神器
基于内容的图像检索系统设计与实现--颜色信息--纹理信息--形状信息--PHASH--SHFT特征点的综合检测项目,包含简易版与完整版的源码及数据!
[Mock Interview - 10 Years of Work] Are more projects an advantage?
应用联合、体系化推进。集团型化工企业数字化转型路径
随机推荐
软件测试技术之如何编写测试用例(4)
得不到你的心,就用“分布式锁”锁住你的人
Ts——项目实战应用enum枚举
Qt中的常用控件
Pytest学习-Fixture
自从新来了个字节20K出来的,就见识到了什么是天花板
学生管理系统架构设计
期货开户哪个平台好,要正规安全的
逆序对的数量
typeScript-promise
【3D建模制作技巧分享】ZBrush如何重新拓扑
JVM memory configuration parameter GC log
Service Mesh落地路径
地面高度检测/平面提取与检测(Fast Plane Extraction in Organized Point Clouds Using Agglomerative Hierarchical Clu)
【转载】kill掉垃圾进程(在资源管理器占用的情况下)
Linux系统重启和停止Mysql服务教程
【3D建模制作技巧分享】ZBrush纹理贴图怎么导入
Shell expect 实战案例
轮播图动态渲染
【字符串函数内功修炼】strcpy + strcat + strcmp(一)