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 <sangmoon.kim@samsung.com>
Change-Id: Ib436fbd8d0ad509c3b5a73ea8f5170e0761a13fd
This commit is contained in:
Sangmoon Kim 2020-08-05 22:13:43 +09:00 • committed by Todd Kjos
commit b519ac4237
6 changed files with 81 additions and 0 deletions

View file

@ -8,9 +8,17 @@
#define CREATE_TRACE_POINTS
#include <trace/hooks/vendor_hooks.h>
#include <trace/hooks/dtask.h>
/*
* 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);

View file

@ -32,6 +32,7 @@
#include <linux/posix-timers.h>
#include <linux/rseq.h>
#include <linux/android_kabi.h>
#include <linux/android_vendor.h>
/* 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);

View file

@ -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 <linux/tracepoint.h>
#include <trace/hooks/vendor_hooks.h>
/*
* 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 <trace/define_trace.h>

View file

@ -36,6 +36,8 @@
# include "mutex.h"
#endif
#include <trace/hooks/dtask.h>
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);

View file

@ -31,6 +31,8 @@
#include "rwsem.h"
#include "lock_events.h"
#include <trace/hooks/dtask.h>
/*
* 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);

View file

@ -24,6 +24,9 @@
#define CREATE_TRACE_POINTS
#include <trace/events/sched.h>
#undef CREATE_TRACE_POINTS
#include <trace/hooks/dtask.h>
/*
* 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);
}