ANDROID: add support for vendor hooks
Add support for vendor hooks. Adds include/trace/hooks directory for trace definition headers where hooks can be defined and vendor_hook.c for instantiating and exporting them for vendor modules. There are two variants of vendor hooks, both based on tracepoints: Normal: this uses the DECLARE_HOOK macro to create a tracepoint function with the name trace_<name> where <name> is the unique identifier for the trace. Restricted: restricted hooks are needed for cases like scheduler hooks where the attached function must be called even if the cpu is offline or requires a non-atomic context. Restricted vendor hooks cannot be detached, so modules that attach to a restricted hook can never unload. Also, only 1 attachment is allowed (any other attempts to attach will fail with -EBUSY). For either case, modules attach to the hook by using register_trace_<name>(func_ptr, NULL). New hooks should be defined in headers in the include/trace/hooks/ directory using the DECLARE_HOOK() or DECLARE_RESTRICTED_HOOK() macros. New files added to include/trace/hooks should be #include'd from drivers/android/vendor_hooks.c. The EXPORT_TRACEPOINT_SYMBOL_GPL() should be also added to drivers/android/vendor_hooks.c. For example, if a new hook, 'android_vh_foo(int &ret)' is added in do_exit() in exit.c, these changes are needed: 1. create a new header file include/trace/hooks/foo.h which contains: #include <trace/hooks/vendor_hooks.h> ... DECLARE_HOOK(android_vh_foo, TP_PROTO(int *retp), TP_ARGS(retp); 2. in exit.c, add #include <trace/hooks/foo.h> ... int ret = 0; ... android_vh_foo(&ret); if (ret) return ret; ... 3. in drivers/android/vendor_hooks.c, add #include <trace/hooks/foo.h> ... EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_foo); The hook can then be attached by adding the registration code to the module: #include <trace/hooks/sched.h> ... static void my_foo(int *retp) { *retp = 0; } ... rc = register_trace_android_vh_sched_exit(my_foo, NULL); Bug: 156285741 Signed-off-by: Todd Kjos <tkjos@google.com> Change-Id: I6a7d1c8919dae91c965e2a0450df50eac2d282db
This commit is contained in:
@@ -398,6 +398,7 @@ CONFIG_GENERIC_PHY=y
|
||||
CONFIG_ANDROID=y
|
||||
CONFIG_ANDROID_BINDER_IPC=y
|
||||
CONFIG_ANDROID_BINDERFS=y
|
||||
CONFIG_ANDROID_VENDOR_HOOKS=y
|
||||
CONFIG_LIBNVDIMM=y
|
||||
# CONFIG_ND_BLK is not set
|
||||
CONFIG_INTERCONNECT=y
|
||||
|
@@ -339,6 +339,7 @@ CONFIG_IIO_TRIGGER=y
|
||||
CONFIG_ANDROID=y
|
||||
CONFIG_ANDROID_BINDER_IPC=y
|
||||
CONFIG_ANDROID_BINDERFS=y
|
||||
CONFIG_ANDROID_VENDOR_HOOKS=y
|
||||
CONFIG_LIBNVDIMM=y
|
||||
# CONFIG_ND_BLK is not set
|
||||
CONFIG_INTERCONNECT=y
|
||||
|
@@ -54,6 +54,15 @@ config ANDROID_BINDER_IPC_SELFTEST
|
||||
exhaustively with combinations of various buffer sizes and
|
||||
alignments.
|
||||
|
||||
config ANDROID_VENDOR_HOOKS
|
||||
bool "Android Vendor Hooks"
|
||||
depends on TRACEPOINTS
|
||||
---help---
|
||||
Enable vendor hooks implemented as tracepoints
|
||||
|
||||
Allow vendor modules to attach to tracepoint "hooks" defined via
|
||||
DECLARE_HOOK or DECLARE_RESTRICTED_HOOK.
|
||||
|
||||
endif # if ANDROID
|
||||
|
||||
endmenu
|
||||
|
@@ -4,3 +4,4 @@ ccflags-y += -I$(src) # needed for trace events
|
||||
obj-$(CONFIG_ANDROID_BINDERFS) += binderfs.o
|
||||
obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o binder_alloc.o
|
||||
obj-$(CONFIG_ANDROID_BINDER_IPC_SELFTEST) += binder_alloc_selftest.o
|
||||
obj-$(CONFIG_ANDROID_VENDOR_HOOKS) += vendor_hooks.o
|
||||
|
16
drivers/android/vendor_hooks.c
Normal file
16
drivers/android/vendor_hooks.c
Normal file
@@ -0,0 +1,16 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* vendor_hook.c
|
||||
*
|
||||
* Android Vendor Hook Support
|
||||
*
|
||||
* Copyright (C) 2020 Google, Inc.
|
||||
*/
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include <trace/hooks/vendor_hooks.h>
|
||||
|
||||
/*
|
||||
* Export tracepoints that act as a bare tracehook (ie: have no trace event
|
||||
* associated with them) to allow external modules to probe them.
|
||||
*/
|
||||
|
72
include/trace/hooks/vendor_hooks.h
Normal file
72
include/trace/hooks/vendor_hooks.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
#if !defined(_TRACE_VENDOR_HOOKS_H) || defined(TRACE_HEADER_MULTI_READ)
|
||||
#define _TRACE_VENDOR_HOOKS_H
|
||||
|
||||
#include <linux/tracepoint.h>
|
||||
|
||||
#define DECLARE_HOOK DECLARE_TRACE
|
||||
|
||||
#ifdef TRACE_HEADER_MULTI_READ
|
||||
|
||||
#undef DECLARE_RESTRICTED_HOOK
|
||||
#define DECLARE_RESTRICTED_HOOK(name, proto, args, cond) \
|
||||
DEFINE_TRACE(name)
|
||||
|
||||
/* prevent additional recursion */
|
||||
#undef TRACE_HEADER_MULTI_READ
|
||||
#else /* TRACE_HEADER_MULTI_READ */
|
||||
|
||||
#define DO_HOOK(tp, proto, args, cond) \
|
||||
do { \
|
||||
struct tracepoint_func *it_func_ptr; \
|
||||
void *it_func; \
|
||||
void *__data; \
|
||||
\
|
||||
if (!(cond)) \
|
||||
return; \
|
||||
\
|
||||
it_func_ptr = (tp)->funcs; \
|
||||
if (it_func_ptr) { \
|
||||
it_func = (it_func_ptr)->func; \
|
||||
__data = (it_func_ptr)->data; \
|
||||
((void(*)(proto))(it_func))(args); \
|
||||
WARN_ON(((++it_func_ptr)->func)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define __DECLARE_HOOK(name, proto, args, cond, data_proto, data_args) \
|
||||
extern struct tracepoint __tracepoint_##name; \
|
||||
static inline void trace_##name(proto) \
|
||||
{ \
|
||||
if (static_key_false(&__tracepoint_##name.key)) \
|
||||
DO_HOOK(&__tracepoint_##name, \
|
||||
TP_PROTO(data_proto), \
|
||||
TP_ARGS(data_args), \
|
||||
TP_CONDITION(cond)); \
|
||||
} \
|
||||
static inline bool \
|
||||
trace_##name##_enabled(void) \
|
||||
{ \
|
||||
return static_key_false(&__tracepoint_##name.key); \
|
||||
} \
|
||||
static inline int \
|
||||
register_trace_##name(void (*probe)(data_proto), void *data) \
|
||||
{ \
|
||||
/* only allow a single attachment */ \
|
||||
if (trace_##name##_enabled()) \
|
||||
return -EBUSY; \
|
||||
return tracepoint_probe_register(&__tracepoint_##name, \
|
||||
(void *)probe, data); \
|
||||
} \
|
||||
/* vendor hooks cannot be unregistered */ \
|
||||
|
||||
#define DECLARE_RESTRICTED_HOOK(name, proto, args, cond) \
|
||||
__DECLARE_HOOK(name, PARAMS(proto), PARAMS(args), \
|
||||
cond, \
|
||||
PARAMS(void *__data, proto), \
|
||||
PARAMS(__data, args))
|
||||
|
||||
#endif /* TRACE_HEADER_MULTI_READ */
|
||||
|
||||
#endif /* _TRACE_VENDOR_HOOKS_H */
|
Reference in New Issue
Block a user