hung_task_timeout_secs 简单学习

[原文链接]

http://hi.baidu.com/stealth_space/item/2007d93fe93ca28fb711dbac

接上篇 简单学习了解下 hung_task_timeout_secs 相关知识.

OS: 2.6.18-194.32.1.el5 x86_64

# 先从系统中看下 hung_task 相关的参数及其参数值

[sina@localhost ~]$ sudo sysctl -a | grep hung

kernel.hung_task_warnings = 0

kernel.hung_task_timeout_secs = 120

kernel.hung_task_check_count = 4194304

kernel.hung_task_panic = 0

[sina@localhost ~]$

# 源码在此.... (v2.6.37.1)   & 结合看下kernel/sysctl.c更好

# kernel/hung_task.c

/*

 * Detect Hung Task

 *

 * kernel/hung_task.c - kernel thread for detecting tasks stuck in D state

 *

 */

#include <linux/mm.h>

#include <linux/cpu.h>

#include <linux/nmi.h>

#include <linux/init.h>

#include <linux/delay.h>

#include <linux/freezer.h>

#include <linux/kthread.h>

#include <linux/lockdep.h>

#include <linux/module.h>

#include <linux/sysctl.h>

/*

 * The number of tasks checked:

 */

unsigned long __read_mostly sysctl_hung_task_check_count = PID_MAX_LIMIT;

/*

 * Limit number of tasks checked in a batch.

 *

 * This value controls the preemptibility of khungtaskd since preemption

 * is disabled during the critical section. It also controls the size of

 * the RCU grace period. So it needs to be upper-bound.

 */

#define HUNG_TASK_BATCHING 1024

/*

 * Zero means infinite timeout - no checking done:

 */

unsigned long __read_mostly sysctl_hung_task_timeout_secs = 120;

unsigned long __read_mostly sysctl_hung_task_warnings = 10;

static int __read_mostly did_panic;

static struct task_struct *watchdog_task;

/*

 * Should we panic (and reboot, if panic_timeout= is set) when a

 * hung task is detected:

 */

unsigned int __read_mostly sysctl_hung_task_panic =

                CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE;

static int __init hung_task_panic_setup(char *str)

{

    sysctl_hung_task_panic = simple_strtoul(str, NULL, 0);

    return 1;

}

__setup("hung_task_panic=", hung_task_panic_setup);

static int

hung_task_panic(struct notifier_block *this, unsigned long event, void *ptr)

{

    did_panic = 1;

    return NOTIFY_DONE;

}

static struct notifier_block panic_block = {

    .notifier_call = hung_task_panic,

};

static void check_hung_task(struct task_struct *t, unsigned long timeout)

{

    unsigned long switch_count = t->nvcsw + t->nivcsw;

    /*

     * Ensure the task is not frozen.

     * Also, when a freshly created task is scheduled once, changes

     * its state to TASK_UNINTERRUPTIBLE without having ever been

     * switched out once, it musn't be checked.

     */

    if (unlikely(t->flags & PF_FROZEN || !switch_count))

        return;

    if (switch_count != t->last_switch_count) {

        t->last_switch_count = switch_count;

        return;

    }

    if (!sysctl_hung_task_warnings)

        return;

    sysctl_hung_task_warnings--;

    /*

     * Ok, the task did not get scheduled for more than 2 minutes,

     * complain:

     */

    printk(KERN_ERR "INFO: task %s:%d blocked for more than "

            "%ld seconds.\n", t->comm, t->pid, timeout);

    printk(KERN_ERR "\"echo 0 > /proc/sys/kernel/hung_task_timeout_secs\""

            " disables this message.\n");

    sched_show_task(t);

    debug_show_held_locks(t);

    touch_nmi_watchdog();

    if (sysctl_hung_task_panic)

        panic("hung_task: blocked tasks");

}

/*

 * To avoid extending the RCU grace period for an unbounded amount of time,

 * periodically exit the critical section and enter a new one.

 *

 * For preemptible RCU it is sufficient to call rcu_read_unlock in order

 * to exit the grace period. For classic RCU, a reschedule is required.

 */

static void rcu_lock_break(struct task_struct *g, struct task_struct *t)

{

    get_task_struct(g);

    get_task_struct(t);

    rcu_read_unlock();

    cond_resched();

    rcu_read_lock();

    put_task_struct(t);

    put_task_struct(g);

}

/*

 * Check whether a TASK_UNINTERRUPTIBLE does not get woken up for

 * a really long time (120 seconds). If that happens, print out

 * a warning.

 */

static void check_hung_uninterruptible_tasks(unsigned long timeout)

{

    int max_count = sysctl_hung_task_check_count;

    int batch_count = HUNG_TASK_BATCHING;

    struct task_struct *g, *t;

    /*

     * If the system crashed already then all bets are off,

     * do not report extra hung tasks:

     */

    if (test_taint(TAINT_DIE) || did_panic)

        return;

    rcu_read_lock();

    do_each_thread(g, t) {

        if (!max_count--)

            goto unlock;

        if (!--batch_count) {

            batch_count = HUNG_TASK_BATCHING;

            rcu_lock_break(g, t);

            /* Exit if t or g was unhashed during refresh. */

            if (t->state == TASK_DEAD || g->state == TASK_DEAD)

                goto unlock;

        }

        /* use "==" to skip the TASK_KILLABLE tasks waiting on NFS */

        if (t->state == TASK_UNINTERRUPTIBLE)

            check_hung_task(t, timeout);

    } while_each_thread(g, t);

 unlock:

    rcu_read_unlock();

}

static unsigned long timeout_jiffies(unsigned long timeout)

{

    /* timeout of 0 will disable the watchdog */

    return timeout ? timeout * HZ : MAX_SCHEDULE_TIMEOUT;

}

/*

 * Process updating of timeout sysctl

 */

int proc_dohung_task_timeout_secs(struct ctl_table *table, int write,

                  void __user *buffer,

                  size_t *lenp, loff_t *ppos)

{

    int ret;

    ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos);

    if (ret || !write)

        goto out;

    wake_up_process(watchdog_task);

 out:

    return ret;

}

/*

 * 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;

        check_hung_uninterruptible_tasks(timeout);

    }

    return 0;

}

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;

}

module_init(hung_task_init);

 

 

 

[ -EOF- ]

时间: 2025-01-25 10:05:44

hung_task_timeout_secs 简单学习的相关文章

SQL Server中的锁的简单学习

原文:SQL Server中的锁的简单学习 简介     在SQL Server中,每一个查询都会找到最短路径实现自己的目标.如果数据库只接受一个连接一次只执行一个查询.那么查询当然是要多快好省的完成工作.但对于大多数数据库来说是需要同时处理多个查询的.这些查询并不会像绅士那样排队等待执行,而是会找最短的路径执行.因此,就像十字路口需要一个红绿灯那样,SQL Server也需要一个红绿灯来告诉查询:什么时候走,什么时候不可以走.这个红绿灯就是锁.     图1.查询可不会像绅士们那样按照次序进行

使用Promise解决多层异步调用的简单学习心得_javascript技巧

前言 第一次接触到Promise这个东西,是2012年微软发布Windows8操作系统后抱着作死好奇的心态研究用html5写Metro应用的时候.当时配合html5提供的WinJS库里面的异步接口全都是Promise形式,这对那时候刚刚毕业一点javascript基础都没有的我而言简直就是天书.我当时想的是,微软又在脑洞大开的瞎捣鼓了. 结果没想到,到了2015年,Promise居然写进ES6标准里面了.而且一项调查显示,js程序员们用这玩意用的还挺high. 讽刺的是,作为早在2012年就在M

Android编程之View简单学习示例_Android

本文实例讲述了Android编程之View简单学习示例.分享给大家供大家参考,具体如下: View,是Android的一个超类,这个类几乎包含了所有的屏幕类型.每一个View都有一个用于绘图的画布,这个画布可以进行任意扩展. 在游戏开发中叶可以自定义视图(View),这个画布的功能更能满足我们在游戏开发中的需要.在Android中,任何一个View类都只需重写onDraw 方法来实现界面显示,自定义的视图可以是复杂的3D实现,也可以是非常简单的文本形式等. 游戏的核心是不断地绘图和刷新界面,An

简单学习Android TextView

本文为大家分享了TextView的简单学习资料,供大家参考,具体内容如下 XML的几个特殊属性 android:autoLink 用于指定是否将文本转换成可点击的超链接形式,它的属性值有none,web,email,phone,map或all android:drawBottom 用于将图片添加到文本的低端 同理还有上,左,右 android:hint 当文本为空时,默认显示的是什么 android:Grivaity 文本的对齐方式 android:inputType 显示的文本类型 Maina

Android编程之View简单学习示例

本文实例讲述了Android编程之View简单学习示例.分享给大家供大家参考,具体如下: View,是Android的一个超类,这个类几乎包含了所有的屏幕类型.每一个View都有一个用于绘图的画布,这个画布可以进行任意扩展. 在游戏开发中叶可以自定义视图(View),这个画布的功能更能满足我们在游戏开发中的需要.在Android中,任何一个View类都只需重写onDraw 方法来实现界面显示,自定义的视图可以是复杂的3D实现,也可以是非常简单的文本形式等. 游戏的核心是不断地绘图和刷新界面,An

jmx的简单学习

背景 前段时间在看btrace源码和jdk一些源码的时候,经常会看到一些jmx的相关内容.以前对jmx基本是一片空白区,花了点时间学习记录下.   过程 jmx总体架构图:  说明:  1.  Agent : javax.management.MBeanServer实现了Agent的功能,以标准的方式给出了管理系统访问 JMX 框架的接口 2. SubAgent: javax.management.MBeans实现了SubAgent的功能,以标准的方式给出了 JMX 框架访问资源的接口 MBea

neo4j简单学习

背景 最近在一些论坛或者新闻里看到了neo4j,一种擅长处理图形的数据库. 据说非常适合做一些join关系型的查询,所以抽空也看了下相关文档,给自己做个技术储备.   过程 深入学习之前,先在网上找了一下别人的一个学习文档总结,踩在别人的肩膀上总是最快,最有效的学习.   http://blog.csdn.net/gtuu0123/article/details/6384375 http://www.iteye.com/topic/978371 顺着这些思路,逐步查看一些neo4j的相关wiki

简单学习vue指令directive_javascript技巧

本文为大家分享了vue指令directive的使用方法,供大家参考,具体内容如下 1.指令的注册 指令跟组件一样需要注册才能使用,同样有两种方式,一种是全局注册: Vue.directive('dirName',function(){ //定义指令 }); 另外一种是局部注册: new Vue({ directives:{ dirName:{ //定义指令 } } }); 2.指令的定义 指令定义,官方提供了五个钩子函数来供我们使用,分别代表了一个组件的各个生命周期 bind: 只调用一次,指令

.NET分页控件简单学习_实用技巧

这几天无意间看到一个关于分页的帖子,觉得写得挺好的.关于这些东西,自己一直都是只知道原理,却没有真正动手做过,于是研究了一下分页的原理自己动手写了一个十分特别非常简单的分页程序,在这里与大家分享一下.  这个程序取数据使用的ado.net,首先先新建一个取数据的类PageDAl  using System; using System.Collections.Generic; using System.Configuration; using System.Data; using System.D