https://blog.csdn.net/hzj_001/article/details/100054659より転載
カーネルwatchodogスレッド、精密タイマー(クロック割り込み)、イベントベース(ノンマスカブル割り込み)PERF NMI PMUハードウェア:これは3つの主要な機構を必要とします。
基本的な考え方:
1)(ソフトロックアップ)プロセスの残りの部分は、スケジュールすることができない原因となる、時間近くをつかむ
2)(ハードロックアップ):.割り込みが長時間密接によって引き起こされます
softlockup基本原則:
登録されている各CPUコアのカーネルウォッチドッグスレッドと呼ばれる検出するために、1)SoftLockup最初の必要性、。すなわち、[ウォッチドッグ/ 0]、[ウォッチドッグ/ 1]、[ウォッチドッグ/ 2] ...
2)同時に、システムは、高精度のタイマーhrtimerを持つことになり、タイマは周期的なクロック割り込み、割り込みコールバックに対応する割り込みを発生()watchdog_timer_fnされ、この割り込みコールバック関数は3つのことを行うために、主に次のとおりです。
a.watchdog_interrupt_count機能アップデートのhrtimer_interrupts変数(判定hardlockupが使用する)
b.wake_up_processウェイクウォッチドッグスレッド(更新されたタイムスタンプ)
soft_lockupがあるかどうかを判断c.is_softlockup
ソフトロック検出器多くのソフトロックアップしきい値よりは説明するために、更新されていない場合には、タイムスタンプをチェックし、[ウォッチドッグ/ x]は実行する機会を取得していない、ソフトロックアップが起こったことであるCPUが占有されていることを意味、。
[ウォッチドッグ/ x]は、スレッドのカーネル目的は、オブジェクトのタイムスタンプを更新することがあることに注意してください時計です。本物のウォッチドッグは、()は、[ウォッチドッグ/ X]は(スケジューラの実行、およびwatchdog_timer_fnのために呼ばれている)がトリガー中断されwatchdog_timer_fn割り込みクロックによってトリガされます。
基本的な原理をhardlockup :(また別の記事https://blog.csdn.net/hzj_001/article/details/95059760)を参照することができる
1)(/ PROC / SYS /カーネルwatchdog_thresh介して、ハードウェアベースのPMUのパーフォレーションイベントを登録/ watchdog_thresh)秒トリガーNMI割り込み
NMI割り込み2 hrtimer_interruptsに対応する割り込みハンドラ(最後の値がhrtimer_interrupts_saved)値が変更さを検出し、存在hardlockupを決定することによって2)
。3)が格納割り込みカウントhrtimer_interrupts_saved = hrtimer_interrupts
1.watchdogスレッドは
、各CPUの一般的なカーネルスレッドを登録し、ウォッチドッグ/ 0、ウォッチドッグ/ 1 ...とそうで呼び出されます。
主な機能:watchdog_touch_tsに現在のCPUのタイムスタンプ更新
2.watchdog_enableが応答関数割り込みクロックによっていくつかのウォッチドッグ機能を実現するために、高精度のタイマーを登録します
1)は、高精度クロックタイマー登録
静的な無効watchdog_enable(unsigned int型をCPU)
{
構造体hrtimer hrtimer * = __&raw_get_cpu_var(watchdog_hrtimer)。
hardlockup検出器のタイマーオフ/ *キック* /
hrtimer_init(hrtimer、CLOCK_MONOTONIC、HRTIMER_MODE_REL)。
hrtimer->機能= watchdog_timer_fn。
/ * * / PERFイベントを有効にし
watchdog_nmi_enable(CPU);
/ *壁紙ここで行わためhrtimer_start CAN smp_processor_idにのみPIN()* /
hrtimer_start(hrtimer、ns_to_ktime(sample_period)、
HRTIMER_MODE_REL_PINNED); / *初期化タイムスタンプ* /
watchdog_set_prio(SCHED_FIFO、MAX_RT_PRIO - 1);
__touch_watchdog();
}
2)に応答してクロック割り込みは、割り込みはコールバック関数watchdog_timer_fn高精度クロック割り込みハンドラhrtimer_interruptに応じて実行されます。
/ *ウォッチドッグキッカー機能* /
静的な列挙型hrtimer_restart watchdog_timer_fn(構造体hrtimer hrtimer *)
{
unsigned long型touch_ts = __this_cpu_read(watchdog_touch_ts); //取得watchdog_touch_tsの現在のCPU、ウォッチドッグ・カーネルスレッドが予定されているときのカウントが更新される
構造体pt_regsを* regsは= get_irq_regs();
int型DURATION;
int型softlockup_all_cpu_backtrace = sysctl_softlockup_all_cpu_backtrace;
IF(!atomic_read(&watchdog_park_in_progress)= 0)
の戻りHRTIMER_NORESTART;
/ * hardlockupキック検出器* /
watchdog_interrupt_count(); //更新割り込み回数
/ *キックsoftlockup検出器* /
wake_up_process(__ this_cpu_read(softlockup_watchdog)) ; // ウェイクウォッチドッグスレッド
/ * ...と繰り返します* /
hrtimer_forward_now(hrtimer、ns_to_ktime(sample_period)); //重启定时器
場合(touch_ts == 0){/ *第一次执行、watchdog_touch_ts时间戳可能为零、需要更新touch_ts为当前时间戳* /
IF(低いです( __this_cpu_read(softlockup_touch_sync))){
/ *
*タイムスタンプがアトミックに触れた場合
* makeは必ずスケジューラティックが最新のものです。
* /
__this_cpu_write(softlockup_touch_sync、偽);
sched_clock_tick();
}
/ *クリアゲスト* /ウォッチドッグリセット時にフラグを一時停止
)(kvm_check_and_clear_guest_paused。
__touch_watchdog(); //更新watchdog_touch_tsは
HRTIMER_RESTARTを返します。
}
/ * A softlockupのためのチェック
*これは、タスクがされていることを確認作るA高い優先順位で実行されます
*というスケジュール。ウォッチドッグでのタスクのタッチがする
*それはCPU時間の取得を示します。その後、場合、それはしていません
*このIS Aグッドの表示いくつかのタスクでCPUを占有することである
* //システムは20代のスケジュール上で発生していないかどうかを検出し、メイクの決定* / *
DURATION = is_softlockup(touch_ts); //ソフトロックが発生したかどうかを判断する、原理はtouch_ts(タイムスタンプ)を決定することである一定を超えます時間が更新されない
IF(可能性は低い(DURATION)){
/ *
*仮想マシンは、それが見ることができ、ホストによって停止されている場合は
Aソフトロックアップのように*ウォッチドッグ、ホストかどうかを確認してください
WEが警告を発行する前に*がVMを停止
* /
IF(()kvm_check_and_clear_guest_paused)
戻りHRTIMER_RESTARTを;
/ *一度だけ警告する* /
IF(trueに__this_cpu_read(soft_watchdog_warn)==){
/ * soft_watchdog_warn識別は、ウォッチドッグタイムアウトが設定されている場合であったであろう
、ここでプロセスのデッドロックが変更された、およびロゴはfalseに再集合になることを、あなたは再トリガアラームにできるようになる場合は、同じプロセスのデッドロック、唯一の警察の行動に一度カーネルためのもの。* /
/ *
*複数のプロセスがsoftlockupsを引き起こしている
* softlockup検出器のみオンザ最初のものを警告
コードはにON Aのフルの静かなサイクルを依存しているので*
*再ARM。第二の処理を防ぎの静かなサイクル
*と報告されることは決してありません。検出するためのタスクポインタを使用します
* この。
* /
(__this_cpu_read(softlockup_task_ptr_saved)=!もし
現在){
__this_cpu_write(soft_watchdog_warn、偽);
__touch_watchdog()。
}
HRTIMER_RESTARTを返します。
}
(softlockup_all_cpu_backtrace){もし
/ *防止、複数のソフトロックアップレポートつのCPUが既にある場合
* CPUのバックトレースをダンプに従事
* /
{場合(test_and_set_bit(0、&soft_lockup_nmi_warn))
/ *他の誰かが私たちを報告します。さんはあきらめましょう* /
__this_cpu_write(soft_watchdog_warn、真の);
戻りHRTIMER_RESTART;
}
}
.. / *上記の本当のsoft_lockupは、以下にいくつかの必要な情報soft_lockupが表示されますが、* /ダンプします、その後であるかどうかの条件が決定された数ある
pr_emerg(「BUG:ソフトロックアップは、 ! - CPUの#%D%米国のためのスタック:[%のS%D] \ N-」、
、DURATION、)(smp_processor_id
の電流する> COMM、task_pid_nr(現在));
__this_cpu_write(softlockup_task_ptr_saved、現在の);
print_modules();
print_irqtrace_events (現在の);
IF(REGS)
show_regs(REGS);
他
dump_stack();
IF(softlockup_all_cpu_backtrace){
/ *避け発生電流のための2つのバックトレース
一つは既に上に形成されていることを考える*
* /
trigger_allbutself_cpu_backtrace();
clear_bit(0、&soft_lockup_nmi_warn)。
/ *他のCPUと同期するバリア* /
smp_mb__after_atomic();
}
add_taint(TAINT_SOFTLOCKUP、LOCKDEP_STILL_OK)。
もし(softlockup_panic)//如果配置了softlockup_panic(PROC中配置)、则パニック
パニック( "softlockup:ハングタスク");
__this_cpu_write(soft_watchdog_warn、TRUE)。//出现了一次超时、ソフトロック。
}他
__this_cpu_write(soft_watchdog_warn、偽);
HRTIMER_RESTARTを返します。
}
3.watchdog_enable PMU登録watchdog_nmi_enableによってコールバック関数watchdog_overflow_callback検出hardlockup割り込みNMIによって、ハードウェアパーフイベントに基づいて説明する
この性能で呼び出さx86ハードウェアで監視した後、このハードウェアは、発行されたサイクル数後のCPUクロックである特徴を有していますNMIは、それを中断しました。
1)登録PERFイベント
静的INT watchdog_nmi_enable(unsigned int型CPU)
{
* wd_attr perf_event_attr構造体。
wd_attr =&wd_hw_attr。
wd_attr-> sample_period = hw_nmi_get_sample_period(watchdog_thresh)。
/ *イベント* / PERFハードウェアを使用して登録してみ
イベント= perf_event_create_kernel_counter(wd_attr、CPU、NULL、watchdog_overflow_callback、NULL);
}
2)设置定时时间sample_period
U64 hw_nmi_get_sample_period(INT watchdog_thresh)
{
リターン(U64)(cpu_khz)×1000 * watchdog_thresh;
}
ここでサイクル後のクロック、現在のCPU周波数に従って、値を算出するには、即ち20秒のCPUは、あまりにも周りに、実際20Sありますこれは、NMIトリガする
、3)NMIを割り込みコールバック関数watchdog_overflow_callbackを実行するために、検出hardlockup
静的ボイドwatchdog_overflow_callback(構造体perf_event *イベント、
構造体perf_sample_data *データ、
構造体pt_regs * REGS)
{
IF(is_hardlockup()){
int型this_cpu = smp_processor_id()。
場合(hardlockup_panic)
パニック(this_cpu "ウォッチドッグは、CPU%Dのハードロックアップ検出しました")。
他
(1、 "ウォッチドッグは、CPU%Dのハードロックアップ検出"、this_cpu)WARN。
リターン;
}
を返します。
}
这个函数主要就是调用is_hardlockup
/ *機能ウォッチドッグ検出* /
静的BOOL is_hardlockup(ボイド)
{
unsigned long型hrint = __this_cpu_read(hrtimer_interrupts);
IF(__this_cpu_read(hrtimer_interrupts_saved)== hrint)
trueに戻り、
__this_cpu_write(hrtimer_interrupts_saved、hrint);
falseに戻り;
}
この関数は、主にビューhrtimer_interruptsが更新されていない、可変クロック割り込みハンドラです。更新がない場合、それは長い時間が問題、エラーコードをオフに遮断手段中断された可能性があります。