时间子系统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;
}
时间: 2024-08-01 16:29:51

时间子系统17_hard lockup机制的相关文章

时间子系统16_soft lockup机制

// 1.debug选项LOCKUP_DETECTOR,开启/关闭kernel中的soft lockup和hard lockup探测 // 2.实现:kernel/watchdog.c // 3.实现原理: // 1.涉及到了3部分内容:kernel线程,时钟中断,NMI中断 // 优先级:kernel线程 < 时钟中断 < NMI中断. // 2.利用它们之间优先级的区别,调试系统运行中的两种问题: // 抢占被长时间关闭而导致进程无法调度(soft lockup) // 中断被长时间关闭而

Linux时间子系统之八:动态时钟框架(CONFIG_NO_HZ、tickless)【转】

转自:http://blog.csdn.net/droidphone/article/details/8112948 版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[-] 数据结构 低分辨率下的动态时钟 1  切换至动态时钟模式 2  低分辨率动态时钟下的事件中断处理函数 3  动态时钟停止周期tick时钟事件 3  动态时钟重新开启周期tick时钟事件 高精度模式下的动态时钟 动态时钟对中断的影响   在前面章节的讨论中,我们一直基于一个假设:Linux中的时钟事件都是由

Linux时间子系统之七:定时器的应用--msleep(),hrtimer_nanosleep()【转】

  转自:http://blog.csdn.net/droidphone/article/details/8104433 我们已经在前面几章介绍了低分辨率定时器和高精度定时器的实现原理,内核为了方便其它子系统,在时间子系统中提供了一些用于延时或调度的API,例如msleep,hrtimer_nanosleep等等,这些API基于低分辨率定时器或高精度定时器来实现,本章的内容就是讨论这些方便.好用的API是如何利用定时器系统来完成所需的功能的. /*************************

时间子系统2_tick device管理机制

// 1.每个cpu都具有一个tick_device,维护周期时钟. // 2.tick_device依赖一个clockevent设备,提供周期事件. // 3.cpu电源状态的改变会影响tick_device,通过tick_notifier监听电源状态. // 4.全局广播设备接管进入省电模式cpu的周期时间维护. // 4.broadcast_mask保存开启广播模式的cpu, broadcast_oneshot_mask保存进入省电模式的cpu. // 监听clockevent设备状态 /

时间子系统12_clockevent设备注册

// 向系统注册时钟事件设备 // 函数任务: // 1.添加设备到clockevent_devices链表 // 2.通知tick device管理机制有clockevent设备注册 1.1 void clockevents_register_device(struct clock_event_device *dev) { unsigned long flags; raw_spin_lock_irqsave(&clockevents_lock, flags); //将设备添加到clockeve

时间子系统9_timekeeper初始化

//Timekeeping // Timekeeping子系统负责更新xtime, 调整误差, 及提供get/settimeofday接口. //Times in Kernel //kernel的time基本类型: // 1) system time // A monotonically increasing value that represents the amount of time the system has been running. // 单调增长的系统运行时间, 可以通过time

时间子系统6_高分辨率定时器框架初始化

// 高分辨率定时器框架初始化 // 调用路径:start_kernel->hrtimers_init // 函数任务: // 1.创建cpu时钟基础 // 2.注册监听cpu状态变化 // 3.注册高分辨率模式下的定时器软中断 // 注: // 1.高分辨率定时器框架的通用部分总是编译进内核 // 2.高分辨率定时器框架初始为未激活状态,由低分辨率定时器软中断中切换到高分辨率 1.1 void __init hrtimers_init(void) { //通知clockevent设备管理,创建

时间子系统14_全局时间维护

// 更新全局时间(由动态时钟调用) // 函数任务: // 1.更新last_jiffies_update,记录距离上次更新jiffies经历的ns // 2.更新jiffies_64,墙上时间,计算cpu负载 // 3.更新下次周期时钟的到期时间 // 注: // 1.在关中断情况下调用该函数 // 2.last_jiffies_update,记录距离上次更新经历的时钟周期(ns) 1.1 static void tick_do_update_jiffies64(ktime_t now) {

时间子系统15_获取系统时间

// 获取系统时间 // 注:将timespec转换为timeval 1.1 void do_gettimeofday(struct timeval *tv) { struct timespec now; getnstimeofday(&now); tv->tv_sec = now.tv_sec; tv->tv_usec = now.tv_nsec/1000; } // 获取纳秒级系统时间 // 函数任务: // 1.获取墙上时间t // 2.获取距离上次更新xtime以来经历的纳秒d