From 57750518de5b7c167d41d352dc6b0d24c840cd76 Mon Sep 17 00:00:00 2001 From: xieliujie Date: Tue, 6 Jun 2023 20:45:12 +0800 Subject: [PATCH] ANDROID: vendor_hook: Avoid clearing protect-flag before waking waiters With hooks below, we can mark a lock-owned thread with an identifiable flag, which can protect it from being preempted by some other unimportant threads, and then waiter will be wakeup more quickly. https://android-review.googlesource.com/c/kernel/common/+/2183353 but now we find an issue like this one: static inline void __up_write(struct rw_semaphore *sem) { ... // Step 1. we clear flag. trace_android_vh_record_rwsem_lock_starttime(current, 0); // Step 2. owner may be preempted by unimportant threads. rwsem_clear_owner(sem); ... // Step 3. wake up waiter, but it's too later. if (unlikely(tmp & RWSEM_FLAG_WAITERS)) rwsem_wake(sem); } This patch will clear protect-flag after waking up waiters. Bug: 286024926 Change-Id: I71f8b6a7d8a01336fd36b8267c2cb5edab65bd11 Signed-off-by: xieliujie --- include/linux/percpu-rwsem.h | 2 +- kernel/locking/mutex.c | 2 +- kernel/locking/percpu-rwsem.c | 2 +- kernel/locking/rwsem.c | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/linux/percpu-rwsem.h b/include/linux/percpu-rwsem.h index 8a39613370a3..ebd81e03f3c1 100644 --- a/include/linux/percpu-rwsem.h +++ b/include/linux/percpu-rwsem.h @@ -102,7 +102,6 @@ static inline bool percpu_down_read_trylock(struct percpu_rw_semaphore *sem) static inline void percpu_up_read(struct percpu_rw_semaphore *sem) { - _trace_android_vh_record_pcpu_rwsem_starttime(current, 0); rwsem_release(&sem->dep_map, _RET_IP_); preempt_disable(); @@ -125,6 +124,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_starttime(current, 0); preempt_enable(); } diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c index e2952e345bb1..4ff70da18e3c 100644 --- a/kernel/locking/mutex.c +++ b/kernel/locking/mutex.c @@ -555,12 +555,12 @@ static noinline void __sched __mutex_unlock_slowpath(struct mutex *lock, unsigne */ void __sched mutex_unlock(struct mutex *lock) { - trace_android_vh_record_mutex_lock_starttime(current, 0); #ifndef CONFIG_DEBUG_LOCK_ALLOC if (__mutex_unlock_fast(lock)) return; #endif __mutex_unlock_slowpath(lock, _RET_IP_); + trace_android_vh_record_mutex_lock_starttime(current, 0); } EXPORT_SYMBOL(mutex_unlock); diff --git a/kernel/locking/percpu-rwsem.c b/kernel/locking/percpu-rwsem.c index 2bf52ced2526..084aedde3d0f 100644 --- a/kernel/locking/percpu-rwsem.c +++ b/kernel/locking/percpu-rwsem.c @@ -269,7 +269,6 @@ EXPORT_SYMBOL_GPL(percpu_down_write); void percpu_up_write(struct percpu_rw_semaphore *sem) { - trace_android_vh_record_pcpu_rwsem_starttime(current, 0); rwsem_release(&sem->dep_map, _RET_IP_); /* @@ -295,5 +294,6 @@ 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_starttime(current, 0); } EXPORT_SYMBOL_GPL(percpu_up_write); diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c index 257cbea27d65..1988ac0dc3b3 100644 --- a/kernel/locking/rwsem.c +++ b/kernel/locking/rwsem.c @@ -1386,7 +1386,6 @@ static inline void __up_read(struct rw_semaphore *sem) DEBUG_RWSEMS_WARN_ON(!is_rwsem_reader_owned(sem), sem); preempt_disable(); - trace_android_vh_record_rwsem_lock_starttime(current, 0); rwsem_clear_reader_owned(sem); tmp = atomic_long_add_return_release(-RWSEM_READER_BIAS, &sem->count); DEBUG_RWSEMS_WARN_ON(tmp < 0, sem); @@ -1395,6 +1394,7 @@ static inline void __up_read(struct rw_semaphore *sem) clear_nonspinnable(sem); rwsem_wake(sem); } + trace_android_vh_record_rwsem_lock_starttime(current, 0); preempt_enable(); } @@ -1414,12 +1414,12 @@ static inline void __up_write(struct rw_semaphore *sem) !rwsem_test_oflags(sem, RWSEM_NONSPINNABLE), sem); preempt_disable(); - trace_android_vh_record_rwsem_lock_starttime(current, 0); rwsem_clear_owner(sem); tmp = atomic_long_fetch_add_release(-RWSEM_WRITER_LOCKED, &sem->count); preempt_enable(); if (unlikely(tmp & RWSEM_FLAG_WAITERS)) rwsem_wake(sem); + trace_android_vh_record_rwsem_lock_starttime(current, 0); } /*