閱讀85 返回首頁    go 阿裏雲 go 技術社區[雲棲]


時間子係統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;
}

最後更新:2017-04-03 14:54:38

  上一篇:go leetcode難度及麵試頻率
  下一篇:go 時間子係統16_soft lockup機製