aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorDmitry Safonov <0x7f454c46@gmail.com>2015-09-29 12:46:15 -0400
committerSteven Rostedt <rostedt@goodmis.org>2015-10-20 20:02:03 -0400
commit0b507e1ed1b7364def464cfb348ea7c9e87e6e18 (patch)
tree0cad422579c4050ce223256fb45aafe30032d723 /kernel
parent3ba009297149fa45956c33ab5de7c5f4da1f28b8 (diff)
ftrace: add module globbing
Extend module command for function filter selection with globbing. It uses the same globbing as function filter. sh# echo '*alloc*:mod:*' > set_ftrace_filter Will trace any function with the letters 'alloc' in the name in any module but not in kernel. sh# echo '!*alloc*:mod:ipv6' >> set_ftrace_filter Will prevent from tracing functions with 'alloc' in the name from module ipv6 (do not forget to append to set_ftrace_filter file). sh# echo '*alloc*:mod:!ipv6' > set_ftrace_filter Will trace functions with 'alloc' in the name from kernel and any module except ipv6. sh# echo '*alloc*:mod:!*' > set_ftrace_filter Will trace any function with the letters 'alloc' in the name only from kernel, but not from any module. sh# echo '*:mod:!*' > set_ftrace_filter or sh# echo ':mod:!' > set_ftrace_filter Will trace every function in the kernel, but will not trace functions from any module. sh# echo '*:mod:*' > set_ftrace_filter or sh# echo ':mod:' > set_ftrace_filter As the opposite will trace all functions from all modules, but not from kernel. sh# echo '*:mod:*snd*' > set_ftrace_filter Will trace your sound drivers only (if any). Link: http://lkml.kernel.org/r/1443545176-3215-4-git-send-email-0x7f454c46@gmail.com Signed-off-by: Dmitry Safonov <0x7f454c46@gmail.com> [ Made format changes ] Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/trace/ftrace.c51
1 files changed, 36 insertions, 15 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 450a5f5676ae..ea2725053771 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -3485,19 +3485,37 @@ enter_record(struct ftrace_hash *hash, struct dyn_ftrace *rec, int clear_filter)
3485} 3485}
3486 3486
3487static int 3487static int
3488ftrace_match_record(struct dyn_ftrace *rec, 3488ftrace_match_record(struct dyn_ftrace *rec, struct ftrace_glob *func_g,
3489 char *mod, struct ftrace_glob *func_g) 3489 struct ftrace_glob *mod_g, int exclude_mod)
3490{ 3490{
3491 char str[KSYM_SYMBOL_LEN]; 3491 char str[KSYM_SYMBOL_LEN];
3492 char *modname; 3492 char *modname;
3493 3493
3494 kallsyms_lookup(rec->ip, NULL, NULL, &modname, str); 3494 kallsyms_lookup(rec->ip, NULL, NULL, &modname, str);
3495 3495
3496 if (mod) { 3496 if (mod_g) {
3497 /* module lookup requires matching the module */ 3497 int mod_matches = (modname) ? ftrace_match(modname, mod_g) : 0;
3498 if (!modname || strcmp(modname, mod)) 3498
3499 /* blank module name to match all modules */
3500 if (!mod_g->len) {
3501 /* blank module globbing: modname xor exclude_mod */
3502 if ((!exclude_mod) != (!modname))
3503 goto func_match;
3504 return 0;
3505 }
3506
3507 /* not matching the module */
3508 if (!modname || !mod_matches) {
3509 if (exclude_mod)
3510 goto func_match;
3511 else
3512 return 0;
3513 }
3514
3515 if (mod_matches && exclude_mod)
3499 return 0; 3516 return 0;
3500 3517
3518func_match:
3501 /* blank search means to match all funcs in the mod */ 3519 /* blank search means to match all funcs in the mod */
3502 if (!func_g->len) 3520 if (!func_g->len)
3503 return 1; 3521 return 1;
@@ -3512,23 +3530,32 @@ match_records(struct ftrace_hash *hash, char *func, int len, char *mod)
3512 struct ftrace_page *pg; 3530 struct ftrace_page *pg;
3513 struct dyn_ftrace *rec; 3531 struct dyn_ftrace *rec;
3514 struct ftrace_glob func_g = { .type = MATCH_FULL }; 3532 struct ftrace_glob func_g = { .type = MATCH_FULL };
3533 struct ftrace_glob mod_g = { .type = MATCH_FULL };
3534 struct ftrace_glob *mod_match = (mod) ? &mod_g : NULL;
3535 int exclude_mod = 0;
3515 int found = 0; 3536 int found = 0;
3516 int ret; 3537 int ret;
3517 int clear_filter; 3538 int clear_filter;
3518 3539
3519 if (len) { 3540 if (func) {
3520 func_g.type = filter_parse_regex(func, len, &func_g.search, 3541 func_g.type = filter_parse_regex(func, len, &func_g.search,
3521 &clear_filter); 3542 &clear_filter);
3522 func_g.len = strlen(func_g.search); 3543 func_g.len = strlen(func_g.search);
3523 } 3544 }
3524 3545
3546 if (mod) {
3547 mod_g.type = filter_parse_regex(mod, strlen(mod),
3548 &mod_g.search, &exclude_mod);
3549 mod_g.len = strlen(mod_g.search);
3550 }
3551
3525 mutex_lock(&ftrace_lock); 3552 mutex_lock(&ftrace_lock);
3526 3553
3527 if (unlikely(ftrace_disabled)) 3554 if (unlikely(ftrace_disabled))
3528 goto out_unlock; 3555 goto out_unlock;
3529 3556
3530 do_for_each_ftrace_rec(pg, rec) { 3557 do_for_each_ftrace_rec(pg, rec) {
3531 if (ftrace_match_record(rec, mod, &func_g)) { 3558 if (ftrace_match_record(rec, &func_g, mod_match, exclude_mod)) {
3532 ret = enter_record(hash, rec, clear_filter); 3559 ret = enter_record(hash, rec, clear_filter);
3533 if (ret < 0) { 3560 if (ret < 0) {
3534 found = ret; 3561 found = ret;
@@ -3568,17 +3595,11 @@ ftrace_mod_callback(struct ftrace_hash *hash,
3568 * you can tell which command was used by the cmd 3595 * you can tell which command was used by the cmd
3569 * parameter. 3596 * parameter.
3570 */ 3597 */
3571
3572 /* we must have a module name */
3573 if (!module || !strlen(module))
3574 return -EINVAL;
3575
3576 ret = match_records(hash, func, strlen(func), module); 3598 ret = match_records(hash, func, strlen(func), module);
3577 if (!ret) 3599 if (!ret)
3578 return -EINVAL; 3600 return -EINVAL;
3579 if (ret < 0) 3601 if (ret < 0)
3580 return ret; 3602 return ret;
3581
3582 return 0; 3603 return 0;
3583} 3604}
3584 3605
@@ -3729,7 +3750,7 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
3729 3750
3730 do_for_each_ftrace_rec(pg, rec) { 3751 do_for_each_ftrace_rec(pg, rec) {
3731 3752
3732 if (!ftrace_match_record(rec, NULL, &func_g)) 3753 if (!ftrace_match_record(rec, &func_g, NULL, 0))
3733 continue; 3754 continue;
3734 3755
3735 entry = kmalloc(sizeof(*entry), GFP_KERNEL); 3756 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
@@ -4621,7 +4642,7 @@ ftrace_set_func(unsigned long *array, int *idx, int size, char *buffer)
4621 4642
4622 do_for_each_ftrace_rec(pg, rec) { 4643 do_for_each_ftrace_rec(pg, rec) {
4623 4644
4624 if (ftrace_match_record(rec, NULL, &func_g)) { 4645 if (ftrace_match_record(rec, &func_g, NULL, 0)) {
4625 /* if it is in the array */ 4646 /* if it is in the array */
4626 exists = false; 4647 exists = false;
4627 for (i = 0; i < *idx; i++) { 4648 for (i = 0; i < *idx; i++) {