linux 内核Lockup机制浅析

概念说明

Linux内核Lockup就是linux内核占用CPU不放,Lockup分为两种:soft lockup 和 hard lockup。

soft lockup是指CPU被内核代码占据,以至于无法执行其它进程。检测soft lockup的原理是给每个CPU分配一个定时执行的内核线程[watchdog/x],

如果该线程在设定的期限内没有得到执行的话就意味着发生了soft lockup,[watchdog/x]是SCHED_FIFO实时进程,优先级为最高的99,拥有优先运行的特权。

hard lockup比soft lockup更加严重,CPU不仅无法执行其它进程,而且不再响应中断。检测hard lockup的原理利用了PMU的NMI perf event,

因为NMI中断是不可屏蔽的,在CPU不再响应中断的情况下仍然可以得到执行,它再去检查时钟中断的计数器hrtimer_interrupts是否在保持递增,

如果停滞就意味着时钟中断未得到响应,也就是发生了hard lockup。

linux内核的代码实现在kernel/watchdog.c中,

主体涉及到了3个东西:kernel线程,时钟中断,NMI中断(不可屏蔽中断)。

这3个东西具有不一样的优先级,依次是kernel线程 < 时钟中断 < NMI中断。

检测机制

Linux kernel设计了一个检测lockup的机制,称为NMI Watchdog,是利用NMI中断实现的,用NMI是因为lockup有可能发生在中断被屏蔽的状态下,这时唯一能把CPU抢下来的方法就是通过NMI,因为NMI中断是不可屏蔽的。NMI Watchdog 中包含 soft lockup detector 和 hard lockup detector,2.6之后的内核的实现方法如下。

NMI Watchdog 的触发机制包括两部分:

1. 一个高精度计时器(hrtimer),对应的中断处理例程是kernel/watchdog.c: watchdog_timer_fn(),在该例程中:

  • 要递增计数器hrtimer_interrupts,这个计数器供hard lockup detector用于判断CPU是否响应中断;
  • 要唤醒[watchdog/x]内核线程,该线程的任务是更新一个时间戳;
  • soft lock detector检查时间戳,如果超过soft lockup threshold一直未更新,说明[watchdog/x]未得到运行机会,意味着CPU被霸占,也就是发生了soft lockup。

2.基于PMU的NMI perf event,当PMU的计数器溢出时会触发NMI中断,对应的中断处理例程是 kernel/watchdog.c: watchdog_overflow_callback(),

hard lockup detector就在其中,它会检查上述hrtimer的中断次数(hrtimer_interrupts)是否在保持递增,如果停滞则表明hrtimer中断未得到响应,也就是发生了hard lockup。

参数设定

hrtimer的周期是:softlockup_thresh/5。

  • 在2.6内核中:
    softlockup_thresh的值等于内核参数kernel.watchdog_thresh,默认60秒;
  • 而到3.10内核中:
    内核参数kernel.watchdog_thresh名称未变,但含义变成了hard lockup threshold,默认10秒;
    soft lockup threshold则等于(2*kernel.watchdog_thresh),即默认20秒。

NMI perf event是基于PMU的,触发周期(hard lockup threshold)在2.6内核里是固定的60秒,不可手工调整;在3.10内核里可以手工调整,

因为直接对应着内核参数kernel.watchdog_thresh,默认值10秒。

异常处理

检测到 lockup 之后怎么办?可以自动panic,也可输出条信息就算完了,这是可以通过内核参数来定义的:

  • kernel.softlockup_panic: 决定了检测到soft lockup时是否自动panic,缺省值是0;
  • kernel.nmi_watchdog: 定义是否开启nmi watchdog、以及hard lockup是否导致panic,该内核参数的格式是”=[panic,][nopanic,][num]”.

参考: https://www.kernel.org/doc/Documentation/lockup-watchdogs.txt

原文地址:https://www.cnblogs.com/jerry116/p/8799355.html

时间: 2024-10-28 10:28:07

linux 内核Lockup机制浅析的相关文章

浅析Linux内核同步机制

很早之前就接触过同步这个概念了,但是一直都很模糊,没有深入地学习了解过,近期有时间了,就花时间研习了一下<linux内核标准教程>和<深入linux设备驱动程序内核机制>这两本书的相关章节.趁刚看完,就把相关的内容总结一下.为了弄清楚什么事同步机制,必须要弄明白以下三个问题: 什么是互斥与同步? 为什么需要同步机制? Linux内核提供哪些方法用于实现互斥与同步的机制? 1.什么是互斥与同步?(通俗理解) 互斥与同步机制是计算机系统中,用于控制进程对某些特定资源的访问的机制. 同步

[内核同步]浅析Linux内核同步机制

转自:http://blog.csdn.net/fzubbsc/article/details/37736683?utm_source=tuicool&utm_medium=referral 很早之前就接触过同步这个概念了,但是一直都很模糊,没有深入地学习了解过,近期有时间了,就花时间研习了一下<linux内核标准教程>和<深入linux设备驱动程序内核机制>这两本书的相关章节.趁刚看完,就把相关的内容总结一下.为了弄清楚什么事同步机制,必须要弄明白以下三个问题: 什么是互

Linux内核同步机制

http://blog.csdn.net/bullbat/article/details/7376424 Linux内核同步控制方法有很多,信号量.锁.原子量.RCU等等,不同的实现方法应用于不同的环境来提高操作系统效率.首先,看看我们最熟悉的两种机制——信号量.锁. 一.信号量 首先还是看看内核中是怎么实现的,内核中用struct semaphore数据结构表示信号量(<linux/semphone.h>中): [cpp] view plaincopyprint? struct semaph

Linux内核OOM机制的详细分析(转)

Linux 内核 有个机制叫OOM killer(Out-Of-Memory killer),该机制会监控那些占用内存过大,尤其是瞬间很快消耗大量内存的进程,为了 防止内存耗尽而内核会把该进程杀掉.典型的情况是:某天一台机器突然ssh远程登录不了,但能ping通,说明不是网络的故障,原因是sshd进程被 OOM killer杀掉了(多次遇到这样的假死状况).重启机器后查看系统日志/var/log/messages会发现 Out of Memory: Kill process 1865(sshd)

Linux内核同步机制--转发自蜗窝科技

Linux内核同步机制之(一):原子操作 http://www.wowotech.net/linux_kenrel/atomic.html 一.源由 我们的程序逻辑经常遇到这样的操作序列: 1.读一个位于memory中的变量的值到寄存器中 2.修改该变量的值(也就是修改寄存器中的值) 3.将寄存器中的数值写回memory中的变量值 如果这个操作序列是串行化的操作(在一个thread中串行执行),那么一切OK,然而,世界总是不能如你所愿.在多CPU体系结构中,运行在两个CPU上的两个内核控制路径同

Linux内核抢占机制 - 实现

本文首发于 http://oliveryang.net,转载时请包含原文或者作者网站链接. 本文主要围绕 Linux 内核调度器 Preemption 的相关实现进行讨论.其中涉及的一般操作系统和 x86 处理器和硬件概念,可能也适用于其它操作系统. 1. Scheduler Overview Linux 调度器的实现实际上主要做了两部分事情, 任务上下文切换 在 Preemption Overview 里,我们对任务上下文切换做了简单介绍.可以看到,任务上下文切换有两个层次的实现:公共层和处理

Linux内核同步机制之completion【转】

Linux内核同步机制之completion 内核编程中常见的一种模式是,在当前线程之外初始化某个活动,然后等待该活动的结束.这个活动可能是,创建一个新的内核线程或者新的用户空间进程.对一个已有进程的某个请求,或者某种类型的硬件动作,等等.在这种情况下,我们可以使用信号量来同步这两个任务.然而,内核中提供了另外一种机制--completion接口.Completion是一种轻量级的机制,他允许一个线程告诉另一个线程某个工作已经完成. 结构与初始化 Completion在内核中的实现基于等待队列(

linux 内核 RCU机制详解

RCU(Read-Copy Update)是数据同步的一种方式,在当前的Linux内核中发挥着重要的作用.RCU主要针对的数据对象是链表,目的是提高遍历读取数据的效率,为了达到目的使用RCU机制读取数据的时候不对链表进行耗时的加锁操作.这样在同一时间可以有多个线程同时读取该链表,并且允许一个线程对链表进行修改(修改的时候,需要加锁).RCU适用于需要频繁的读取数据,而相应修改数据并不多的情景,例如在文件系统中,经常需要查找定位目录,而对目录的修改相对来说并不多,这就是RCU发挥作用的最佳场景.

linux内核notifier机制 linux通知链

在linux内核系统中,各个模块.子系统之间是相互独立的.Linux内核可以通过通知链机制来获取由其它模块或子系统产生的它感兴趣的某些事件.使用notifier由通知者可以传递给被通知者长整型参数与指针.在linux中有许多地方用到,比如reboot通知,cpu调频通知,网卡事件,电池低电警报等等.熟悉使用notifier有助于linux内核驱动开发. notifier_block结构: struct notifier_block { int (*notifier_call)(struct no