static keys: Introduce 'struct static_key', static_key_true()/false() and static_key_...
[platform/adaptation/renesas_rcar/renesas_kernel.git] / include / linux / tracepoint.h
index df0a779..bd96ecd 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/rcupdate.h>
-#include <linux/jump_label.h>
+#include <linux/static_key.h>
 
 struct module;
 struct tracepoint;
@@ -29,7 +29,7 @@ struct tracepoint_func {
 
 struct tracepoint {
        const char *name;               /* Tracepoint name */
-       struct jump_label_key key;
+       struct static_key key;
        void (*regfunc)(void);
        void (*unregfunc)(void);
        struct tracepoint_func __rcu *funcs;
@@ -114,7 +114,7 @@ static inline void tracepoint_synchronize_unregister(void)
  * as "(void *, void)". The DECLARE_TRACE_NOARGS() will pass in just
  * "void *data", where as the DECLARE_TRACE() will pass in "void *data, proto".
  */
-#define __DO_TRACE(tp, proto, args, cond)                              \
+#define __DO_TRACE(tp, proto, args, cond, prercu, postrcu)             \
        do {                                                            \
                struct tracepoint_func *it_func_ptr;                    \
                void *it_func;                                          \
@@ -122,6 +122,7 @@ static inline void tracepoint_synchronize_unregister(void)
                                                                        \
                if (!(cond))                                            \
                        return;                                         \
+               prercu;                                                 \
                rcu_read_lock_sched_notrace();                          \
                it_func_ptr = rcu_dereference_sched((tp)->funcs);       \
                if (it_func_ptr) {                                      \
@@ -132,6 +133,7 @@ static inline void tracepoint_synchronize_unregister(void)
                        } while ((++it_func_ptr)->func);                \
                }                                                       \
                rcu_read_unlock_sched_notrace();                        \
+               postrcu;                                                \
        } while (0)
 
 /*
@@ -139,15 +141,25 @@ static inline void tracepoint_synchronize_unregister(void)
  * not add unwanted padding between the beginning of the section and the
  * structure. Force alignment to the same alignment as the section start.
  */
-#define __DECLARE_TRACE(name, proto, args, cond, data_proto, data_args)        \
+#define __DECLARE_TRACE(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_TRACE(&__tracepoint_##name,                \
+                               TP_PROTO(data_proto),                   \
+                               TP_ARGS(data_args),                     \
+                               TP_CONDITION(cond),,);                  \
+       }                                                               \
+       static inline void trace_##name##_rcuidle(proto)                \
+       {                                                               \
                if (static_branch(&__tracepoint_##name.key))            \
                        __DO_TRACE(&__tracepoint_##name,                \
                                TP_PROTO(data_proto),                   \
                                TP_ARGS(data_args),                     \
-                               TP_CONDITION(cond));                    \
+                               TP_CONDITION(cond),                     \
+                               rcu_idle_exit(),                        \
+                               rcu_idle_enter());                      \
        }                                                               \
        static inline int                                               \
        register_trace_##name(void (*probe)(data_proto), void *data)    \
@@ -176,7 +188,7 @@ static inline void tracepoint_synchronize_unregister(void)
        __attribute__((section("__tracepoints_strings"))) = #name;       \
        struct tracepoint __tracepoint_##name                            \
        __attribute__((section("__tracepoints"))) =                      \
-               { __tpstrtab_##name, JUMP_LABEL_INIT, reg, unreg, NULL };\
+               { __tpstrtab_##name, STATIC_KEY_INIT_FALSE, reg, unreg, NULL };\
        static struct tracepoint * const __tracepoint_ptr_##name __used  \
        __attribute__((section("__tracepoints_ptrs"))) =                 \
                &__tracepoint_##name;
@@ -190,9 +202,11 @@ static inline void tracepoint_synchronize_unregister(void)
        EXPORT_SYMBOL(__tracepoint_##name)
 
 #else /* !CONFIG_TRACEPOINTS */
-#define __DECLARE_TRACE(name, proto, args, cond, data_proto, data_args)        \
+#define __DECLARE_TRACE(name, proto, args, cond, data_proto, data_args) \
        static inline void trace_##name(proto)                          \
        { }                                                             \
+       static inline void trace_##name##_rcuidle(proto)                \
+       { }                                                             \
        static inline int                                               \
        register_trace_##name(void (*probe)(data_proto),                \
                              void *data)                               \