Commit 647664eaf4033501739ac1f42dd52ce8c9266ccc
Committed by
Steven Rostedt
1 parent
ad97772ad8
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
ftrace: add ftrace_set_filter_ip() for address based filter
Add a new filter update interface ftrace_set_filter_ip() to set ftrace filter by ip address, not only glob pattern. Link: http://lkml.kernel.org/r/20120605102808.27845.67952.stgit@localhost.localdomain Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@redhat.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com> Cc: "Frank Ch. Eigler" <fche@redhat.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Frederic Weisbecker <fweisbec@gmail.com> Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Showing 2 changed files with 60 additions and 2 deletions Side-by-side Diff
include/linux/ftrace.h
... | ... | @@ -317,6 +317,8 @@ |
317 | 317 | }; |
318 | 318 | |
319 | 319 | int ftrace_force_update(void); |
320 | +int ftrace_set_filter_ip(struct ftrace_ops *ops, unsigned long ip, | |
321 | + int remove, int reset); | |
320 | 322 | int ftrace_set_filter(struct ftrace_ops *ops, unsigned char *buf, |
321 | 323 | int len, int reset); |
322 | 324 | int ftrace_set_notrace(struct ftrace_ops *ops, unsigned char *buf, |
... | ... | @@ -544,6 +546,7 @@ |
544 | 546 | */ |
545 | 547 | #define ftrace_regex_open(ops, flag, inod, file) ({ -ENODEV; }) |
546 | 548 | #define ftrace_set_early_filter(ops, buf, enable) do { } while (0) |
549 | +#define ftrace_set_filter_ip(ops, ip, remove, reset) ({ -ENODEV; }) | |
547 | 550 | #define ftrace_set_filter(ops, buf, len, reset) ({ -ENODEV; }) |
548 | 551 | #define ftrace_set_notrace(ops, buf, len, reset) ({ -ENODEV; }) |
549 | 552 | #define ftrace_free_filter(ops) do { } while (0) |
kernel/trace/ftrace.c
... | ... | @@ -3242,9 +3242,28 @@ |
3242 | 3242 | } |
3243 | 3243 | |
3244 | 3244 | static int |
3245 | -ftrace_set_regex(struct ftrace_ops *ops, unsigned char *buf, int len, | |
3246 | - int reset, int enable) | |
3245 | +ftrace_match_addr(struct ftrace_hash *hash, unsigned long ip, int remove) | |
3247 | 3246 | { |
3247 | + struct ftrace_func_entry *entry; | |
3248 | + | |
3249 | + if (!ftrace_location(ip)) | |
3250 | + return -EINVAL; | |
3251 | + | |
3252 | + if (remove) { | |
3253 | + entry = ftrace_lookup_ip(hash, ip); | |
3254 | + if (!entry) | |
3255 | + return -ENOENT; | |
3256 | + free_hash_entry(hash, entry); | |
3257 | + return 0; | |
3258 | + } | |
3259 | + | |
3260 | + return add_hash_entry(hash, ip); | |
3261 | +} | |
3262 | + | |
3263 | +static int | |
3264 | +ftrace_set_hash(struct ftrace_ops *ops, unsigned char *buf, int len, | |
3265 | + unsigned long ip, int remove, int reset, int enable) | |
3266 | +{ | |
3248 | 3267 | struct ftrace_hash **orig_hash; |
3249 | 3268 | struct ftrace_hash *hash; |
3250 | 3269 | int ret; |
... | ... | @@ -3272,6 +3291,11 @@ |
3272 | 3291 | ret = -EINVAL; |
3273 | 3292 | goto out_regex_unlock; |
3274 | 3293 | } |
3294 | + if (ip) { | |
3295 | + ret = ftrace_match_addr(hash, ip, remove); | |
3296 | + if (ret < 0) | |
3297 | + goto out_regex_unlock; | |
3298 | + } | |
3275 | 3299 | |
3276 | 3300 | mutex_lock(&ftrace_lock); |
3277 | 3301 | ret = ftrace_hash_move(ops, enable, orig_hash, hash); |
... | ... | @@ -3286,6 +3310,37 @@ |
3286 | 3310 | |
3287 | 3311 | free_ftrace_hash(hash); |
3288 | 3312 | return ret; |
3313 | +} | |
3314 | + | |
3315 | +static int | |
3316 | +ftrace_set_addr(struct ftrace_ops *ops, unsigned long ip, int remove, | |
3317 | + int reset, int enable) | |
3318 | +{ | |
3319 | + return ftrace_set_hash(ops, 0, 0, ip, remove, reset, enable); | |
3320 | +} | |
3321 | + | |
3322 | +/** | |
3323 | + * ftrace_set_filter_ip - set a function to filter on in ftrace by address | |
3324 | + * @ops - the ops to set the filter with | |
3325 | + * @ip - the address to add to or remove from the filter. | |
3326 | + * @remove - non zero to remove the ip from the filter | |
3327 | + * @reset - non zero to reset all filters before applying this filter. | |
3328 | + * | |
3329 | + * Filters denote which functions should be enabled when tracing is enabled | |
3330 | + * If @ip is NULL, it failes to update filter. | |
3331 | + */ | |
3332 | +int ftrace_set_filter_ip(struct ftrace_ops *ops, unsigned long ip, | |
3333 | + int remove, int reset) | |
3334 | +{ | |
3335 | + return ftrace_set_addr(ops, ip, remove, reset, 1); | |
3336 | +} | |
3337 | +EXPORT_SYMBOL_GPL(ftrace_set_filter_ip); | |
3338 | + | |
3339 | +static int | |
3340 | +ftrace_set_regex(struct ftrace_ops *ops, unsigned char *buf, int len, | |
3341 | + int reset, int enable) | |
3342 | +{ | |
3343 | + return ftrace_set_hash(ops, buf, len, 0, 0, reset, enable); | |
3289 | 3344 | } |
3290 | 3345 | |
3291 | 3346 | /** |