diff options
Diffstat (limited to 'include/linux/ftrace.h')
| -rw-r--r-- | include/linux/ftrace.h | 77 |
1 files changed, 72 insertions, 5 deletions
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 028e26f0bf08..72a6cabb4d5b 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h | |||
| @@ -31,16 +31,33 @@ ftrace_enable_sysctl(struct ctl_table *table, int write, | |||
| 31 | 31 | ||
| 32 | typedef void (*ftrace_func_t)(unsigned long ip, unsigned long parent_ip); | 32 | typedef void (*ftrace_func_t)(unsigned long ip, unsigned long parent_ip); |
| 33 | 33 | ||
| 34 | /* | ||
| 35 | * FTRACE_OPS_FL_* bits denote the state of ftrace_ops struct and are | ||
| 36 | * set in the flags member. | ||
| 37 | * | ||
| 38 | * ENABLED - set/unset when ftrace_ops is registered/unregistered | ||
| 39 | * GLOBAL - set manualy by ftrace_ops user to denote the ftrace_ops | ||
| 40 | * is part of the global tracers sharing the same filter | ||
| 41 | * via set_ftrace_* debugfs files. | ||
| 42 | * DYNAMIC - set when ftrace_ops is registered to denote dynamically | ||
| 43 | * allocated ftrace_ops which need special care | ||
| 44 | * CONTROL - set manualy by ftrace_ops user to denote the ftrace_ops | ||
| 45 | * could be controled by following calls: | ||
| 46 | * ftrace_function_local_enable | ||
| 47 | * ftrace_function_local_disable | ||
| 48 | */ | ||
| 34 | enum { | 49 | enum { |
| 35 | FTRACE_OPS_FL_ENABLED = 1 << 0, | 50 | FTRACE_OPS_FL_ENABLED = 1 << 0, |
| 36 | FTRACE_OPS_FL_GLOBAL = 1 << 1, | 51 | FTRACE_OPS_FL_GLOBAL = 1 << 1, |
| 37 | FTRACE_OPS_FL_DYNAMIC = 1 << 2, | 52 | FTRACE_OPS_FL_DYNAMIC = 1 << 2, |
| 53 | FTRACE_OPS_FL_CONTROL = 1 << 3, | ||
| 38 | }; | 54 | }; |
| 39 | 55 | ||
| 40 | struct ftrace_ops { | 56 | struct ftrace_ops { |
| 41 | ftrace_func_t func; | 57 | ftrace_func_t func; |
| 42 | struct ftrace_ops *next; | 58 | struct ftrace_ops *next; |
| 43 | unsigned long flags; | 59 | unsigned long flags; |
| 60 | int __percpu *disabled; | ||
| 44 | #ifdef CONFIG_DYNAMIC_FTRACE | 61 | #ifdef CONFIG_DYNAMIC_FTRACE |
| 45 | struct ftrace_hash *notrace_hash; | 62 | struct ftrace_hash *notrace_hash; |
| 46 | struct ftrace_hash *filter_hash; | 63 | struct ftrace_hash *filter_hash; |
| @@ -97,6 +114,55 @@ int register_ftrace_function(struct ftrace_ops *ops); | |||
| 97 | int unregister_ftrace_function(struct ftrace_ops *ops); | 114 | int unregister_ftrace_function(struct ftrace_ops *ops); |
| 98 | void clear_ftrace_function(void); | 115 | void clear_ftrace_function(void); |
| 99 | 116 | ||
| 117 | /** | ||
| 118 | * ftrace_function_local_enable - enable controlled ftrace_ops on current cpu | ||
| 119 | * | ||
| 120 | * This function enables tracing on current cpu by decreasing | ||
| 121 | * the per cpu control variable. | ||
| 122 | * It must be called with preemption disabled and only on ftrace_ops | ||
| 123 | * registered with FTRACE_OPS_FL_CONTROL. If called without preemption | ||
| 124 | * disabled, this_cpu_ptr will complain when CONFIG_DEBUG_PREEMPT is enabled. | ||
| 125 | */ | ||
| 126 | static inline void ftrace_function_local_enable(struct ftrace_ops *ops) | ||
| 127 | { | ||
| 128 | if (WARN_ON_ONCE(!(ops->flags & FTRACE_OPS_FL_CONTROL))) | ||
| 129 | return; | ||
| 130 | |||
| 131 | (*this_cpu_ptr(ops->disabled))--; | ||
| 132 | } | ||
| 133 | |||
| 134 | /** | ||
| 135 | * ftrace_function_local_disable - enable controlled ftrace_ops on current cpu | ||
| 136 | * | ||
| 137 | * This function enables tracing on current cpu by decreasing | ||
| 138 | * the per cpu control variable. | ||
| 139 | * It must be called with preemption disabled and only on ftrace_ops | ||
| 140 | * registered with FTRACE_OPS_FL_CONTROL. If called without preemption | ||
| 141 | * disabled, this_cpu_ptr will complain when CONFIG_DEBUG_PREEMPT is enabled. | ||
| 142 | */ | ||
| 143 | static inline void ftrace_function_local_disable(struct ftrace_ops *ops) | ||
| 144 | { | ||
| 145 | if (WARN_ON_ONCE(!(ops->flags & FTRACE_OPS_FL_CONTROL))) | ||
| 146 | return; | ||
| 147 | |||
| 148 | (*this_cpu_ptr(ops->disabled))++; | ||
| 149 | } | ||
| 150 | |||
| 151 | /** | ||
| 152 | * ftrace_function_local_disabled - returns ftrace_ops disabled value | ||
| 153 | * on current cpu | ||
| 154 | * | ||
| 155 | * This function returns value of ftrace_ops::disabled on current cpu. | ||
| 156 | * It must be called with preemption disabled and only on ftrace_ops | ||
| 157 | * registered with FTRACE_OPS_FL_CONTROL. If called without preemption | ||
| 158 | * disabled, this_cpu_ptr will complain when CONFIG_DEBUG_PREEMPT is enabled. | ||
| 159 | */ | ||
| 160 | static inline int ftrace_function_local_disabled(struct ftrace_ops *ops) | ||
| 161 | { | ||
| 162 | WARN_ON_ONCE(!(ops->flags & FTRACE_OPS_FL_CONTROL)); | ||
| 163 | return *this_cpu_ptr(ops->disabled); | ||
| 164 | } | ||
| 165 | |||
| 100 | extern void ftrace_stub(unsigned long a0, unsigned long a1); | 166 | extern void ftrace_stub(unsigned long a0, unsigned long a1); |
| 101 | 167 | ||
| 102 | #else /* !CONFIG_FUNCTION_TRACER */ | 168 | #else /* !CONFIG_FUNCTION_TRACER */ |
| @@ -178,12 +244,13 @@ struct dyn_ftrace { | |||
| 178 | }; | 244 | }; |
| 179 | 245 | ||
| 180 | int ftrace_force_update(void); | 246 | int ftrace_force_update(void); |
| 181 | void ftrace_set_filter(struct ftrace_ops *ops, unsigned char *buf, | 247 | int ftrace_set_filter(struct ftrace_ops *ops, unsigned char *buf, |
| 182 | int len, int reset); | 248 | int len, int reset); |
| 183 | void ftrace_set_notrace(struct ftrace_ops *ops, unsigned char *buf, | 249 | int ftrace_set_notrace(struct ftrace_ops *ops, unsigned char *buf, |
| 184 | int len, int reset); | 250 | int len, int reset); |
| 185 | void ftrace_set_global_filter(unsigned char *buf, int len, int reset); | 251 | void ftrace_set_global_filter(unsigned char *buf, int len, int reset); |
| 186 | void ftrace_set_global_notrace(unsigned char *buf, int len, int reset); | 252 | void ftrace_set_global_notrace(unsigned char *buf, int len, int reset); |
| 253 | void ftrace_free_filter(struct ftrace_ops *ops); | ||
| 187 | 254 | ||
| 188 | int register_ftrace_command(struct ftrace_func_command *cmd); | 255 | int register_ftrace_command(struct ftrace_func_command *cmd); |
| 189 | int unregister_ftrace_command(struct ftrace_func_command *cmd); | 256 | int unregister_ftrace_command(struct ftrace_func_command *cmd); |
| @@ -314,9 +381,6 @@ extern void ftrace_enable_daemon(void); | |||
| 314 | #else | 381 | #else |
| 315 | static inline int skip_trace(unsigned long ip) { return 0; } | 382 | static inline int skip_trace(unsigned long ip) { return 0; } |
| 316 | static inline int ftrace_force_update(void) { return 0; } | 383 | static inline int ftrace_force_update(void) { return 0; } |
| 317 | static inline void ftrace_set_filter(unsigned char *buf, int len, int reset) | ||
| 318 | { | ||
| 319 | } | ||
| 320 | static inline void ftrace_disable_daemon(void) { } | 384 | static inline void ftrace_disable_daemon(void) { } |
| 321 | static inline void ftrace_enable_daemon(void) { } | 385 | static inline void ftrace_enable_daemon(void) { } |
| 322 | static inline void ftrace_release_mod(struct module *mod) {} | 386 | static inline void ftrace_release_mod(struct module *mod) {} |
| @@ -340,6 +404,9 @@ static inline int ftrace_text_reserved(void *start, void *end) | |||
| 340 | */ | 404 | */ |
| 341 | #define ftrace_regex_open(ops, flag, inod, file) ({ -ENODEV; }) | 405 | #define ftrace_regex_open(ops, flag, inod, file) ({ -ENODEV; }) |
| 342 | #define ftrace_set_early_filter(ops, buf, enable) do { } while (0) | 406 | #define ftrace_set_early_filter(ops, buf, enable) do { } while (0) |
| 407 | #define ftrace_set_filter(ops, buf, len, reset) ({ -ENODEV; }) | ||
| 408 | #define ftrace_set_notrace(ops, buf, len, reset) ({ -ENODEV; }) | ||
| 409 | #define ftrace_free_filter(ops) do { } while (0) | ||
| 343 | 410 | ||
| 344 | static inline ssize_t ftrace_filter_write(struct file *file, const char __user *ubuf, | 411 | static inline ssize_t ftrace_filter_write(struct file *file, const char __user *ubuf, |
| 345 | size_t cnt, loff_t *ppos) { return -ENODEV; } | 412 | size_t cnt, loff_t *ppos) { return -ENODEV; } |
