From b519ac423787d38f467ca479d2126b7204d6f498 Mon Sep 17 00:00:00 2001 From: Sangmoon Kim Date: Wed, 5 Aug 2020 22:13:43 +0900 Subject: [PATCH] ANDROID: vendor_hooks: add waiting information for blocked tasks - Add the hook to get mutex/rwsem information that the tasks are waiting for. - Add the hook to print messages for sched_show_task. - ANDROID_VENDOR_DATA_ARRAY added to task_struct Bug: 162776704 Signed-off-by: Sangmoon Kim Change-Id: Ib436fbd8d0ad509c3b5a73ea8f5170e0761a13fd --- drivers/android/vendor_hooks.c | 8 +++++ include/linux/sched.h | 3 ++ include/trace/hooks/dtask.h | 53 ++++++++++++++++++++++++++++++++++ kernel/locking/mutex.c | 5 ++++ kernel/locking/rwsem.c | 8 +++++ kernel/sched/core.c | 4 +++ 6 files changed, 81 insertions(+) create mode 100644 include/trace/hooks/dtask.h diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index cf75759e4c3f..a62235c8e058 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -8,9 +8,17 @@ #define CREATE_TRACE_POINTS #include +#include /* * Export tracepoints that act as a bare tracehook (ie: have no trace event * associated with them) to allow external modules to probe them. */ +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mutex_wait_start); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mutex_wait_finish); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_read_wait_start); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_read_wait_finish); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_write_wait_start); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_write_wait_finish); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sched_show_task); diff --git a/include/linux/sched.h b/include/linux/sched.h index 3865142b31a7..a99ebd816867 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -32,6 +32,7 @@ #include #include #include +#include /* task_struct member predeclarations (sorted alphabetically): */ struct audit_context; @@ -1291,6 +1292,8 @@ struct task_struct { unsigned long prev_lowest_stack; #endif + ANDROID_VENDOR_DATA_ARRAY(1, 2); + ANDROID_KABI_RESERVE(1); ANDROID_KABI_RESERVE(2); ANDROID_KABI_RESERVE(3); diff --git a/include/trace/hooks/dtask.h b/include/trace/hooks/dtask.h new file mode 100644 index 000000000000..f4fafbfedc23 --- /dev/null +++ b/include/trace/hooks/dtask.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM dtask +#define TRACE_INCLUDE_PATH trace/hooks + +#if !defined(_TRACE_HOOK_DTASK_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_HOOK_DTASK_H +#include +#include +/* + * Following tracepoints are not exported in tracefs and provide a + * mechanism for vendor modules to hook and extend functionality + */ +#if defined(CONFIG_TRACEPOINTS) && defined(CONFIG_ANDROID_VENDOR_HOOKS) +struct mutex; +DECLARE_HOOK(android_vh_mutex_wait_start, + TP_PROTO(struct mutex *lock), + TP_ARGS(lock)); +DECLARE_HOOK(android_vh_mutex_wait_finish, + TP_PROTO(struct mutex *lock), + TP_ARGS(lock)); + +struct rw_semaphore; +DECLARE_HOOK(android_vh_rwsem_read_wait_start, + TP_PROTO(struct rw_semaphore *sem), + TP_ARGS(sem)); +DECLARE_HOOK(android_vh_rwsem_read_wait_finish, + TP_PROTO(struct rw_semaphore *sem), + TP_ARGS(sem)); +DECLARE_HOOK(android_vh_rwsem_write_wait_start, + TP_PROTO(struct rw_semaphore *sem), + TP_ARGS(sem)); +DECLARE_HOOK(android_vh_rwsem_write_wait_finish, + TP_PROTO(struct rw_semaphore *sem), + TP_ARGS(sem)); + +struct task_struct; +DECLARE_HOOK(android_vh_sched_show_task, + TP_PROTO(struct task_struct *task), + TP_ARGS(task)); +#else +#define trace_android_vh_mutex_wait_start(lock) +#define trace_android_vh_mutex_wait_finish(lock) +#define trace_android_vh_rwsem_read_wait_start(sem) +#define trace_android_vh_rwsem_read_wait_finish(sem) +#define trace_android_vh_rwsem_write_wait_start(sem) +#define trace_android_vh_rwsem_write_wait_finish(sem) +#define trace_android_vh_sched_show_task(task) +#endif + +#endif /* _TRACE_HOOK_DTASK_H */ +/* This part must be outside protection */ +#include diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c index 468a9b8422e3..5227d478672f 100644 --- a/kernel/locking/mutex.c +++ b/kernel/locking/mutex.c @@ -36,6 +36,8 @@ # include "mutex.h" #endif +#include + void __mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key) { @@ -1002,6 +1004,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, waiter.task = current; + trace_android_vh_mutex_wait_start(lock); set_current_state(state); for (;;) { /* @@ -1057,6 +1060,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, spin_lock(&lock->wait_lock); acquired: __set_current_state(TASK_RUNNING); + trace_android_vh_mutex_wait_finish(lock); if (use_ww_ctx && ww_ctx) { /* @@ -1087,6 +1091,7 @@ skip_wait: err: __set_current_state(TASK_RUNNING); + trace_android_vh_mutex_wait_finish(lock); mutex_remove_waiter(lock, &waiter, current); err_early_kill: spin_unlock(&lock->wait_lock); diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c index baafa1dd9fcc..fe9cf499b1d7 100644 --- a/kernel/locking/rwsem.c +++ b/kernel/locking/rwsem.c @@ -31,6 +31,8 @@ #include "rwsem.h" #include "lock_events.h" +#include + /* * The least significant 3 bits of the owner value has the following * meanings when set. @@ -1085,6 +1087,7 @@ queue: wake_up_q(&wake_q); /* wait to be given the lock */ + trace_android_vh_rwsem_read_wait_start(sem); for (;;) { set_current_state(state); if (!smp_load_acquire(&waiter.task)) { @@ -1104,6 +1107,7 @@ queue: } __set_current_state(TASK_RUNNING); + trace_android_vh_rwsem_read_wait_finish(sem); lockevent_inc(rwsem_rlock); return sem; @@ -1115,6 +1119,7 @@ out_nolock: } raw_spin_unlock_irq(&sem->wait_lock); __set_current_state(TASK_RUNNING); + trace_android_vh_rwsem_read_wait_finish(sem); lockevent_inc(rwsem_rlock_fail); return ERR_PTR(-EINTR); } @@ -1209,6 +1214,7 @@ rwsem_down_write_slowpath(struct rw_semaphore *sem, int state) wait: /* wait until we successfully acquire the lock */ + trace_android_vh_rwsem_write_wait_start(sem); set_current_state(state); for (;;) { if (rwsem_try_write_lock(sem, wstate)) { @@ -1268,6 +1274,7 @@ trylock_again: raw_spin_lock_irq(&sem->wait_lock); } __set_current_state(TASK_RUNNING); + trace_android_vh_rwsem_write_wait_finish(sem); list_del(&waiter.list); rwsem_disable_reader_optspin(sem, disable_rspin); raw_spin_unlock_irq(&sem->wait_lock); @@ -1277,6 +1284,7 @@ trylock_again: out_nolock: __set_current_state(TASK_RUNNING); + trace_android_vh_rwsem_write_wait_finish(sem); raw_spin_lock_irq(&sem->wait_lock); list_del(&waiter.list); diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 53d2f7451495..c7bfaf6fef14 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -24,6 +24,9 @@ #define CREATE_TRACE_POINTS #include +#undef CREATE_TRACE_POINTS +#include + /* * Export tracepoints that act as a bare tracehook (ie: have no trace event * associated with them) to allow external modules to probe them. @@ -5930,6 +5933,7 @@ void sched_show_task(struct task_struct *p) (unsigned long)task_thread_info(p)->flags); print_worker_info(KERN_INFO, p); + trace_android_vh_sched_show_task(p); show_stack(p, NULL); put_task_stack(p); }