diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index d508cc353fc3..c835f500ac9d 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -73,10 +73,16 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mutex_wait_start); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mutex_wait_finish); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rtmutex_wait_start); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rtmutex_wait_finish); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mutex_opt_spin_start); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mutex_opt_spin_finish); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mutex_can_spin_on_owner); 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_rwsem_opt_spin_start); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_opt_spin_finish); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_can_spin_on_owner); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sched_show_task); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cpu_idle_enter); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cpu_idle_exit); diff --git a/include/trace/hooks/dtask.h b/include/trace/hooks/dtask.h index f92996271a1f..4220575c98f8 100644 --- a/include/trace/hooks/dtask.h +++ b/include/trace/hooks/dtask.h @@ -22,6 +22,15 @@ DECLARE_HOOK(android_vh_mutex_wait_start, DECLARE_HOOK(android_vh_mutex_wait_finish, TP_PROTO(struct mutex *lock), TP_ARGS(lock)); +DECLARE_HOOK(android_vh_mutex_opt_spin_start, + TP_PROTO(struct mutex *lock, bool *time_out, int *cnt), + TP_ARGS(lock, time_out, cnt)); +DECLARE_HOOK(android_vh_mutex_opt_spin_finish, + TP_PROTO(struct mutex *lock, bool taken), + TP_ARGS(lock, taken)); +DECLARE_HOOK(android_vh_mutex_can_spin_on_owner, + TP_PROTO(struct mutex *lock, int *retval), + TP_ARGS(lock, retval)); DECLARE_HOOK(android_vh_rtmutex_wait_start, TP_PROTO(struct rt_mutex_base *lock), @@ -42,6 +51,15 @@ DECLARE_HOOK(android_vh_rwsem_write_wait_start, DECLARE_HOOK(android_vh_rwsem_write_wait_finish, TP_PROTO(struct rw_semaphore *sem), TP_ARGS(sem)); +DECLARE_HOOK(android_vh_rwsem_opt_spin_start, + TP_PROTO(struct rw_semaphore *sem, bool *time_out, int *cnt, bool chk_only), + TP_ARGS(sem, time_out, cnt, chk_only)); +DECLARE_HOOK(android_vh_rwsem_opt_spin_finish, + TP_PROTO(struct rw_semaphore *sem, bool taken), + TP_ARGS(sem, taken)); +DECLARE_HOOK(android_vh_rwsem_can_spin_on_owner, + TP_PROTO(struct rw_semaphore *sem, bool *ret), + TP_ARGS(sem, ret)); DECLARE_HOOK(android_vh_sched_show_task, TP_PROTO(struct task_struct *task), diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c index 622dcf7a26b0..44b6ff75d31d 100644 --- a/kernel/locking/mutex.c +++ b/kernel/locking/mutex.c @@ -361,10 +361,17 @@ bool mutex_spin_on_owner(struct mutex *lock, struct task_struct *owner, struct ww_acquire_ctx *ww_ctx, struct mutex_waiter *waiter) { bool ret = true; + int cnt = 0; + bool time_out = false; lockdep_assert_preemption_disabled(); while (__mutex_owner(lock) == owner) { + trace_android_vh_mutex_opt_spin_start(lock, &time_out, &cnt); + if (time_out) { + ret = false; + break; + } /* * Ensure we emit the owner->on_cpu, dereference _after_ * checking lock->owner still matches owner. And we already @@ -415,6 +422,7 @@ static inline int mutex_can_spin_on_owner(struct mutex *lock) owner = __mutex_owner(lock); if (owner) retval = owner_on_cpu(owner); + trace_android_vh_mutex_can_spin_on_owner(lock, &retval); /* * If lock->owner is not set, the mutex has been released. Return true @@ -496,6 +504,7 @@ mutex_optimistic_spin(struct mutex *lock, struct ww_acquire_ctx *ww_ctx, if (!waiter) osq_unlock(&lock->osq); + trace_android_vh_mutex_opt_spin_finish(lock, true); return true; @@ -504,6 +513,7 @@ fail_unlock: osq_unlock(&lock->osq); fail: + trace_android_vh_mutex_opt_spin_finish(lock, false); /* * If we fell out of the spin path because of need_resched(), * reschedule now, before we try-lock the mutex. This avoids getting diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c index 0e6c93fb1f2d..bcf8160bb6ac 100644 --- a/kernel/locking/rwsem.c +++ b/kernel/locking/rwsem.c @@ -734,6 +734,7 @@ static inline bool rwsem_can_spin_on_owner(struct rw_semaphore *sem) (owner && !(flags & RWSEM_READER_OWNED) && !owner_on_cpu(owner))) ret = false; preempt_enable(); + trace_android_vh_rwsem_can_spin_on_owner(sem, &ret); lockevent_cond_inc(rwsem_opt_fail, !ret); return ret; @@ -759,6 +760,8 @@ rwsem_spin_on_owner(struct rw_semaphore *sem) struct task_struct *new, *owner; unsigned long flags, new_flags; enum owner_state state; + int cnt = 0; + bool time_out = false; lockdep_assert_preemption_disabled(); @@ -768,6 +771,9 @@ rwsem_spin_on_owner(struct rw_semaphore *sem) return state; for (;;) { + trace_android_vh_rwsem_opt_spin_start(sem, &time_out, &cnt, true); + if (time_out) + break; /* * When a waiting writer set the handoff flag, it may spin * on the owner as well. Once that writer acquires the lock, @@ -832,6 +838,8 @@ static bool rwsem_optimistic_spin(struct rw_semaphore *sem) int prev_owner_state = OWNER_NULL; int loop = 0; u64 rspin_threshold = 0; + int cnt = 0; + bool time_out = false; preempt_disable(); @@ -848,6 +856,9 @@ static bool rwsem_optimistic_spin(struct rw_semaphore *sem) for (;;) { enum owner_state owner_state; + trace_android_vh_rwsem_opt_spin_start(sem, &time_out, &cnt, false); + if (time_out) + break; owner_state = rwsem_spin_on_owner(sem); if (!(owner_state & OWNER_SPINNABLE)) break; @@ -941,6 +952,7 @@ static bool rwsem_optimistic_spin(struct rw_semaphore *sem) cpu_relax(); } osq_unlock(&sem->osq); + trace_android_vh_rwsem_opt_spin_finish(sem, taken); done: preempt_enable(); lockevent_cond_inc(rwsem_opt_fail, !taken);