当前位置: 首页 > news >正文

专业网站制作电话关键词爱站网

专业网站制作电话,关键词爱站网,东莞市非凡网站建设,WordPress制作404页面问题描述 某 4.x 内核使用 lkdtm 测试异常注入功能时,在触发 softlockup 后,内核一直检测不到不能触发 panic 自动重启。 排查过程 排查 softlockup 相关内核配置参数是否开启–已经开启排查 sysctl kernel.softlockup_panic 配置是否开启–已经开启排…

问题描述

某 4.x 内核使用 lkdtm 测试异常注入功能时,在触发 softlockup 后,内核一直检测不到不能触发 panic 自动重启。

排查过程

  1. 排查 softlockup 相关内核配置参数是否开启–已经开启
  2. 排查 sysctl kernel.softlockup_panic 配置是否开启–已经开启
  3. 排查 sysctl kernel.panic 配置是否设置 – 正常设置
  4. 排查每个核上的 watchdog_timer_fn hrtimer 定时器事件是否开启

在第四步中,查看 /proc/timer_list 发现只有 0 核上开启了 watchdog_timer_fn,其它核上未开启故而无法检测到 softlockup 与 hardlockup。

为什么其它核上未开启用于 softlockup 检测的 hrtimer 定时器事件?

在定位这个问题前,笔者对于 softlockup 的检测原理有个概要的认识,知道它会在每个 cpu 核上创建一个 hrtimer 定时器来进行检测,既然这个定时器都没有创建,那检测不到异常也是正常的。

另外一个问题就是为什么 0 核上开启了 watchdog_timer_fn 但是也检测不到呢?

在回答这个问题前笔者先分析下第一个问题,粗略扫描代码发现 softlockup 检测功能的开启与 watchdog_cpumask 掩码有关,此掩码配置又会受 housekeeping_mask 掩码内容影响,下面基于 4.x 内核对这一过程进行分析。

watchdog_cpumask 相关代码分析

内核会在 lockup 检测器初始化时,在 NO_HZ_FULL开启及 nohz_full功能运行时将未开启 nohz_full 的 cpu 核掩码写入 housekeeping_mask,此后 housekeeping_mask被拷贝到 watchdog_cpumask 中,否则拷贝 cpu_possible_mask 表示所有的 cpu 核掩码。

此后初始化 softlockup detector,在每个 cpu 核上创建 watchdog_thread 线程,仅在 watchdog_cpumask 使能的每个 cpu 核中唤醒 watchdog_thread 运行,未使能的 cpu 核上创建的 watchdog_thread 不会运行。watchdog_thread 线程模拟看门狗周期性更新 softlockup watchdog,实现类似于“喂狗”的操作。

系统中的 watchdog/x 线程:

[root@localhost]# ps aux |grep watchdog                                                  
root         12  0.0  0.0      0     0 ?        S    02:52   0:00 [watchdog/0]  
root         13  0.0  0.0      0     0 ?        S    02:52   0:00 [watchdog/1]  
root         20  0.0  0.0      0     0 ?        S    02:52   0:00 [watchdog/2]  
root         27  0.0  0.0      0     0 ?        S    02:52   0:00 [watchdog/3]  
root         34  0.0  0.0      0     0 ?        S    02:52   0:00 [watchdog/4]  
root         41  0.0  0.0      0     0 ?        S    02:52   0:00 [watchdog/5]  
root         48  0.0  0.0      0     0 ?        S    02:52   0:00 [watchdog/6]  
root         55  0.0  0.0      0     0 ?        S    02:52   0:00 [watchdog/7]  
root         62  0.0  0.0      0     0 ?        S    02:52   0:00 [watchdog/8]  
root         69  0.0  0.0      0     0 ?        S    02:52   0:00 [watchdog/9]  
root         76  0.0  0.0      0     0 ?        S    02:52   0:00 [watchdog/10] 
root         83  0.0  0.0      0     0 ?        S    02:52   0:00 [watchdog/11] 
root         90  0.0  0.0      0     0 ?        S    02:52   0:00 [watchdog/12] 
root         97  0.0  0.0      0     0 ?        S    02:52   0:00 [watchdog/13] 
root        104  0.0  0.0      0     0 ?        S    02:52   0:00 [watchdog/14] 
root        111  0.0  0.0      0     0 ?        S    02:52   0:00 [watchdog/15] 

watchdog_threads 定义如下:

static struct smp_hotplug_thread watchdog_threads = {.store                  = &softlockup_watchdog,.thread_should_run      = watchdog_should_run,.thread_fn              = watchdog,.thread_comm            = "watchdog/%u",.setup                  = watchdog_enable,.cleanup                = watchdog_cleanup,.park                   = watchdog_disable,.unpark                 = watchdog_enable,
};

相关字段的含义如下:

回调触发时机作用
storethread_fn() 内部访问存储 watchdog 的全局变量
thread_should_run()线程调度时检查决定 watchdog 线程是否需要运行
thread_fn()thread_should_run() 返回 true 时执行执行 watchdog 逻辑,检测软锁
setup()线程创建时(CPU 上线)启用 watchdog,初始化数据
cleanup()CPU 下线,线程销毁释放资源,关闭 watchdog
park()CPU 下线时线程进入暂停状态,不再运行
unpark()CPU 重新上线重新启用 watchdog 线程
thread_comm线程创建时设定 watchdog 线程的名称

这里主要描述 setup 函数与 thread_should_run 及 thread_fn 函数。setup 函数在线程执行时做初始化的操作,这里对应的 watchdog_enable 函数,其代码如下:

static void watchdog_set_prio(unsigned int policy, unsigned int prio)
{struct sched_param param = { .sched_priority = prio };sched_setscheduler(current, policy, &param);
}static void watchdog_enable(unsigned int cpu)
{struct hrtimer *hrtimer = raw_cpu_ptr(&watchdog_hrtimer);/* kick off the timer for the hardlockup detector */hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);hrtimer->function = watchdog_timer_fn;/* Enable the perf event */watchdog_nmi_enable(cpu);/* done here because hrtimer_start can only pin to smp_processor_id() */hrtimer_start(hrtimer, ns_to_ktime(sample_period),HRTIMER_MODE_REL_PINNED);/* initialize timestamp */watchdog_set_prio(SCHED_FIFO, MAX_RT_PRIO - 1);__touch_watchdog();
}

它会初始化用于检测 softlockup 的 hrtimer,此 hrtimer 周期性运行检测是否发生了 softlockup,当检测到有 softlockup 发生时,根据配置触发 panic、打印信息。

同时这里还做了 hardlockup 初始化,老版本内核 hardlockup 使用 perf 注册一个周期性的 nmi 中断,在中断中执行 hardlockup 检测。注意它还将线程的调度策略设置为 SCHED_FIFO 并将优先级设置为最大以优先调度,最后立刻出发了一次喂狗操作,避免错误检测。

thread_should_run 函数的触发时机:

  • 调度器决定是否唤醒 watchdog 线程 时调用。
  • 每次 CPU 进入/退出空闲状态、上下文切换 时都会检查该函数

当返回 true 时调度器会执行 watchdog 线程,返回 false 则不需要执行。

经过上述分析,确定开启了 nohz_full 功能的核上不会使能 softlockup 检测,cat /proc/cmdline 发现我们并未设置 nohz_full 相关内核引导参数,继续阅读内核源码发现它由 NO_HZ_FULL_ALL 配置使能,继续对此配置进行分析。

NO_HZ_FULL_ALL 配置功能分析

内核原文:

config NO_HZ_FULL_ALLbool "Full dynticks system on all CPUs by default (except CPU 0)"depends on NO_HZ_FULLhelpIf the user doesn't pass the nohz_full boot option todefine the range of full dynticks CPUs, consider that allCPUs in the system are full dynticks by default.Note the boot CPU will still be kept outside the range tohandle the timekeeping duty.

如果用户没有传递 nohz_full 启动参数来定义完整的 dynticks cpu 的范围,则默认所有 cpu 都开启此模式。请注意,启动 cpu(cpu 0)仍将保持在范围之外以处理定时任务。

测试记录如下:

 [root@localhost]# dmesg | grep NO_HZ                                                     
[    0.000000] NO_HZ: Clearing 0 from nohz_full range for timekeeping           
[    0.000000] NO_HZ: Full dynticks CPUs: 1-127.   

除引导核外,所有使能了 nohz_full 功能的 cpu 核会从 housekeeping 掩码中去掉,这样在 softlockup 初始化的时候就不会在这些核上启动检测 softlockup 的 hrtimer 定时器事件,这就是内核没有检测到软锁并触发 panic 的根本原因。

同时 softlockup 检测的作用范围是单个核,一个核上的定时器事件只能检测该核上的 softlockup,这样即便 0 核上开启了 softlokcup 检测,但是触发 softlockup 的核非 0 核时,在问题场景也无法正常工作。

内核主线移除 NO_HZ_FULL_ALL 配置的修改:

commit a7c8655b073d89303911c89d0fd9fc4be7631fbe
Author: Paul E. McKenney <paulmck@kernel.org>
Date:   Thu Nov 30 15:36:35 2017 -0800sched/isolation: Eliminate NO_HZ_FULL_ALLCommit 6f1982fedd59 ("sched/isolation: Handle the nohz_full= parameter")broke CONFIG_NO_HZ_FULL_ALL=y kernels.  This breakage is due to the codeunder CONFIG_NO_HZ_FULL_ALL failing to invoke the shiny new housekeepingfunctions.  This means that rcutorture scenario TREE04 now emits RCU CPUstall warnings due to the RCU grace-period kthreads not being awakenedat a time of their choosing, or perhaps even not at all:[   27.731422] rcu_bh kthread starved for 21001 jiffies! g18446744073709551369 c18446744073709551368 f0x0 RCU_GP_WAIT_FQS(3) ->state=0x402 ->cpu=3[   27.731423] rcu_bh          I14936     9      2 0x80080000[   27.731435] Call Trace:[   27.731440]  __schedule+0x31a/0x6d0[   27.731442]  schedule+0x31/0x80[   27.731446]  schedule_timeout+0x15a/0x320[   27.731453]  ? call_timer_fn+0x130/0x130[   27.731457]  rcu_gp_kthread+0x66c/0xea0[   27.731458]  ? rcu_gp_kthread+0x66c/0xea0Because no one has complained about CONFIG_NO_HZ_FULL_ALL=y being broken,I hypothesize that no one is in fact using it, other than rcutorture.This commit therefore eliminates CONFIG_NO_HZ_FULL_ALL and updatesrcutorture's config files to instead use the nohz_full= kernel parameterto put the desired CPUs into nohz_full mode.Fixes: 6f1982fedd59 ("sched/isolation: Handle the nohz_full= parameter")Reported-by: kernel test robot <xiaolong.ye@intel.com>Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>Cc: Frederic Weisbecker <frederic@kernel.org>Cc: Thomas Gleixner <tglx@linutronix.de>Cc: Chris Metcalf <cmetcalf@mellanox.com>Cc: Christoph Lameter <cl@linux.com>Cc: Linus Torvalds <torvalds@linux-foundation.org>Cc: Luiz Capitulino <lcapitulino@redhat.com>Cc: Mike Galbraith <efault@gmx.de>Cc: Peter Zijlstra <peterz@infradead.org>Cc: Rik van Riel <riel@redhat.com>Cc: Wanpeng Li <kernellwp@gmail.com>Cc: Ingo Molnar <mingo@kernel.org>Cc: John Stultz <john.stultz@linaro.org>Cc: Jonathan Corbet <corbet@lwn.net>

linux 内核 v4.15 版本移除了 NO_HZ_FULL_ALL 选项,后续内核版本不存在此问题。

问题延伸:watchdog_cpumask 配置

通过写入 watchdog_cpumask文件能够动态配置 watchdog 线程进入暂停、运行状态以此来使能指定核上的 softlockup 检测。
它保存了掩码的值,不支持特殊的格式,当写入后,内核会通过 park、unpark 机制来暂停、运行指定核上的 watchdog_thread 线程来达到动态配置的效果。

如何解决此问题?

根据分析情况,高版本内核也已经不具备此配置,关闭 CONFIG_NOHZ_FULL_ALL 配置能够解决此问题,这里隐含着一个问题就是对于开启了 nohz_full 的 cpu 核,软硬锁检测功能将会失效。

总结

nohz_full 功能是针对 cpu 性能的一个优化,通过减少 cpu 核上运行的时钟中断来提高程序性能。需要注意的是开启了此功能对现有内核检测机制的影响,例如这里的 softlockup 检测失效的问题。

softlockup 检测作为一种可靠性的功能,此问题的存在表明产品在追求高性能的同时设计中也需要兼顾可靠性能力,有时候这两者可能还存在一些冲突,需要权衡。

http://www.tj-hxxt.cn/news/6210.html

相关文章:

  • 十大收益最好的自媒体平台阜新网站seo
  • 广州地址设计网站网站建设公司哪家好?该如何选择
  • 个人工商注册查询网站网络舆情处置的五个步骤
  • 网站可以做音频线吗网络营销运营策划
  • 个人做旅游网站怎样万物识别扫一扫
  • 重庆网站建设选卓光南京seo排名
  • 代码做网站的软件百度浏览器官网下载
  • 网站有免费的域名和空间么网站seo推广员招聘
  • 国外乡村建设网站网络营销推广方案ppt
  • 3合1网站建设公司企业网站模板设计
  • 深圳做网站知名排行北京seo优化排名
  • 网站开发邮件服务器免费发布信息网平台
  • 做彩票网站的方案关键字查找
  • 广西建设网登录入口seo长尾关键词优化
  • 百度智能小程序是什么青岛seo霸屏
  • 网站的基本建设投资中国十大搜索引擎网站
  • 做网站需要前台和后台吗seo的内容主要有哪些方面
  • 日照做网站的那家做的好外贸推广具体是做什么
  • 地方门户网站如何盈利百度竞价排名的使用方法
  • 网站建设销售实习怎么创建自己的免费网址
  • 北京建设高端网站代运营哪家比较可靠
  • 西双版纳网站建设公司推广网站文案
  • 西安网站开发的空间新乡百度网站优化排名
  • 超实用网站电商平台怎么运营的
  • 泸州网站开发舆情网站直接打开怎么弄
  • 队徽logo在线设计前端seo怎么优化
  • app费用北京网站优化外包
  • 武汉新公司做网站|武昌专业做网站--武汉金宇盈科技有限公司大搜推广
  • 网页设计网站图片seo标题生成器
  • 河南网站排名太原网站建设制作