深度:linux内核调试技术—进程D状态死锁检测

本文介绍了Linux内核中进程的D状态(TASK_UNINTERRUPTIBLE),及其可能导致的死锁问题。内核通过hung task机制来检测长时间处于D状态的进程,当进程超过预设时间未发生调度时,会触发警告或panic。文章详细分析了hung task机制的工作原理,并通过示例展示了如何在系统中引发并检测死锁。
摘要由CSDN通过智能技术生成

【推荐阅读】

深入linux内核架构--进程&线程

浅谈linux 内核网络 sk_buff 之克隆与复制

30分钟了解linux操作系统内核总结

1 TASK_UNINTERRUPTIBLE 状态概述

Linux的进程存在多种状态,如TASK_RUNNING的运行态、EXIT_DEAD的停止态和TASK_INTERRUPTIBLE的接收信号的等待状态等等(可在include/linux/sched.h中查看)。其中有一种状态等待为TASK_UNINTERRUPTIBLE,称为D状态,该种状态下进程不接收信号,只能通过wake_up唤醒。处于这种状态的情况有很多,例如mutex锁就可能会设置进程于该状态,有时候进程在等待某种IO资源就绪时(wait_event机制)会设置进程进入该状态。一般情况下,进程处于该状态的时间不会太久,但若IO设备出现故障或者出现进程死锁等情况,进程就可能长期处于该状态而无法再返回到TASK_RUNNING态。因此,内核为了便于发现这类情况设计出了hung task机制专门用于检测长期处于D状态的进程并发出告警。本文分析内核hung task机制的源码并给出一个示例演示。

2 hung task机制分析

内核在很早的版本中就已经引入了hung task机制,本文以较新的Linux 4.1.15版本源码为例进行分析,代码量并不多,源代码文件为kernel/hung_task.c。首先给出整体流程框图和设计思想:

其核心思想为创建一个内核监测进程循环监测处于D状态的每一个进程(任务),统计它们在两次检测之间的调度次数,如果发现有任务在两次监测之间没有发生任何的调度则可判断该进程一直处于D状态,很有可能已经死锁,因此触发报警日志打印,输出进程的基本信息,栈回溯以及寄存器保存信息以供内核开发人员定位。下面详细分析实现方式:

static int __init hung_task_init(void)
{
    atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
    watchdog_task = kthread_run(watchdog, NULL, "khungtaskd");
 
    return 0;
}
subsys_initcall(hung_task_init);

首先,若在内核配置中启用了该机制,在内核的subsys初始化阶段就会调用hung_task_init()函数启用功能,首先向内核的panic_notifier_list通知链注册回调:

static struct notifier_block panic_block = {
    .notifier_call = hung_task_panic,
};

在内核触发panic时就会调用该hung_task_panic()函数,这个函数的作用稍后再看。继续往下初始化,调用kthread_run()函数创建了一个名为khungtaskd的线程,执行watchdog()函数,立即尝试调度执行。该线程就是专用于检测D状态死锁进程的后台内核线程。

 /*
 * kthread which checks for tasks stuck in D state
 */
static int watchdog(void *dummy)
{
    set_user_nice(current, 0);
 
    for ( ; ; ) {
        unsigned long timeout = sysctl_hung_task_timeout_secs;
 
        while (schedule_timeout_interruptible(timeout_jiffies(timeout)))
            timeout = sysctl_hung_task_timeout_secs;
 
        if (atomic_xchg(&reset_hung_task, 0))
            continue;
 
        check_hung_uninterruptible_tasks(timeout)
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值