Commit 647664eaf4033501739ac1f42dd52ce8c9266ccc

Authored by Masami Hiramatsu
Committed by Steven Rostedt
1 parent ad97772ad8

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 /**