在系统中,有时可能会看到如下警告:

INFO: rcu_sched self-detected stall on CPU   0-...: (9999 ticks this GP) idle=cee/140000000000001/0 softirq=64858/64858 fqs=4891 (t=10000 jiffies g=13416 c=13415 q=68)
Task dump for CPU 0:
my_debug_1      R  running task

这是rcu的cpu停顿警告,也只是一个警告诉你。就是告诉我们,某个cpu长时间没有进行进程切换等其他操作。

几个概念:

静止状态QS(Quiescent State): CPU发生了上下文切换称为经历一个quiescent state;
当所有CPU都经历过静止状态时,才标志着一个宽限期的结束。

静止状态的标志:

  • 在时钟tick中检测CPU处于用户模式或者idle模式,则表明CPU离开了临界区;
  • 在不支持抢占的RCU实现中,检测到CPU有context切换,就能表明CPU离开了临界区;
  • 另外对于 rcu_bh,如果现在没有正在处理软中断或是禁止了软中断,对于 rcu_bh 类型的 RCU 来说,也经历过了一个Quiescent State。

导致RCU警告的情况

导致的原因有很多,下文为内核文档 RCU stallwarn.txt 的部分原文以及对应的翻译:

So your kernel printed an RCU CPU stall warning.  The next question is "What caused it?"  The following problems can result in RCU CPU stall warnings:**所以你的内核打印了一个 RCU CPU 停顿警告。 下一个问题是“是什么引起的?” 以下问题可能导致 RCU CPU 停顿警告:**1. A CPU looping in an RCU read-side critical section.**在 RCU 读取端临界区中循环的 CPU。**2. A CPU looping with interrupts disabled.**禁用中断的 CPU 循环**3. A CPU looping with preemption disabled.  This condition can result in RCU-sched stalls and, if ksoftirqd is in use, RCU-bh stalls.**禁用抢占的 CPU 循环。 这种情况会导致 RCU-sched 停顿,如果 ksoftirqd 正在使用,RCU-bh 停顿。**4. A CPU looping with bottom halves disabled.  This condition can result in RCU-sched and RCU-bh stalls.**禁用下半部分的 CPU 循环。 这种情况会导致 RCU-schedule 和 RCU-bh 停顿。**5. For !CONFIG_PREEMPT kernels, a CPU looping anywhere in the kernel without invoking schedule().  Note that cond_resched() does not necessarily prevent RCU CPU stall warnings.  Therefore, if the looping in the kernel is really expected and desirable behavior, you might need to replace some of the cond_resched() calls with calls to cond_resched_rcu_qs().**对于 !CONFIG_PREEMPT 内核,CPU 在内核中的任何位置循环,而无需调用 schedule()。 请注意, cond_resched() 不一定能阻止 RCU CPU 停顿警告。 因此,如果内核中的循环确实是预期和可取的行为,您可能需要将一些 cond_resched() 调用替换为对 cond_resched_rcu_qs() 的调用**6. Booting Linux using a console connection that is too slow to keep up with the boot-time console-message rate.  For example, a 115Kbaud serial console can be -way- too slow to keep up with boot-time message rates, and will frequently result in RCU CPU stall warning messages.  Especially if you have added debug printk()s.**使用控制台连接引导 Linux,该连接太慢而无法跟上引导时控制台消息速率。 例如,115Kbaud 串行控制台可能太慢而无法跟上启动时的消息速率,并且会经常导致 RCU CPU 停顿警告消息。 特别是如果您添加了调试 printk()s。**7. Anything that prevents RCU's grace-period kthreads from running. This can result in the "All QSes seen" console-log message. This message will include information on when the kthread last ran and how often it should be expected to run.**任何阻止 RCU 的宽限期 kthread 运行的东西。 这可能会导致“所有 QSes 可见”控制台日志消息。 此消息将包含有关 kthread 上次运行的时间以及应该多久运行一次的信息。**8. A CPU-bound real-time task in a CONFIG_PREEMPT kernel, which might happen to preempt a low-priority task in the middle of an RCU read-side critical section.   This is especially damaging if that low-priority task is not permitted to run on any other CPU, in which case the next RCU grace period can never complete, which will eventually cause the system to run out of memory and hang. While the system is in the process of running itself out of memory, you might see stall-warning messages.**CONFIG_PREEMPT 内核中的 CPU 密集型实时任务,它可能会在 RCU 读取端临界区的中间抢占低优先级任务。 如果不允许该低优先级任务在任何其他 CPU 上运行,则这尤其具有破坏性,在这种情况下,下一个 RCU 宽限期将永远无法完成,最终将导致系统内存不足并挂起。 当系统正在耗尽内存时,您可能会看到停顿警告消息。**9. A CPU-bound real-time task in a CONFIG_PREEMPT_RT kernel that is running at a higher priority than the RCU softirq threads. This will prevent RCU callbacks from ever being invoked, and in a CONFIG_PREEMPT_RCU kernel will further prevent RCU grace periods from ever completing.  Either way, the system will eventually run out of memory and hang.  In the CONFIG_PREEMPT_RCU case, you might see stall-warning messages.**CONFIG_PREEMPT_RT 内核中的 CPU 密集型实时任务,它以比 RCU 软中断线程更高的优先级运行。 这将阻止 RCU 回调被调用,并且在 CONFIG_PREEMPT_RCU 内核中将进一步阻止 RCU 宽限期完成。 无论哪种方式,系统最终都会耗尽内存并挂起。 在 CONFIG_PREEMPT_RCU 情况下,您可能会看到停顿警告消息。**10. A hardware or software issue shuts off the scheduler-clock interrupt on a CPU that is not in dyntick-idle mode.  This problem really has happened, and seems to be most likely to result in RCU CPU stall warnings for CONFIG_NO_HZ_COMMON=n kernels.**硬件或软件问题会关闭未处于 dyntick-idle 模式的 CPU 上的调度程序时钟中断。 这个问题确实发生了,并且似乎最有可能导致 CONFIG_NO_HZ_COMMON=n 内核的 RCU CPU 停顿警告。**11. A bug in the RCU implementation.**RCU 实现中的错误。**12. A hardware failure.  This is quite unlikely, but has occurred at least once in real life.  A CPU failed in a running system, becoming unresponsive, but not causing an immediate crash. This resulted in a series of RCU CPU stall warnings, eventually leading the realization that the CPU had failed.**硬件故障。 这不太可能,但在现实生活中至少发生过一次。 CPU 在运行的系统中出现故障,变得无响应,但不会导致立即崩溃。 这导致了一系列 RCU CPU 停顿警告,最终导致人们意识到 CPU 已发生故障。**

导致RCU警告的原因

上述情况都会因为阻止进程切换或CPU的IDLE状态。这样,在其他核心使用RCU的时候,RCU宽限期就会被延长,甚至无限延长。当宽限期超过 /sys/module/rcupdate/parameters/rcu_cpu_stall_timeout 的值的时候,就会打印此消息。

验证

方式1

将多核处理器的某个核心通过自旋锁所住,然后在其他核心使用rcu,看是 call_rcu() 函数注册的回调处理函数是否会被执行。

结果:
回调函数不会被执行,该回调函数会在宽限期结束时执行,但是由于死锁的存在,宽限期被无无限延长,所以,回调函数永远不会执行。

方式2

对于双核设备,将创建两个线程,分别绑定两个核心,然后将两个线程互相锁住。

volatile int a = 0;
volatile int b = 0;int debug_1(void *arg)
{printk("11111 begin\n");msleep(1000);printk("11111 after sleep\n");spin_lock(&sp_lock_1);while(a == 0);b = 1;printk("11111 get lock2\n");spin_lock(&sp_lock_2);printk("11111 over\n");return 0;
}int debug_2(void *arg)
{printk("22222 begin\n");msleep(1000);printk("22222 after sleep\n");spin_lock(&sp_lock_2);a = 1;while(b == 0);printk("22222 get lock1\n");spin_lock(&sp_lock_1);printk("22222 over\n");return 0;
}

结果:
不会打印RCU失速警告,因为死锁过程中没有使用RCU,所以不会打印RCU警告。

RCU检测CPU stall的原理相关推荐

  1. 见微知著:CPU的工作原理

    引言:借助于简单的例子,全面讲了CPU如何工作的,需要慢慢消化的一篇讲解. 引入计算机CPU CPU是Center Processing Unit(中央处理器)的缩写,是计算机的大脑,一旦了解了它的运 ...

  2. 13 种在 Linux 系统上检测 CPU 信息的工具

    13 种在 Linux 系统上检测 CPU 信息的工具 问题: 我想要了解我的电脑关于CPU处理器的详细信息,查看CPU信息比较有效地方法是什么? 根据你的需要,有各种各样的关于你的CPU处理器信息你 ...

  3. 深入理解CPU的调度原理

    前言 软件工程师们总习惯把OS(Operating System,操作系统)当成是一个非常值得信赖的管家,我们只管把程序托管到OS上运行,却很少深入了解操作系统的运行原理.确实,OS作为一个通用的软件 ...

  4. [VT虚拟化驱动]安装DPC回调检测CPU对VT的支持

    文章目录 前言 一.驱动基本框架 二.安装DPC回调 三.检测CPU对VT的支持 本章代码 def.h: DriverEntry.cpp util.cpp 前言 对于VT的介绍网上有很多详细的介绍,这 ...

  5. 性能测试中怎么检测CPU情况

    压测过程,其中最重要的一部分就是检测CPU的运行情况:那么怎么分析判断是否是CPU的原因? 首先查看 QPS,QPS很高,导致cpu自然也高(大流量,水平扩展) 然后看到QPS很低,那么再来看CPU情 ...

  6. 用什么软件能测试cpu好坏,如何检测cpu是否损坏

    作为电脑的核心设备,CPU负责处理运算计算机内部所有数据,一旦发生故障将会使整台电脑瘫痪.下面是学习啦小编跟大家分享的是如何检测cpu是否损坏,欢迎大家来阅读学习. 如何检测cpu是否损坏 工具/原料 ...

  7. 内存错误检测工具——kfence工作原理分析

    一.功能介绍 Linux 5.13引入一个新的内存错误检测工具:KFENCE(Kernel Electric-Fence,内核电子栅栏).KFENCE是一个低开销的.基于采样的内存错误检测工具.KFE ...

  8. 检测cpu是否支持VT

    检测cpu是否支持VT 最近研究云,一个前提基本就是是否支持VT,以前我以为外面的cpu,基本都支持,不过发现不是.只是我的笔记本的cpu,不支持,去年才买的. 检测这个,通过cpu-z好像是不行,需 ...

  9. linux 系统硬件信息检测工具,9种在Linux系统上检测CPU信息的工具

    在Linux中,有许多命令行或基于GUI的工具就能来展示你的CPU硬件的相关具体信息.下面是学习啦小编收集整理的9 种在 Linux 系统上检测 CPU 信息的工具,希望对大家有帮助~~ 9 种在 L ...

最新文章

  1. RESTful之限流Throttling
  2. cf559C. Gerald and Giant Chess(容斥原理)
  3. MySQL 5.0-触发器
  4. [BRF+] 测试ruleset
  5. xvid 数据编码和解码
  6. 基础篇--Java IO--概览
  7. pandas 根据列名索引多列数据_Pandas 数据聚合与分组运算[groupby+apply]速查笔记
  8. C++中关于隐藏的理解
  9. 监督学习 | CART 分类回归树原理
  10. linux总线错误无法删除文件,linux – 系统D-Bus不允许使用conf文件来破坏所有权...
  11. HAOI2008 硬币购物
  12. 《演讲之禅》迷你书免费下载 每小时30000美元的秘诀
  13. Code-NFine:NFine介绍
  14. php宠物管理系统的开题报告,宠物医院管理系统的设计与实现开题报告.doc
  15. php微信公众号群发,php实现微信公众号无限群发,php信公众群发
  16. otg usb 定位_怎样打开安卓手机外接USB功能(即OTG功能)
  17. 经典Bug永流传---每周一“虫”(三十七)
  18. hadoop 清理日志文件
  19. 小白学 Python 爬虫(26):为啥上海二手房你都买不起
  20. Ubuntu下安装PCL1.12.1点云库经验分享

热门文章

  1. vue 本地搜索 js实现本地数据搜索 el-select 模糊搜索
  2. 深度学习调参trick 调参技巧
  3. 条件随机场分词_CodingPark编程公园
  4. 波士顿动力机器狗进公园当保安,驱散聚集人群
  5. 初版ps3安装linux,索尼取消PS3安装Linux系统 向全美旧版玩家巨额赔款
  6. 期货期权的异同(期货期权的异同点)
  7. Mac版ToDesk 安装教程
  8. Windows命令行常用指令
  9. 使用GD32F303RET6 驱动NRF24L01
  10. c语言课程设计实验报告模板,[C语言课程设计实验报告模板.doc