ANDROID: vendor_hooks:vendor hook for percpu-rwsem

We need a new vendor hook for two reasons:
1.The position of the previous vendor hook is inappropriate: when the task wakes up from percpu_rwsem_wait, it will enter a long runnable state, which will cause frame loss when the application starts. In order to solve this problem, we need to let the process enter the "vip" queue when it is woken up, so we need to set a flag for the process holding the lock to prove that it is about to hold the lock. The timing of setting the flag should be at the beginning of percpu_down_read/percpu_down_write rather than the end.
2.Most of this long runnable state occurs in the cgroup_threadgroup_rwsem, so we only care cgroup_threadgroup_rwsem, and cgroup_threadgroup_rwsem should be exported. At the same time, one more parameter "struct percpu_rw_semaphore *sem", is needed for this vendor hook.

Bug: 294496814
Change-Id: I5f014cfb68a60c29bbfd21452336e381e31e81b1
Signed-off-by: liuxudong5 <liuxudong5@xiaomi.com>
This commit is contained in:
liuxudong5 2023-07-27 19:26:47 +08:00 committed by Treehugger Robot
parent 63af84cffe
commit 2d7f87b0ff
4 changed files with 29 additions and 0 deletions

View file

@ -186,6 +186,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_set_module_permit_before_init);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_set_module_permit_after_init);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_selinux_is_initialized);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_shmem_get_folio);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_record_pcpu_rwsem_time_early);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_check_mmap_file);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_check_file_open);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_check_bpf_syscall);

View file

@ -23,6 +23,9 @@ struct percpu_rw_semaphore {
#endif
};
void _trace_android_vh_record_pcpu_rwsem_time_early(
unsigned long settime, struct percpu_rw_semaphore *sem);
#ifdef CONFIG_DEBUG_LOCK_ALLOC
#define __PERCPU_RWSEM_DEP_MAP_INIT(lockname) .dep_map = { .name = #lockname },
#else
@ -54,6 +57,8 @@ static inline void percpu_down_read(struct percpu_rw_semaphore *sem)
rwsem_acquire_read(&sem->dep_map, 0, 0, _RET_IP_);
preempt_disable();
_trace_android_vh_record_pcpu_rwsem_time_early(jiffies, sem);
/*
* We are in an RCU-sched read-side critical section, so the writer
* cannot both change sem->state from readers_fast and start checking
@ -93,6 +98,7 @@ static inline bool percpu_down_read_trylock(struct percpu_rw_semaphore *sem)
*/
if (ret) {
_trace_android_vh_record_pcpu_rwsem_time_early(jiffies, sem);
_trace_android_vh_record_pcpu_rwsem_starttime(current, jiffies);
rwsem_acquire_read(&sem->dep_map, 0, 1, _RET_IP_);
}
@ -124,6 +130,7 @@ static inline void percpu_up_read(struct percpu_rw_semaphore *sem)
this_cpu_dec(*sem->read_count);
rcuwait_wake_up(&sem->writer);
}
_trace_android_vh_record_pcpu_rwsem_time_early(0, sem);
_trace_android_vh_record_pcpu_rwsem_starttime(current, 0);
preempt_enable();
}

View file

@ -15,6 +15,7 @@ struct mutex;
struct rt_mutex_base;
struct rw_semaphore;
struct task_struct;
struct percpu_rw_semaphore;
DECLARE_HOOK(android_vh_mutex_wait_start,
TP_PROTO(struct mutex *lock),
@ -80,6 +81,9 @@ DECLARE_HOOK(android_vh_record_rwsem_lock_starttime,
DECLARE_HOOK(android_vh_record_pcpu_rwsem_starttime,
TP_PROTO(struct task_struct *tsk, unsigned long settime_jiffies),
TP_ARGS(tsk, settime_jiffies));
DECLARE_HOOK(android_vh_record_pcpu_rwsem_time_early,
TP_PROTO(unsigned long settime_jiffies, struct percpu_rw_semaphore *sem),
TP_ARGS(settime_jiffies, sem));
struct mutex_waiter;
DECLARE_HOOK(android_vh_alter_mutex_list_add,

View file

@ -26,6 +26,20 @@ void _trace_android_vh_record_pcpu_rwsem_starttime(struct task_struct *tsk,
}
EXPORT_SYMBOL_GPL(_trace_android_vh_record_pcpu_rwsem_starttime);
/*
* trace_android_vh_record_pcpu_rwsem_time_early is called in
* include/linux/percpu-rwsem.h by including include/hooks/dtask.h, which
* will result to build-err. So we create
* func: _trace_android_vh_record_pcpu_rwsem_time_early for percpu-rwsem.h to call.
*/
void _trace_android_vh_record_pcpu_rwsem_time_early(
unsigned long settime, struct percpu_rw_semaphore *sem)
{
trace_android_vh_record_pcpu_rwsem_time_early(settime, sem);
}
EXPORT_SYMBOL_GPL(_trace_android_vh_record_pcpu_rwsem_time_early);
int __percpu_init_rwsem(struct percpu_rw_semaphore *sem,
const char *name, struct lock_class_key *key)
{
@ -242,6 +256,8 @@ void __sched percpu_down_write(struct percpu_rw_semaphore *sem)
rwsem_acquire(&sem->dep_map, 0, 0, _RET_IP_);
trace_contention_begin(sem, LCB_F_PERCPU | LCB_F_WRITE);
trace_android_vh_record_pcpu_rwsem_time_early(jiffies, sem);
/* Notify readers to take the slow path. */
rcu_sync_enter(&sem->rss);
@ -294,6 +310,7 @@ void percpu_up_write(struct percpu_rw_semaphore *sem)
* exclusive write lock because its counting.
*/
rcu_sync_exit(&sem->rss);
trace_android_vh_record_pcpu_rwsem_time_early(0, sem);
trace_android_vh_record_pcpu_rwsem_starttime(current, 0);
}
EXPORT_SYMBOL_GPL(percpu_up_write);