From 3e4fa5265cbe083c88375fe04ae6747a93973f43 Mon Sep 17 00:00:00 2001 From: Huang Yiwei Date: Tue, 10 Jan 2023 17:29:51 +0800 Subject: [PATCH] ANDROID: hung_task: Add vendor hook for hung task detect Add vendor hook for hung task detect, so we can decide which threads need to check, avoiding false alarms. And the NULL tracehook is used to indicate one check cycle is finished, so additional checks can be done after one hung task check cycle. Bug: 188684133 Change-Id: I5d7dfeb071cbfda8121134c38a458202aaa3a8c6 Signed-off-by: Huang Yiwei --- drivers/android/vendor_hooks.c | 3 +++ include/trace/hooks/hung_task.h | 23 +++++++++++++++++++++++ kernel/hung_task.c | 17 ++++++++++++----- 3 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 include/trace/hooks/hung_task.h diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 50ccc9040a89b..c16c01262a1c1 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -45,6 +45,7 @@ #include #include #include +#include /* * Export tracepoints that act as a bare tracehook (ie: have no trace event @@ -135,3 +136,5 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_aes_expandkey); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_aes_encrypt); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_aes_decrypt); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_timer_calc_index); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_check_uninterrupt_tasks); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_check_uninterrupt_tasks_done); diff --git a/include/trace/hooks/hung_task.h b/include/trace/hooks/hung_task.h new file mode 100644 index 0000000000000..cdbf59e06990d --- /dev/null +++ b/include/trace/hooks/hung_task.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM hung_task + +#define TRACE_INCLUDE_PATH trace/hooks + +#if !defined(_TRACE_HOOK_HUNG_TASK_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_HOOK_HUNG_TASK_H + +#include + +DECLARE_HOOK(android_vh_check_uninterrupt_tasks, + TP_PROTO(struct task_struct *t, unsigned long timeout, + bool *need_check), + TP_ARGS(t, timeout, need_check)); + +DECLARE_HOOK(android_vh_check_uninterrupt_tasks_done, + TP_PROTO(void *unused), + TP_ARGS(unused)); + +#endif /* _TRACE_HOOK_HUNG_TASK_H */ +/* This part must be outside protection */ +#include diff --git a/kernel/hung_task.c b/kernel/hung_task.c index c71889f3f3fc2..6766fd41ec1ad 100644 --- a/kernel/hung_task.c +++ b/kernel/hung_task.c @@ -24,6 +24,8 @@ #include #include +#undef CREATE_TRACE_POINTS +#include /* * The number of tasks checked: @@ -180,6 +182,7 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout) int max_count = sysctl_hung_task_check_count; unsigned long last_break = jiffies; struct task_struct *g, *t; + bool need_check = true; /* * If the system crashed already then all bets are off, @@ -204,12 +207,16 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout) * skip the TASK_KILLABLE tasks -- these can be killed * skip the TASK_IDLE tasks -- those are genuinely idle */ - state = READ_ONCE(t->__state); - if ((state & TASK_UNINTERRUPTIBLE) && - !(state & TASK_WAKEKILL) && - !(state & TASK_NOLOAD)) - check_hung_task(t, timeout); + trace_android_vh_check_uninterrupt_tasks(t, timeout, &need_check); + if (need_check) { + state = READ_ONCE(t->__state); + if ((state & TASK_UNINTERRUPTIBLE) && + !(state & TASK_WAKEKILL) && + !(state & TASK_NOLOAD)) + check_hung_task(t, timeout); + } } + trace_android_vh_check_uninterrupt_tasks_done(NULL); unlock: rcu_read_unlock(); if (hung_task_show_lock)