[PATCH] tracepoints: Implement it with dynamic functions

From: Steven Rostedt (VMware)
Date: Fri Oct 05 2018 - 09:31:43 EST


Signed-off-by: Steven Rostedt (VMware) <rostedt@xxxxxxxxxxx>
---
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 <linux/atomic.h>
#include <linux/static_key.h>

+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 <linux/cpumask.h>
#include <linux/rcupdate.h>
#include <linux/tracepoint-defs.h>
+#include <linux/static_call.h>

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


--MP_/oQYGN0stwB_381CxFSfiLTe--