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 <xieliujie@oppo.com>
This commit is contained in:
xieliujie 2023-06-06 20:45:12 +08:00 committed by Treehugger Robot
parent aacbded3ac
commit 57750518de
4 changed files with 5 additions and 5 deletions

View file

@ -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) 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_); rwsem_release(&sem->dep_map, _RET_IP_);
preempt_disable(); preempt_disable();
@ -125,6 +124,7 @@ static inline void percpu_up_read(struct percpu_rw_semaphore *sem)
this_cpu_dec(*sem->read_count); this_cpu_dec(*sem->read_count);
rcuwait_wake_up(&sem->writer); rcuwait_wake_up(&sem->writer);
} }
_trace_android_vh_record_pcpu_rwsem_starttime(current, 0);
preempt_enable(); preempt_enable();
} }

View file

@ -555,12 +555,12 @@ static noinline void __sched __mutex_unlock_slowpath(struct mutex *lock, unsigne
*/ */
void __sched mutex_unlock(struct mutex *lock) void __sched mutex_unlock(struct mutex *lock)
{ {
trace_android_vh_record_mutex_lock_starttime(current, 0);
#ifndef CONFIG_DEBUG_LOCK_ALLOC #ifndef CONFIG_DEBUG_LOCK_ALLOC
if (__mutex_unlock_fast(lock)) if (__mutex_unlock_fast(lock))
return; return;
#endif #endif
__mutex_unlock_slowpath(lock, _RET_IP_); __mutex_unlock_slowpath(lock, _RET_IP_);
trace_android_vh_record_mutex_lock_starttime(current, 0);
} }
EXPORT_SYMBOL(mutex_unlock); EXPORT_SYMBOL(mutex_unlock);

View file

@ -269,7 +269,6 @@ EXPORT_SYMBOL_GPL(percpu_down_write);
void percpu_up_write(struct percpu_rw_semaphore *sem) 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_); 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. * exclusive write lock because its counting.
*/ */
rcu_sync_exit(&sem->rss); rcu_sync_exit(&sem->rss);
trace_android_vh_record_pcpu_rwsem_starttime(current, 0);
} }
EXPORT_SYMBOL_GPL(percpu_up_write); EXPORT_SYMBOL_GPL(percpu_up_write);

View file

@ -1386,7 +1386,6 @@ static inline void __up_read(struct rw_semaphore *sem)
DEBUG_RWSEMS_WARN_ON(!is_rwsem_reader_owned(sem), sem); DEBUG_RWSEMS_WARN_ON(!is_rwsem_reader_owned(sem), sem);
preempt_disable(); preempt_disable();
trace_android_vh_record_rwsem_lock_starttime(current, 0);
rwsem_clear_reader_owned(sem); rwsem_clear_reader_owned(sem);
tmp = atomic_long_add_return_release(-RWSEM_READER_BIAS, &sem->count); tmp = atomic_long_add_return_release(-RWSEM_READER_BIAS, &sem->count);
DEBUG_RWSEMS_WARN_ON(tmp < 0, sem); DEBUG_RWSEMS_WARN_ON(tmp < 0, sem);
@ -1395,6 +1394,7 @@ static inline void __up_read(struct rw_semaphore *sem)
clear_nonspinnable(sem); clear_nonspinnable(sem);
rwsem_wake(sem); rwsem_wake(sem);
} }
trace_android_vh_record_rwsem_lock_starttime(current, 0);
preempt_enable(); preempt_enable();
} }
@ -1414,12 +1414,12 @@ static inline void __up_write(struct rw_semaphore *sem)
!rwsem_test_oflags(sem, RWSEM_NONSPINNABLE), sem); !rwsem_test_oflags(sem, RWSEM_NONSPINNABLE), sem);
preempt_disable(); preempt_disable();
trace_android_vh_record_rwsem_lock_starttime(current, 0);
rwsem_clear_owner(sem); rwsem_clear_owner(sem);
tmp = atomic_long_fetch_add_release(-RWSEM_WRITER_LOCKED, &sem->count); tmp = atomic_long_fetch_add_release(-RWSEM_WRITER_LOCKED, &sem->count);
preempt_enable(); preempt_enable();
if (unlikely(tmp & RWSEM_FLAG_WAITERS)) if (unlikely(tmp & RWSEM_FLAG_WAITERS))
rwsem_wake(sem); rwsem_wake(sem);
trace_android_vh_record_rwsem_lock_starttime(current, 0);
} }
/* /*