Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cfde7b83 authored by JianMin Liu's avatar JianMin Liu Committed by Todd Kjos
Browse files

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: 161400830

Signed-off-by: default avatarJianMin Liu <jian-min.liu@mediatek.com>
Change-Id: I007a5e26f3db2adaeaf4e5ccea414ce7abfa83b8
parent 06f8eab9
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#include <trace/hooks/dtask.h>
#include <trace/hooks/net.h>
#include <trace/hooks/binder.h>
#include <trace/hooks/rwsem.h>

/*
 * Export tracepoints that act as a bare tracehook (ie: have no trace event
@@ -30,3 +31,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_kfree_skb);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_transaction_init);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_set_priority);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_restore_priority);
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);
+2 −0
Original line number Diff line number Diff line
@@ -19,6 +19,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
@@ -51,6 +52,7 @@ struct rw_semaphore {
#ifdef CONFIG_DEBUG_LOCK_ALLOC
	struct lockdep_map	dep_map;
#endif
	ANDROID_VENDOR_DATA(1);
};

/*
+38 −0
Original line number Diff line number Diff line
/* 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 <linux/tracepoint.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
 */
#if defined(CONFIG_TRACEPOINTS) && defined(CONFIG_ANDROID_VENDOR_HOOKS)
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));
#else
#define trace_android_vh_rwsem_init(sem)
#define trace_android_vh_rwsem_wake(sem)
#define trace_android_vh_rwsem_write_finished(sem)
#define trace_android_vh_alter_rwsem_list_add(waiter, sem, already_on_list)
#endif
#endif /* _TRACE_HOOK_RWSEM_H */
/* This part must be outside protection */
#include <trace/define_trace.h>
+18 −2
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#include "lock_events.h"

#include <trace/hooks/dtask.h>
#include <trace/hooks/rwsem.h>

/*
 * The least significant 3 bits of the owner value has the following
@@ -343,6 +344,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);

@@ -1000,6 +1002,7 @@ rwsem_down_read_slowpath(struct rw_semaphore *sem, int state)
	struct rwsem_waiter waiter;
	DEFINE_WAKE_Q(wake_q);
	bool wake = false;
	bool already_on_list = false;

	/*
	 * Save the current read-owner of rwsem, if available, and the
@@ -1061,6 +1064,10 @@ rwsem_down_read_slowpath(struct rw_semaphore *sem, int state)
		}
		adjustment += RWSEM_FLAG_WAITERS;
	}
	trace_android_vh_alter_rwsem_list_add(
					&waiter,
					sem, &already_on_list);
	if (!already_on_list)
		list_add_tail(&waiter.list, &sem->wait_list);

	/* we're now waiting on the lock, but no longer actively locking */
@@ -1083,6 +1090,7 @@ rwsem_down_read_slowpath(struct rw_semaphore *sem, int state)
		    (adjustment & RWSEM_FLAG_WAITERS)))
		rwsem_mark_wake(sem, RWSEM_WAKE_ANY, &wake_q);

	trace_android_vh_rwsem_wake(sem);
	raw_spin_unlock_irq(&sem->wait_lock);
	wake_up_q(&wake_q);

@@ -1149,6 +1157,7 @@ rwsem_down_write_slowpath(struct rw_semaphore *sem, int state)
	struct rwsem_waiter waiter;
	struct rw_semaphore *ret = sem;
	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_WR_NONSPINNABLE) &&
@@ -1177,6 +1186,10 @@ rwsem_down_write_slowpath(struct rw_semaphore *sem, int state)
	/* account for this before adding a new element to the list */
	wstate = list_empty(&sem->wait_list) ? WRITER_FIRST : WRITER_NOT_FIRST;

	trace_android_vh_alter_rwsem_list_add(
					&waiter,
					sem, &already_on_list);
	if (!already_on_list)
		list_add_tail(&waiter.list, &sem->wait_list);

	/* we're now waiting on the lock */
@@ -1213,6 +1226,7 @@ rwsem_down_write_slowpath(struct rw_semaphore *sem, int state)
	}

wait:
	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);
@@ -1592,6 +1606,7 @@ EXPORT_SYMBOL(up_read);
void up_write(struct rw_semaphore *sem)
{
	rwsem_release(&sem->dep_map, 1, _RET_IP_);
	trace_android_vh_rwsem_write_finished(sem);
	__up_write(sem);
}
EXPORT_SYMBOL(up_write);
@@ -1602,6 +1617,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);