Linux内核死锁检测机制【转】
转自:http://www.oenhan.com/kernel-deadlock-check
死锁就是多个进程(线程)因为等待别的进程已占有的自己所需要的资源而陷入阻塞的一种状态,死锁状态一旦形成,进程本身是解决不了的,需要外在的推动,才能解决,最重要的是死锁不仅仅影响进程业务,而且还会占用系统资源,影响其他进程。所以内核中设计了内核死锁检测机制,一旦发现死锁进程,就重启OS,快刀斩乱麻解决问题。之所以使用重启招数,还是在于分布式系统中可以容忍单点崩溃,不能容忍单点进程计算异常,否则进行死锁检测重启OS就得不偿失了。
内核提供自旋锁、信号量等锁形式的工具,具体不再赘述。
Linux内核死锁主要分为分为两种:D状态死锁和R状态死锁。
一、D状态死锁检测
D状态死锁:进程长时间处于TASK_UNINTERRUPTIBLE而不恢复的状态。进程处于TASK_UNINTERRUPTIBLE状态,不响应其他信号(kill -9),保证一些内核原子操作不被意外中断。但这种状态时间长就表示进程异常了,需要处理。
内核D状态死锁检测就是hung_task机制,主要代码就在kernel/hung_task.c文件。
具体实现原理:
1.创建Normal级别的khungtaskd内核线程,在死循环中每隔sysctl_hung_task_timeout_secs时间后check一下,用schedule_timeout定时(节约定时器浪费的CPU)。
2.调用do_each_thread,while_each_thread宏遍历所有的进程信息,如果有D状态进程,则检查最近切换次数和task计算是否一致,即最近是否有调度切换,如果一致,则没有切换,打印相关信息,并根据sysctl_hung_task_panic开关决定是否重启。
对应用户态控制的proc接口有:
/proc/sys/kernel/hung_task_timeout_secs,hung_task_panic等。
二、R状态死锁检测
R状态死锁:进程长时间处于TASK_RUNNING 状态抢占CPU而不发生切换,一般是,进程关抢占后一直执行任务,或者进程关抢占后处于死循环或者睡眠,此时往往会导致多个CPU互锁,整个系统异常。
补充:lockdep不是所谓的死锁。
内核R状态死锁检测机制就是lockdep机制,入口即是lockup_detector_init函数。
1.通过cpu_callback函数调用watchdog_enable,在每个CPU core上创建SCHED_FIFO级别的实时线程watchdog,其中使用了hrtimer定时器,控制检查周期。
2.hrtimer定时器调用watchdog_timer_fn进行清狗的时间检查,而线程则每次重置清狗时间,如果watchdog_timer_fn发现狗的重置时间已经和当前时间差出危险值,则根据开关进行panic处理。
对应用户态控制的proc接口有:
/proc/sys/kernel/watchdog_thresh,softlockup_panic等。
整个死锁检测机制比较简单,但cpu_callback函数结构性设计巧妙,可以在很多地方参考使用。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
static int __cpuinit
cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
{
int hotcpu = (unsigned long)hcpu;
switch (action) {
case CPU_UP_PREPARE:
case CPU_UP_PREPARE_FROZEN:
watchdog_prepare_cpu(hotcpu);
break;
case CPU_ONLINE:
case CPU_ONLINE_FROZEN:
if (watchdog_enabled)
watchdog_enable(hotcpu);
break;
#ifdef CONFIG_HOTPLUG_CPU
case CPU_UP_CANCELED:
case CPU_UP_CANCELED_FROZEN:
watchdog_disable(hotcpu);
break;
case CPU_DEAD:
case CPU_DEAD_FROZEN:
watchdog_disable(hotcpu);
break;
#endif /* CONFIG_HOTPLUG_CPU */
}
/*
* hardlockup and softlockup are not important enough
* to block cpu bring up. Just always succeed and
* rely on printk output to flag problems.
*/
return NOTIFY_OK;
}
|
—结束—
http://www.oenhan.com/kernel-deadlock-check
Linux内核死锁检测机制【转】的更多相关文章
- Linux 内核死锁
死锁是指多个进程(线程)因为长久等待已被其他进程占有的的资源而陷入阻塞的一种状态.当等待的资源一直得不到释放,死锁会一直持续下去.死锁一旦发生,程序本身是解决不了的,只能依靠外部力量使得程序恢复运行, ...
- Linux内核中锁机制之RCU、大内核锁
在上篇博文中笔者分析了关于完成量和互斥量的使用以及一些经典的问题,下面笔者将在本篇博文中重点分析有关RCU机制的相关内容以及介绍目前已被淘汰出内核的大内核锁(BKL).文章的最后对<大话Linu ...
- 大话Linux内核中锁机制之RCU、大内核锁
大话Linux内核中锁机制之RCU.大内核锁 在上篇博文中笔者分析了关于完成量和互斥量的使用以及一些经典的问题,下面笔者将在本篇博文中重点分析有关RCU机制的相关内容以及介绍目前已被淘汰出内核的大内核 ...
- Linux内核抢占实现机制分析【转】
Linux内核抢占实现机制分析 转自:http://blog.chinaunix.net/uid-24227137-id-3050754.html [摘要]本文详解了Linux内核抢占实现机制.首先介 ...
- Linux内核中锁机制之内存屏障、读写自旋锁及顺序锁
在上一篇博文中笔者讨论了关于原子操作和自旋锁的相关内容,本篇博文将继续锁机制的讨论,包括内存屏障.读写自旋锁以及顺序锁的相关内容.下面首先讨论内存屏障的相关内容. 三.内存屏障 不知读者是是否记得在笔 ...
- Linux内核中锁机制之信号量、读写信号量
在上一篇博文中笔者分析了关于内存屏障.读写自旋锁以及顺序锁的相关内容,本篇博文将着重讨论有关信号量.读写信号量的内容. 六.信号量 关于信号量的内容,实际上它是与自旋锁类似的概念,只有得到信号量的进程 ...
- Linux内核中锁机制之原子操作、自旋锁
很多人会问这样的问题,Linux内核中提供了各式各样的同步锁机制到底有何作用?追根到底其实是由于操作系统中存在多进程对共享资源的并发访问,从而引起了进程间的竞态.这其中包括了我们所熟知的SMP系统,多 ...
- 大话Linux内核中锁机制之信号量、读写信号量
大话Linux内核中锁机制之信号量.读写信号量 在上一篇博文中笔者分析了关于内存屏障.读写自旋锁以及顺序锁的相关内容,本篇博文将着重讨论有关信号量.读写信号量的内容. 六.信号量 关于信号量的内容,实 ...
- 大话Linux内核中锁机制之内存屏障、读写自旋锁及顺序锁
大话Linux内核中锁机制之内存屏障.读写自旋锁及顺序锁 在上一篇博文中笔者讨论了关于原子操作和自旋锁的相关内容,本篇博文将继续锁机制的讨论,包括内存屏障.读写自旋锁以及顺序锁的相关内容.下面首先讨论 ...
随机推荐
- jCanvaScript canvas的操作库
在jcscript.com上下载最新的jCanvaScript.1.5.18.min.js文件 里面有很多关于canvas的方法都已经是封装好了的,只需直接调用,但是要注意调用之前和调用之后都要写: ...
- C语言指针【转】
一.C语言指针的概念 在计算机中,所有的数据都是存放在存储器中的.一般把存储器中的一个字节称为一个内存单元,不同的数据类型所占用的内存单元数不等,如整型量占2个单元,字符量占1个单元等,在前面已有详细 ...
- Go语言【第八篇】:Go语言变量作用域
Go语言变量作用域 作用域为已声明标识符所表示的常量.类型.变量.函数或包在源代码中的作用范围,Go语言中变量可以在三个地方声明: 函数内定义的变量称为局部变量: 函数外定义的变量称为全局变量: 函数 ...
- BZOJ1566:[NOI2009]管道取珠——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=1566 https://www.luogu.org/problemnew/show/P1758 题目 ...
- 洛谷P3759 [TJOI2017]不勤劳的图书管理员 【树状数组套主席树】
题目链接 洛谷P3759 题解 树状数组套主席树板题 #include<algorithm> #include<iostream> #include<cstring> ...
- sql中按in中的ID进行排序输出
builder.OrderBy("charindex(','+convert(varchar,ID)+',',',"+chufenOrder+"') ");
- selenium - webdriver - Keys类(键盘操作)
Keys()类提供了键盘上几乎所有按键的方法,这个类可用来模拟键盘上的按键,包括各种组合键,如 Ctrl+A, Ctrl+X,Ctrl+C, Ctrl+V 等等 from selenium impor ...
- Machine Learning CodeForces - 940F (带修改的莫队)
You come home and fell some unpleasant smell. Where is it coming from? You are given an array a. You ...
- shell中的$* $@
shell中$*与$@的区别 关于$* 和 $@的 一点 认识 同是菜鸟一起学习 $* 所有的位置参数,被作为一个单词. 注意:"$*"必须被""引用. $@ ...
- lightoj 1245
lightoj 1245 Harmonic Number (II) 题意:给定一个 n ,求 n/1 + n/2 + …… + n/n 的值(这里的 "/" 是计算机的整数除法,向 ...