diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 3a317c513c87..12111662e56d 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -424,3 +424,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_read_trylock_failed); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_percpu_rwsem_down_read); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_percpu_rwsem_up_write); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_percpu_rwsem_wait_complete); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_record_rwsem_reader_owned); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_clear_rwsem_reader_owned); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_record_rwsem_writer_owned); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_clear_rwsem_writer_owned); diff --git a/include/trace/hooks/rwsem.h b/include/trace/hooks/rwsem.h index 6c1e36468271..1e2257c3e84e 100644 --- a/include/trace/hooks/rwsem.h +++ b/include/trace/hooks/rwsem.h @@ -37,6 +37,19 @@ DECLARE_HOOK(android_vh_rwsem_optimistic_rspin, DECLARE_HOOK(android_vh_rwsem_read_trylock_failed, TP_PROTO(struct rw_semaphore *sem, long *cntp, int *ret), TP_ARGS(sem, cntp, ret)); +DECLARE_HOOK(android_vh_record_rwsem_reader_owned, + TP_PROTO(struct rw_semaphore *sem, + struct list_head *wlist), + TP_ARGS(sem, wlist)); +DECLARE_HOOK(android_vh_clear_rwsem_reader_owned, + TP_PROTO(struct rw_semaphore *sem), + TP_ARGS(sem)); +DECLARE_HOOK(android_vh_record_rwsem_writer_owned, + TP_PROTO(struct rw_semaphore *sem), + TP_ARGS(sem)); +DECLARE_HOOK(android_vh_clear_rwsem_writer_owned, + TP_PROTO(struct rw_semaphore *sem), + TP_ARGS(sem)); #endif /* _TRACE_HOOK_RWSEM_H */ /* This part must be outside protection */ #include diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c index c847167f536f..98ee3906ee8a 100644 --- a/kernel/locking/rwsem.c +++ b/kernel/locking/rwsem.c @@ -143,12 +143,14 @@ static inline void rwsem_set_owner(struct rw_semaphore *sem) { lockdep_assert_preemption_disabled(); atomic_long_set(&sem->owner, (long)current); + trace_android_vh_record_rwsem_writer_owned(sem); } static inline void rwsem_clear_owner(struct rw_semaphore *sem) { lockdep_assert_preemption_disabled(); atomic_long_set(&sem->owner, 0); + trace_android_vh_clear_rwsem_writer_owned(sem); } /* @@ -181,6 +183,7 @@ static inline void __rwsem_set_reader_owned(struct rw_semaphore *sem, static inline void rwsem_set_reader_owned(struct rw_semaphore *sem) { __rwsem_set_reader_owned(sem, current); + trace_android_vh_record_rwsem_reader_owned(sem, NULL); } /* @@ -211,6 +214,7 @@ static inline void rwsem_clear_reader_owned(struct rw_semaphore *sem) { unsigned long val = atomic_long_read(&sem->owner); + trace_android_vh_clear_rwsem_reader_owned(sem); while ((val & ~RWSEM_OWNER_FLAGS_MASK) == (unsigned long)current) { if (atomic_long_try_cmpxchg(&sem->owner, &val, val & RWSEM_OWNER_FLAGS_MASK)) @@ -220,6 +224,7 @@ static inline void rwsem_clear_reader_owned(struct rw_semaphore *sem) #else static inline void rwsem_clear_reader_owned(struct rw_semaphore *sem) { + trace_android_vh_clear_rwsem_reader_owned(sem); } #endif @@ -561,6 +566,7 @@ static void rwsem_mark_wake(struct rw_semaphore *sem, if (adjustment) atomic_long_add(adjustment, &sem->count); + trace_android_vh_record_rwsem_reader_owned(sem, &wlist); /* 2nd pass */ list_for_each_entry_safe(waiter, tmp, &wlist, list) {