ANDROID: rwsem: Add vendor hook to the rw-semaphore
Add the hook to apply vendor's performance tune for owner of rwsem. Add the hook for the waiter list of rwsem to allow vendor perform waiting queue enhancement ANDROID_VENDOR_DATA added to rw_semaphore Bug: 319399115 Signed-off-by: JianMin Liu <jian-min.liu@mediatek.com> Signed-off-by: Guanwun Chen <guan-wun.chen@mediatek.com> Change-Id: I007a5e26f3db2adaeaf4e5ccea414ce7abfa83b8
This commit is contained in:
@@ -43,6 +43,7 @@
|
||||
#include <trace/hooks/traps.h>
|
||||
#include <trace/hooks/fault.h>
|
||||
#include <trace/hooks/topology.h>
|
||||
#include <trace/hooks/rwsem.h>
|
||||
|
||||
/*
|
||||
* Export tracepoints that act as a bare tracehook (ie: have no trace event
|
||||
@@ -141,3 +142,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_test_clear_look_around_ref);
|
||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_arm64_serror_panic);
|
||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_do_sea);
|
||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_cpu_capacity_show);
|
||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_init);
|
||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_wake);
|
||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_write_finished);
|
||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_alter_rwsem_list_add);
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#ifdef CONFIG_RWSEM_SPIN_ON_OWNER
|
||||
#include <linux/osq_lock.h>
|
||||
#endif
|
||||
#include <linux/android_vendor.h>
|
||||
|
||||
/*
|
||||
* For an uncontended rwsem, count and owner are the only fields a task
|
||||
@@ -64,6 +65,7 @@ struct rw_semaphore {
|
||||
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
||||
struct lockdep_map dep_map;
|
||||
#endif
|
||||
ANDROID_VENDOR_DATA(1);
|
||||
};
|
||||
|
||||
#define RWSEM_UNLOCKED_VALUE 0UL
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#undef TRACE_SYSTEM
|
||||
#define TRACE_SYSTEM rwsem
|
||||
#define TRACE_INCLUDE_PATH trace/hooks
|
||||
#if !defined(_TRACE_HOOK_RWSEM_H) || defined(TRACE_HEADER_MULTI_READ)
|
||||
#define _TRACE_HOOK_RWSEM_H
|
||||
#include <trace/hooks/vendor_hooks.h>
|
||||
/*
|
||||
* Following tracepoints are not exported in tracefs and provide a
|
||||
* mechanism for vendor modules to hook and extend functionality
|
||||
*/
|
||||
struct rw_semaphore;
|
||||
struct rwsem_waiter;
|
||||
DECLARE_HOOK(android_vh_rwsem_init,
|
||||
TP_PROTO(struct rw_semaphore *sem),
|
||||
TP_ARGS(sem));
|
||||
DECLARE_HOOK(android_vh_rwsem_wake,
|
||||
TP_PROTO(struct rw_semaphore *sem),
|
||||
TP_ARGS(sem));
|
||||
DECLARE_HOOK(android_vh_rwsem_write_finished,
|
||||
TP_PROTO(struct rw_semaphore *sem),
|
||||
TP_ARGS(sem));
|
||||
DECLARE_HOOK(android_vh_alter_rwsem_list_add,
|
||||
TP_PROTO(struct rwsem_waiter *waiter,
|
||||
struct rw_semaphore *sem,
|
||||
bool *already_on_list),
|
||||
TP_ARGS(waiter, sem, already_on_list));
|
||||
#endif /* _TRACE_HOOK_RWSEM_H */
|
||||
/* This part must be outside protection */
|
||||
#include <trace/define_trace.h>
|
||||
+18
-2
@@ -32,6 +32,7 @@
|
||||
#ifndef CONFIG_PREEMPT_RT
|
||||
#include "lock_events.h"
|
||||
#include <trace/hooks/dtask.h>
|
||||
#include <trace/hooks/rwsem.h>
|
||||
|
||||
/*
|
||||
* The least significant 2 bits of the owner value has the following
|
||||
@@ -326,6 +327,7 @@ void __init_rwsem(struct rw_semaphore *sem, const char *name,
|
||||
#ifdef CONFIG_RWSEM_SPIN_ON_OWNER
|
||||
osq_lock_init(&sem->osq);
|
||||
#endif
|
||||
trace_android_vh_rwsem_init(sem);
|
||||
}
|
||||
EXPORT_SYMBOL(__init_rwsem);
|
||||
|
||||
@@ -998,6 +1000,7 @@ rwsem_down_read_slowpath(struct rw_semaphore *sem, long count, unsigned int stat
|
||||
long rcnt = (count >> RWSEM_READER_SHIFT);
|
||||
struct rwsem_waiter waiter;
|
||||
DEFINE_WAKE_Q(wake_q);
|
||||
bool already_on_list = false;
|
||||
|
||||
/*
|
||||
* To prevent a constant stream of readers from starving a sleeping
|
||||
@@ -1054,12 +1057,17 @@ queue:
|
||||
}
|
||||
adjustment += RWSEM_FLAG_WAITERS;
|
||||
}
|
||||
rwsem_add_waiter(sem, &waiter);
|
||||
trace_android_vh_alter_rwsem_list_add(
|
||||
&waiter,
|
||||
sem, &already_on_list);
|
||||
if (!already_on_list)
|
||||
rwsem_add_waiter(sem, &waiter);
|
||||
|
||||
/* we're now waiting on the lock, but no longer actively locking */
|
||||
count = atomic_long_add_return(adjustment, &sem->count);
|
||||
|
||||
rwsem_cond_wake_waiter(sem, count, &wake_q);
|
||||
trace_android_vh_rwsem_wake(sem);
|
||||
raw_spin_unlock_irq(&sem->wait_lock);
|
||||
|
||||
if (!wake_q_empty(&wake_q))
|
||||
@@ -1110,6 +1118,7 @@ rwsem_down_write_slowpath(struct rw_semaphore *sem, int state)
|
||||
{
|
||||
struct rwsem_waiter waiter;
|
||||
DEFINE_WAKE_Q(wake_q);
|
||||
bool already_on_list = false;
|
||||
|
||||
/* do optimistic spinning and steal lock if possible */
|
||||
if (rwsem_can_spin_on_owner(sem) && rwsem_optimistic_spin(sem)) {
|
||||
@@ -1127,7 +1136,11 @@ rwsem_down_write_slowpath(struct rw_semaphore *sem, int state)
|
||||
waiter.handoff_set = false;
|
||||
|
||||
raw_spin_lock_irq(&sem->wait_lock);
|
||||
rwsem_add_waiter(sem, &waiter);
|
||||
trace_android_vh_alter_rwsem_list_add(
|
||||
&waiter,
|
||||
sem, &already_on_list);
|
||||
if (!already_on_list)
|
||||
rwsem_add_waiter(sem, &waiter);
|
||||
|
||||
/* we're now waiting on the lock */
|
||||
if (rwsem_first_waiter(sem) != &waiter) {
|
||||
@@ -1146,6 +1159,7 @@ rwsem_down_write_slowpath(struct rw_semaphore *sem, int state)
|
||||
atomic_long_or(RWSEM_FLAG_WAITERS, &sem->count);
|
||||
}
|
||||
|
||||
trace_android_vh_rwsem_wake(sem);
|
||||
/* wait until we successfully acquire the lock */
|
||||
trace_android_vh_rwsem_write_wait_start(sem);
|
||||
set_current_state(state);
|
||||
@@ -1634,6 +1648,7 @@ EXPORT_SYMBOL(up_read);
|
||||
void up_write(struct rw_semaphore *sem)
|
||||
{
|
||||
rwsem_release(&sem->dep_map, _RET_IP_);
|
||||
trace_android_vh_rwsem_write_finished(sem);
|
||||
__up_write(sem);
|
||||
}
|
||||
EXPORT_SYMBOL(up_write);
|
||||
@@ -1644,6 +1659,7 @@ EXPORT_SYMBOL(up_write);
|
||||
void downgrade_write(struct rw_semaphore *sem)
|
||||
{
|
||||
lock_downgrade(&sem->dep_map, _RET_IP_);
|
||||
trace_android_vh_rwsem_write_finished(sem);
|
||||
__downgrade_write(sem);
|
||||
}
|
||||
EXPORT_SYMBOL(downgrade_write);
|
||||
|
||||
Reference in New Issue
Block a user