时间子系统17_hard lockup机制

简介:
//	使能hard lockup探测
//	调用路径:watchdog_enable->watchdog_nmi_enable
//	函数任务:
//		1.初始化hard lockup检测事件
//			2.hard lockup阈值为10s
//		2.向performance monitoring子系统注册hard lockup检测事件
//		3.使能hard lockup检测事件
//	注:
//		performance monitoring,x86中的硬件设备,当cpu clock经过了指定个周期后发出一个NMI中断。
1.1 static int watchdog_nmi_enable(unsigned int cpu)
{
	//hard lockup事件
	struct perf_event_attr *wd_attr;
	struct perf_event *event = per_cpu(watchdog_ev, cpu);
	....
	wd_attr = &wd_hw_attr;
	//hard lockup检测周期,10s
	wd_attr->sample_period = hw_nmi_get_sample_period(watchdog_thresh);
	//向performance monitoring注册hard lockup检测事件
	event = perf_event_create_kernel_counter(wd_attr, cpu, NULL, watchdog_overflow_callback, NULL);
	....
	//使能hard lockup的检测
	per_cpu(watchdog_ev, cpu) = event;
	perf_event_enable(per_cpu(watchdog_ev, cpu));
	return 0;
}

//	换算hard lockup检测周期到cpu频率
1.2 u64 hw_nmi_get_sample_period(int watchdog_thresh)
{
	return (u64)(cpu_khz) * 1000 * watchdog_thresh;
}

//	hard lockup检测事件发生时的nmi回调函数
//	函数任务:
//		1.判断是否发生了hard lockup
//			1.1 dump hard lockup信息
1.3 static void watchdog_overflow_callback(struct perf_event *event,
		 struct perf_sample_data *data,
		 struct pt_regs *regs)
{
	//判断是否发生hard lockup
	if (is_hardlockup()) {
		int this_cpu = smp_processor_id();

		//打印hard lockup信息
		if (hardlockup_panic)
			panic("Watchdog detected hard LOCKUP on cpu %d", this_cpu);
		else
			WARN(1, "Watchdog detected hard LOCKUP on cpu %d", this_cpu);

		return;
	}
	return;
}

//	判断是否发生hard lockup
//	注:
//		如果时钟中断在指定阈值范围内为运行,核心认为可屏蔽中断被屏蔽时间过长
1.4 static int is_hardlockup(void)
{
	//获取watchdog timer的运行次数
	unsigned long hrint = __this_cpu_read(hrtimer_interrupts);
	//在一个hard lockup检测时间阈值内,如果watchdog timer未运行,说明cpu中断被屏蔽时间超过阈值
	if (__this_cpu_read(hrtimer_interrupts_saved) == hrint)
		return 1;
	//记录watchdog timer运行的次数
	__this_cpu_write(hrtimer_interrupts_saved, hrint);
	return 0;
}

//	关闭hard lockup检测机制
//	函数任务:
//		1.向performance monitoring子系统注销hard lockup检测控制块
//		2.清空per-cpu hard lockup检测控制块
//		3.释放hard lock检测控制块
2.1 static void watchdog_nmi_disable(unsigned int cpu)
{
	struct perf_event *event = per_cpu(watchdog_ev, cpu);
	if (event) {
		//向performance monitoring子系统注销hard lockup检测控制块
		perf_event_disable(event);
		//清空per-cpu hard lockup检测控制块
		per_cpu(watchdog_ev, cpu) = NULL;
		//释放hard lock检测控制块
		perf_event_release_kernel(event);
	}
	return;
}

目录
相关文章
|
3月前
|
缓存 负载均衡 Linux
内核:进程与调度机制(笔记)
内核:进程与调度机制(笔记)
59 0
|
4月前
|
存储 网络协议 Java
深入理解Linux网络——内核与用户进程协作之同步阻塞方案(BIO)
在上一部分中讲述了网络包是如何从网卡送到协议栈的(详见深入理解Linux网络——内核是如何接收到网络包的),接下来内核还有一项重要的工作,就是在协议栈接收处理完输入包后要通知到用户进程,如何用户进程接收到并处理这些数据。
驱动开发:内核MDL读写进程内存
MDL内存读写是最常用的一种读写模式,通常需要附加到指定进程空间内然后调用内存拷贝得到对端内存中的数据,在调用结束后再将其空间释放掉,通过这种方式实现内存读写操作,此种模式的读写操作也是最推荐使用的相比于CR3切换来说,此方式更稳定并不会受寄存器的影响。
613 0
驱动开发:内核MDL读写进程内存
|
缓存 前端开发 rax
浅析CPU结构对程序的影响以及熔断原理
## CPU 结构简介 ### CPU 指令结构 * 下表列出了CPU关键技术的发展历程以及代表系列,每一个关键技术的诞生都是环环相扣的,处理器这些技术发展历程都围绕着如何不让“CPU闲下来”这一个核心目标展开。
2358 0