From 341d8326ef359ebfdf7923e01e225f653111c304 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (VMware)" Date: Fri, 5 Oct 2018 09:31:43 -0400 Subject: [PATCH] tracepoints: Implement it with dynamic functions Signed-off-by: Steven Rostedt (VMware) --- include/linux/tracepoint-defs.h | 4 +++- include/linux/tracepoint.h | 24 ++++++++++++------------ kernel/tracepoint.c | 8 ++++---- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/include/linux/tracepoint-defs.h b/include/linux/tracepoint-defs.h index 8013fc442964..ae16672bea61 100644 --- a/include/linux/tracepoint-defs.h +++ b/include/linux/tracepoint-defs.h @@ -11,6 +11,8 @@ #include #include +struct static_call_key; + struct trace_print_flags { unsigned long mask; const char *name; @@ -30,7 +32,7 @@ struct tracepoint_func { struct tracepoint { const char *name; /* Tracepoint name */ struct static_key key; - void **function_ptr; + struct static_call_key *static_call_key; void *iterator; int (*regfunc)(void); void (*unregfunc)(void); diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index b60d547c44ba..e0d787a7e68b 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -21,6 +21,7 @@ #include #include #include +#include struct module; struct tracepoint; @@ -191,8 +192,7 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) rcu_dereference_raw((&__tracepoint_##name)->funcs); \ if (it_func_ptr) { \ __data = (it_func_ptr)->data; \ - /* printk("%pS\n", __tp_func_##name); */ \ - __tp_func_##name(args); \ + static_call(__tp_func_##name, args); \ } \ \ if (rcuidle) { \ @@ -230,8 +230,8 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) * poking RCU a bit. */ #define __DECLARE_TRACE(name, proto, args, cond, data_proto, data_args) \ - extern void __tracepoint_iter_##name(data_proto); \ - extern void (*__tp_func_##name)(data_proto); \ + extern int __tracepoint_iter_##name(data_proto); \ + DECLARE_STATIC_CALL(__tp_func_##name, __tracepoint_iter_##name); \ extern struct tracepoint __tracepoint_##name; \ static inline void trace_##name(proto) \ { \ @@ -285,16 +285,15 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) #define DEFINE_TRACE_FN(name, reg, unreg, proto, args) \ static const char __tpstrtab_##name[] \ __attribute__((section("__tracepoints_strings"))) = #name; \ - void __tracepoint_iter_##name(void *__data, proto); \ - void (*__tp_func_##name)(void *__data, proto) = \ - __tracepoint_iter_##name; \ + int __tracepoint_iter_##name(void *__data, proto); \ + extern struct static_call_key __tp_func_##name; \ struct tracepoint __tracepoint_##name \ __attribute__((section("__tracepoints"), used)) = \ { __tpstrtab_##name, STATIC_KEY_INIT_FALSE, \ - (void **)&__tp_func_##name, __tracepoint_iter_##name, \ + &__tp_func_##name, __tracepoint_iter_##name, \ reg, unreg, NULL }; \ __TRACEPOINT_ENTRY(name); \ - void __tracepoint_iter_##name(void *__data, proto) \ + int __tracepoint_iter_##name(void *__data, proto) \ { \ struct tracepoint_func *it_func_ptr; \ void *it_func; \ @@ -307,17 +306,18 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) ((void(*)(void *, proto))(it_func))(__data, args); \ } while ((++it_func_ptr)->func); \ return 0; \ - } + } \ + DEFINE_STATIC_CALL(__tp_func_##name, __tracepoint_iter_##name); #define DEFINE_TRACE(name, proto, args) \ DEFINE_TRACE_FN(name, NULL, NULL, PARAMS(proto), PARAMS(args)); #define EXPORT_TRACEPOINT_SYMBOL_GPL(name) \ EXPORT_SYMBOL_GPL(__tracepoint_##name); \ - EXPORT_SYMBOL_GPL(__tp_func_##name) + EXPORT_STATIC_CALL_GPL(__tp_func_##name) #define EXPORT_TRACEPOINT_SYMBOL(name) \ EXPORT_SYMBOL(__tracepoint_##name); \ - EXPORT_SYMBOL(__tp_func_##name) + EXPORT_STATIC_CALL(__tp_func_##name) #else /* !TRACEPOINTS_ENABLED */ diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c index 7e1f34edd1d7..4105bdd872f9 100644 --- a/kernel/tracepoint.c +++ b/kernel/tracepoint.c @@ -271,10 +271,10 @@ static int tracepoint_add_func(struct tracepoint *tp, if (probes == 1) { printk("make direct call to %pS\n", tp_funcs->func); - *tp->function_ptr = tp_funcs->func; + __static_call_update(tp->static_call_key, tp_funcs->func); } else { printk("[%d] make call to iterator %pS\n", probes, tp->iterator); - *tp->function_ptr = tp->iterator; + __static_call_update(tp->static_call_key, tp->iterator); } release_probes(old); @@ -312,10 +312,10 @@ static int tracepoint_remove_func(struct tracepoint *tp, if (probes_left == 1) { printk("make direct call to %pS\n", tp_funcs->func); - *tp->function_ptr = tp_funcs->func; + __static_call_update(tp->static_call_key, tp_funcs->func); } else { printk("[%d] make call to iterator %pS\n", probes_left, tp->iterator); - *tp->function_ptr = tp->iterator; + __static_call_update(tp->static_call_key, tp->iterator); } rcu_assign_pointer(tp->funcs, tp_funcs); -- 2.19.1