* [PATCH 1/5] ftrace: remove redundant strsep in mod_callback
@ 2015-09-29 16:46 Dmitry Safonov
2015-09-29 16:46 ` [PATCH 2/5] ftrace: clarify code for mod command Dmitry Safonov
` (5 more replies)
0 siblings, 6 replies; 11+ messages in thread
From: Dmitry Safonov @ 2015-09-29 16:46 UTC (permalink / raw)
To: rostedt; +Cc: mingo, corbet, linux-doc, linux-kernel, Dmitry Safonov
By now there isn't any subcommand for mod.
Before:
sh$ echo '*:mod:ipv6:a' > set_ftrace_filter
sh$ echo '*:mod:ipv6' > set_ftrace_filter
had the same results, but now first will result in:
sh$ echo '*:mod:ipv6:a' > set_ftrace_filter
-bash: echo: write error: Invalid argument
Also, I clarified ftrace_mod_callback code a little.
Signed-off-by: Dmitry Safonov <0x7f454c46@gmail.com>
---
kernel/trace/ftrace.c | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index b0623ac..f87401b 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -3564,8 +3564,7 @@ static int
ftrace_mod_callback(struct ftrace_hash *hash,
char *func, char *cmd, char *param, int enable)
{
- char *mod;
- int ret = -EINVAL;
+ int ret;
/*
* cmd == 'mod' because we only registered this func
@@ -3576,16 +3575,12 @@ ftrace_mod_callback(struct ftrace_hash *hash,
*/
/* we must have a module name */
- if (!param)
- return ret;
-
- mod = strsep(¶m, ":");
- if (!strlen(mod))
- return ret;
+ if (!param || !strlen(param))
+ return -EINVAL;
- ret = ftrace_match_module_records(hash, func, mod);
- if (!ret)
- ret = -EINVAL;
+ ret = ftrace_match_module_records(hash, func, param);
+ if (ret == 0)
+ return -EINVAL;
if (ret < 0)
return ret;
--
2.5.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 2/5] ftrace: clarify code for mod command
2015-09-29 16:46 [PATCH 1/5] ftrace: remove redundant strsep in mod_callback Dmitry Safonov
@ 2015-09-29 16:46 ` Dmitry Safonov
2015-09-29 16:46 ` [PATCH 3/5] ftrace: introduce ftrace_glob structure Dmitry Safonov
` (4 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Dmitry Safonov @ 2015-09-29 16:46 UTC (permalink / raw)
To: rostedt; +Cc: mingo, corbet, linux-doc, linux-kernel, Dmitry Safonov
"Not" is too abstract variable name - changed to clear_filter.
Removed ftrace_match_module_records function: comparison with !* or *
not does the general code in filter_parse_regex() as it works without
mod command for
sh# echo '!*' > /sys/kernel/debug/tracing/set_ftrace_filter
Signed-off-by: Dmitry Safonov <0x7f454c46@gmail.com>
---
kernel/trace/ftrace.c | 37 ++++++++++---------------------------
1 file changed, 10 insertions(+), 27 deletions(-)
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index f87401b..a56f028 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -3449,13 +3449,13 @@ static int ftrace_match(char *str, char *regex, int len, int type)
}
static int
-enter_record(struct ftrace_hash *hash, struct dyn_ftrace *rec, int not)
+enter_record(struct ftrace_hash *hash, struct dyn_ftrace *rec, int clear_filter)
{
struct ftrace_func_entry *entry;
int ret = 0;
entry = ftrace_lookup_ip(hash, rec->ip);
- if (not) {
+ if (clear_filter) {
/* Do nothing if it doesn't exist */
if (!entry)
return 0;
@@ -3494,8 +3494,7 @@ ftrace_match_record(struct dyn_ftrace *rec, char *mod,
}
static int
-match_records(struct ftrace_hash *hash, char *buff,
- int len, char *mod, int not)
+match_records(struct ftrace_hash *hash, char *buff, int len, char *mod)
{
unsigned search_len = 0;
struct ftrace_page *pg;
@@ -3504,9 +3503,10 @@ match_records(struct ftrace_hash *hash, char *buff,
char *search = buff;
int found = 0;
int ret;
+ int clear_filter;
if (len) {
- type = filter_parse_regex(buff, len, &search, ¬);
+ type = filter_parse_regex(buff, len, &search, &clear_filter);
search_len = strlen(search);
}
@@ -3517,7 +3517,7 @@ match_records(struct ftrace_hash *hash, char *buff,
do_for_each_ftrace_rec(pg, rec) {
if (ftrace_match_record(rec, mod, search, search_len, type)) {
- ret = enter_record(hash, rec, not);
+ ret = enter_record(hash, rec, clear_filter);
if (ret < 0) {
found = ret;
goto out_unlock;
@@ -3534,26 +3534,9 @@ match_records(struct ftrace_hash *hash, char *buff,
static int
ftrace_match_records(struct ftrace_hash *hash, char *buff, int len)
{
- return match_records(hash, buff, len, NULL, 0);
+ return match_records(hash, buff, len, NULL);
}
-static int
-ftrace_match_module_records(struct ftrace_hash *hash, char *buff, char *mod)
-{
- int not = 0;
-
- /* blank or '*' mean the same */
- if (strcmp(buff, "*") == 0)
- buff[0] = 0;
-
- /* handle the case of 'dont filter this module' */
- if (strcmp(buff, "!") == 0 || strcmp(buff, "!*") == 0) {
- buff[0] = 0;
- not = 1;
- }
-
- return match_records(hash, buff, strlen(buff), mod, not);
-}
/*
* We register the module command as a template to show others how
@@ -3562,7 +3545,7 @@ ftrace_match_module_records(struct ftrace_hash *hash, char *buff, char *mod)
static int
ftrace_mod_callback(struct ftrace_hash *hash,
- char *func, char *cmd, char *param, int enable)
+ char *func, char *cmd, char *module, int enable)
{
int ret;
@@ -3575,10 +3558,10 @@ ftrace_mod_callback(struct ftrace_hash *hash,
*/
/* we must have a module name */
- if (!param || !strlen(param))
+ if (!module || !strlen(module))
return -EINVAL;
- ret = ftrace_match_module_records(hash, func, param);
+ ret = match_records(hash, func, strlen(func), module);
if (ret == 0)
return -EINVAL;
if (ret < 0)
--
2.5.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 3/5] ftrace: introduce ftrace_glob structure
2015-09-29 16:46 [PATCH 1/5] ftrace: remove redundant strsep in mod_callback Dmitry Safonov
2015-09-29 16:46 ` [PATCH 2/5] ftrace: clarify code for mod command Dmitry Safonov
@ 2015-09-29 16:46 ` Dmitry Safonov
2015-10-16 15:05 ` Steven Rostedt
2015-09-29 16:46 ` [PATCH 4/5] ftrace: add module globbing Dmitry Safonov
` (3 subsequent siblings)
5 siblings, 1 reply; 11+ messages in thread
From: Dmitry Safonov @ 2015-09-29 16:46 UTC (permalink / raw)
To: rostedt; +Cc: mingo, corbet, linux-doc, linux-kernel, Dmitry Safonov
ftrace_match parameters are very related and I reduce the number of local
variables & parameters with it.
This is also preparation for module globbing as it would introduce more
realated variables & parameters.
Signed-off-by: Dmitry Safonov <0x7f454c46@gmail.com>
---
kernel/trace/ftrace.c | 84 ++++++++++++++++++++++++++++-----------------------
1 file changed, 46 insertions(+), 38 deletions(-)
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index a56f028..6ffc1a2 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -3420,27 +3420,35 @@ ftrace_notrace_open(struct inode *inode, struct file *file)
inode, file);
}
-static int ftrace_match(char *str, char *regex, int len, int type)
+/* Type for quick search ftrace basic regexes (globs) from filter_parse_regex */
+struct ftrace_glob {
+ char *search;
+ unsigned len;
+ int type;
+};
+
+static int ftrace_match(char *str, struct ftrace_glob *g)
{
int matched = 0;
int slen;
- switch (type) {
+ switch (g->type) {
case MATCH_FULL:
- if (strcmp(str, regex) == 0)
+ if (strcmp(str, g->search) == 0)
matched = 1;
break;
case MATCH_FRONT_ONLY:
- if (strncmp(str, regex, len) == 0)
+ if (strncmp(str, g->search, g->len) == 0)
matched = 1;
break;
case MATCH_MIDDLE_ONLY:
- if (strstr(str, regex))
+ if (strstr(str, g->search))
matched = 1;
break;
case MATCH_END_ONLY:
slen = strlen(str);
- if (slen >= len && memcmp(str + slen - len, regex, len) == 0)
+ if (slen >= g->len && memcmp(str + slen - g->len,
+ g->search, g->len) == 0)
matched = 1;
break;
}
@@ -3472,8 +3480,8 @@ enter_record(struct ftrace_hash *hash, struct dyn_ftrace *rec, int clear_filter)
}
static int
-ftrace_match_record(struct dyn_ftrace *rec, char *mod,
- char *regex, int len, int type)
+ftrace_match_record(struct dyn_ftrace *rec,
+ char *mod, struct ftrace_glob *func_g)
{
char str[KSYM_SYMBOL_LEN];
char *modname;
@@ -3486,28 +3494,27 @@ ftrace_match_record(struct dyn_ftrace *rec, char *mod,
return 0;
/* blank search means to match all funcs in the mod */
- if (!len)
+ if (!func_g->len)
return 1;
}
- return ftrace_match(str, regex, len, type);
+ return ftrace_match(str, func_g);
}
static int
-match_records(struct ftrace_hash *hash, char *buff, int len, char *mod)
+match_records(struct ftrace_hash *hash, char *func, int len, char *mod)
{
- unsigned search_len = 0;
struct ftrace_page *pg;
struct dyn_ftrace *rec;
- int type = MATCH_FULL;
- char *search = buff;
+ struct ftrace_glob func_g = { .type = MATCH_FULL };
int found = 0;
int ret;
int clear_filter;
if (len) {
- type = filter_parse_regex(buff, len, &search, &clear_filter);
- search_len = strlen(search);
+ func_g.type = filter_parse_regex(func, len,
+ &func_g.search, &clear_filter);
+ func_g.len = strlen(func_g.search);
}
mutex_lock(&ftrace_lock);
@@ -3516,7 +3523,7 @@ match_records(struct ftrace_hash *hash, char *buff, int len, char *mod)
goto out_unlock;
do_for_each_ftrace_rec(pg, rec) {
- if (ftrace_match_record(rec, mod, search, search_len, type)) {
+ if (ftrace_match_record(rec, mod, &func_g)) {
ret = enter_record(hash, rec, clear_filter);
if (ret < 0) {
found = ret;
@@ -3682,14 +3689,15 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
struct ftrace_hash *hash;
struct ftrace_page *pg;
struct dyn_ftrace *rec;
- int type, len, not;
+ int not;
unsigned long key;
int count = 0;
- char *search;
int ret;
+ struct ftrace_glob func_g;
- type = filter_parse_regex(glob, strlen(glob), &search, ¬);
- len = strlen(search);
+ func_g.type = filter_parse_regex(glob, strlen(glob),
+ &func_g.search, ¬);
+ func_g.len = strlen(func_g.search);
/* we do not support '!' for function probes */
if (WARN_ON(not))
@@ -3716,7 +3724,7 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
do_for_each_ftrace_rec(pg, rec) {
- if (!ftrace_match_record(rec, NULL, search, len, type))
+ if (!ftrace_match_record(rec, NULL, &func_g))
continue;
entry = kmalloc(sizeof(*entry), GFP_KERNEL);
@@ -3795,18 +3803,18 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
struct ftrace_hash *hash;
struct hlist_node *tmp;
char str[KSYM_SYMBOL_LEN];
- int type = MATCH_FULL;
- int i, len = 0;
- char *search;
- int ret;
+ int i, ret;
+ struct ftrace_glob func_g;
if (glob && (strcmp(glob, "*") == 0 || !strlen(glob)))
- glob = NULL;
+ func_g.search = NULL;
else if (glob) {
int not;
- type = filter_parse_regex(glob, strlen(glob), &search, ¬);
- len = strlen(search);
+ func_g.type = filter_parse_regex(glob, strlen(glob),
+ &func_g.search, ¬);
+ func_g.len = strlen(func_g.search);
+ func_g.search = glob;
/* we do not support '!' for function probes */
if (WARN_ON(not))
@@ -3835,10 +3843,10 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
continue;
/* do this last, since it is the most expensive */
- if (glob) {
+ if (func_g.search) {
kallsyms_lookup(entry->ip, NULL, NULL,
NULL, str);
- if (!ftrace_match(str, glob, len, type))
+ if (!ftrace_match(str, &func_g))
continue;
}
@@ -3867,7 +3875,7 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
ftrace_free_entry(entry);
}
mutex_unlock(&ftrace_lock);
-
+
out_unlock:
mutex_unlock(&trace_probe_ops.func_hash->regex_lock);
free_ftrace_hash(hash);
@@ -4585,19 +4593,19 @@ ftrace_set_func(unsigned long *array, int *idx, int size, char *buffer)
{
struct dyn_ftrace *rec;
struct ftrace_page *pg;
- int search_len;
int fail = 1;
- int type, not;
- char *search;
+ int not;
bool exists;
int i;
+ struct ftrace_glob func_g;
/* decode regex */
- type = filter_parse_regex(buffer, strlen(buffer), &search, ¬);
+ func_g.type = filter_parse_regex(buffer, strlen(buffer),
+ &func_g.search, ¬);
if (!not && *idx >= size)
return -EBUSY;
- search_len = strlen(search);
+ func_g.len = strlen(func_g.search);
mutex_lock(&ftrace_lock);
@@ -4608,7 +4616,7 @@ ftrace_set_func(unsigned long *array, int *idx, int size, char *buffer)
do_for_each_ftrace_rec(pg, rec) {
- if (ftrace_match_record(rec, NULL, search, search_len, type)) {
+ if (ftrace_match_record(rec, NULL, &func_g)) {
/* if it is in the array */
exists = false;
for (i = 0; i < *idx; i++) {
--
2.5.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 4/5] ftrace: add module globbing
2015-09-29 16:46 [PATCH 1/5] ftrace: remove redundant strsep in mod_callback Dmitry Safonov
2015-09-29 16:46 ` [PATCH 2/5] ftrace: clarify code for mod command Dmitry Safonov
2015-09-29 16:46 ` [PATCH 3/5] ftrace: introduce ftrace_glob structure Dmitry Safonov
@ 2015-09-29 16:46 ` Dmitry Safonov
2015-09-29 16:46 ` [PATCH 5/5] Documentation: ftrace: module globbing usage Dmitry Safonov
` (2 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Dmitry Safonov @ 2015-09-29 16:46 UTC (permalink / raw)
To: rostedt; +Cc: mingo, corbet, linux-doc, linux-kernel, Dmitry Safonov
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).
Signed-off-by: Dmitry Safonov <0x7f454c46@gmail.com>
---
kernel/trace/ftrace.c | 54 +++++++++++++++++++++++++++++++++++----------------
1 file changed, 37 insertions(+), 17 deletions(-)
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 6ffc1a2..a2a4e57 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -3480,19 +3480,37 @@ enter_record(struct ftrace_hash *hash, struct dyn_ftrace *rec, int clear_filter)
}
static int
-ftrace_match_record(struct dyn_ftrace *rec,
- char *mod, struct ftrace_glob *func_g)
+ftrace_match_record(struct dyn_ftrace *rec, struct ftrace_glob *func_g,
+ struct ftrace_glob *mod_g, int exclude_mod)
{
char str[KSYM_SYMBOL_LEN];
char *modname;
kallsyms_lookup(rec->ip, NULL, NULL, &modname, str);
- if (mod) {
- /* module lookup requires matching the module */
- if (!modname || strcmp(modname, mod))
+ if (mod_g) {
+ int mod_matches = (modname) ? ftrace_match(modname, mod_g) : 0;
+
+ /* blank module name to match all modules */
+ if (!mod_g->len) {
+ /* blank module globbing: modname xor exclude_mod */
+ if ((!exclude_mod) != (!modname))
+ goto func_match;
+ return 0;
+ }
+
+ /* not matching the module */
+ if (!modname || !mod_matches) {
+ if (exclude_mod)
+ goto func_match;
+ else
+ return 0;
+ }
+
+ if (mod_matches && exclude_mod)
return 0;
+func_match:
/* blank search means to match all funcs in the mod */
if (!func_g->len)
return 1;
@@ -3507,23 +3525,31 @@ match_records(struct ftrace_hash *hash, char *func, int len, char *mod)
struct ftrace_page *pg;
struct dyn_ftrace *rec;
struct ftrace_glob func_g = { .type = MATCH_FULL };
+ struct ftrace_glob mod_g = { .type = MATCH_FULL };
+ struct ftrace_glob *mod_match = (mod) ? &mod_g : NULL;
int found = 0;
int ret;
- int clear_filter;
+ int clear_filter, exclude_mod = 0;
- if (len) {
+ if (func) {
func_g.type = filter_parse_regex(func, len,
&func_g.search, &clear_filter);
func_g.len = strlen(func_g.search);
}
+ if (mod) {
+ mod_g.type = filter_parse_regex(mod, strlen(mod),
+ &mod_g.search, &exclude_mod);
+ mod_g.len = strlen(mod_g.search);
+ }
+
mutex_lock(&ftrace_lock);
if (unlikely(ftrace_disabled))
goto out_unlock;
do_for_each_ftrace_rec(pg, rec) {
- if (ftrace_match_record(rec, mod, &func_g)) {
+ if (ftrace_match_record(rec, &func_g, mod_match, exclude_mod)) {
ret = enter_record(hash, rec, clear_filter);
if (ret < 0) {
found = ret;
@@ -3554,8 +3580,6 @@ static int
ftrace_mod_callback(struct ftrace_hash *hash,
char *func, char *cmd, char *module, int enable)
{
- int ret;
-
/*
* cmd == 'mod' because we only registered this func
* for the 'mod' ftrace_func_command.
@@ -3564,16 +3588,12 @@ ftrace_mod_callback(struct ftrace_hash *hash,
* parameter.
*/
- /* we must have a module name */
- if (!module || !strlen(module))
- return -EINVAL;
+ int ret = match_records(hash, func, strlen(func), module);
- ret = match_records(hash, func, strlen(func), module);
if (ret == 0)
return -EINVAL;
if (ret < 0)
return ret;
-
return 0;
}
@@ -3724,7 +3744,7 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
do_for_each_ftrace_rec(pg, rec) {
- if (!ftrace_match_record(rec, NULL, &func_g))
+ if (!ftrace_match_record(rec, &func_g, NULL, 0))
continue;
entry = kmalloc(sizeof(*entry), GFP_KERNEL);
@@ -4616,7 +4636,7 @@ ftrace_set_func(unsigned long *array, int *idx, int size, char *buffer)
do_for_each_ftrace_rec(pg, rec) {
- if (ftrace_match_record(rec, NULL, &func_g)) {
+ if (ftrace_match_record(rec, &func_g, NULL, 0)) {
/* if it is in the array */
exists = false;
for (i = 0; i < *idx; i++) {
--
2.5.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 5/5] Documentation: ftrace: module globbing usage
2015-09-29 16:46 [PATCH 1/5] ftrace: remove redundant strsep in mod_callback Dmitry Safonov
` (2 preceding siblings ...)
2015-09-29 16:46 ` [PATCH 4/5] ftrace: add module globbing Dmitry Safonov
@ 2015-09-29 16:46 ` Dmitry Safonov
2015-09-29 19:11 ` [PATCH 1/5] ftrace: remove redundant strsep in mod_callback Steven Rostedt
2015-10-14 0:48 ` Steven Rostedt
5 siblings, 0 replies; 11+ messages in thread
From: Dmitry Safonov @ 2015-09-29 16:46 UTC (permalink / raw)
To: rostedt; +Cc: mingo, corbet, linux-doc, linux-kernel, Dmitry Safonov
Signed-off-by: Dmitry Safonov <0x7f454c46@gmail.com>
---
Documentation/trace/ftrace.txt | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/Documentation/trace/ftrace.txt b/Documentation/trace/ftrace.txt
index ef621d3..db18362 100644
--- a/Documentation/trace/ftrace.txt
+++ b/Documentation/trace/ftrace.txt
@@ -2437,6 +2437,23 @@ The following commands are supported:
echo '!writeback*:mod:ext3' >> set_ftrace_filter
+ Mod command supports module globbing. Disable tracing for all
+ functions except a specific module:
+
+ echo '!*:mod:!ext3' >> set_ftrace_filter
+
+ Disable tracing for all modules, but still trace kernel:
+
+ echo '!*:mod:*' >> set_ftrace_filter
+
+ Enable filter only for kernel:
+
+ echo '*write*:mod:!*' >> set_ftrace_filter
+
+ Enable filter for module globbing:
+
+ echo '*write*:mod:*snd*' >> set_ftrace_filter
+
- traceon/traceoff
These commands turn tracing on and off when the specified
functions are hit. The parameter determines how many times the
--
2.5.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 1/5] ftrace: remove redundant strsep in mod_callback
2015-09-29 16:46 [PATCH 1/5] ftrace: remove redundant strsep in mod_callback Dmitry Safonov
` (3 preceding siblings ...)
2015-09-29 16:46 ` [PATCH 5/5] Documentation: ftrace: module globbing usage Dmitry Safonov
@ 2015-09-29 19:11 ` Steven Rostedt
2015-10-05 15:16 ` Дмитрий Сафонов
2015-10-14 0:48 ` Steven Rostedt
5 siblings, 1 reply; 11+ messages in thread
From: Steven Rostedt @ 2015-09-29 19:11 UTC (permalink / raw)
To: Dmitry Safonov; +Cc: mingo, corbet, linux-doc, linux-kernel
On Tue, 29 Sep 2015 19:46:12 +0300
Dmitry Safonov <0x7f454c46@gmail.com> wrote:
> By now there isn't any subcommand for mod.
>
> Before:
> sh$ echo '*:mod:ipv6:a' > set_ftrace_filter
> sh$ echo '*:mod:ipv6' > set_ftrace_filter
> had the same results, but now first will result in:
> sh$ echo '*:mod:ipv6:a' > set_ftrace_filter
> -bash: echo: write error: Invalid argument
>
> Also, I clarified ftrace_mod_callback code a little.
Thanks for the patches. I don't have time to look at them at the moment
as I'm trying to finish up some stuff before I leave for LinuxCon EU.
If you don't hear from me by Monday, feel free to ping me again. I'll
be in Dublin (for LinuxCon), but I should be able to take a look at the
patches while I'm there. What do you think keynotes are for ;-)
-- Steve
>
> Signed-off-by: Dmitry Safonov <0x7f454c46@gmail.com>
> ---
> kernel/trace/ftrace.c | 17 ++++++-----------
> 1 file changed, 6 insertions(+), 11 deletions(-)
>
> diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
> index b0623ac..f87401b 100644
> --- a/kernel/trace/ftrace.c
> +++ b/kernel/trace/ftrace.c
> @@ -3564,8 +3564,7 @@ static int
> ftrace_mod_callback(struct ftrace_hash *hash,
> char *func, char *cmd, char *param, int enable)
> {
> - char *mod;
> - int ret = -EINVAL;
> + int ret;
>
> /*
> * cmd == 'mod' because we only registered this func
> @@ -3576,16 +3575,12 @@ ftrace_mod_callback(struct ftrace_hash *hash,
> */
>
> /* we must have a module name */
> - if (!param)
> - return ret;
> -
> - mod = strsep(¶m, ":");
> - if (!strlen(mod))
> - return ret;
> + if (!param || !strlen(param))
> + return -EINVAL;
>
> - ret = ftrace_match_module_records(hash, func, mod);
> - if (!ret)
> - ret = -EINVAL;
> + ret = ftrace_match_module_records(hash, func, param);
> + if (ret == 0)
> + return -EINVAL;
> if (ret < 0)
> return ret;
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/5] ftrace: remove redundant strsep in mod_callback
2015-09-29 19:11 ` [PATCH 1/5] ftrace: remove redundant strsep in mod_callback Steven Rostedt
@ 2015-10-05 15:16 ` Дмитрий Сафонов
0 siblings, 0 replies; 11+ messages in thread
From: Дмитрий Сафонов @ 2015-10-05 15:16 UTC (permalink / raw)
To: Steven Rostedt; +Cc: mingo, Jonathan Corbet, linux-doc, linux-kernel
Hello again, Steven.
I'm pinging :)
2015-09-29 22:11 GMT+03:00 Steven Rostedt <rostedt@goodmis.org>:
> On Tue, 29 Sep 2015 19:46:12 +0300
> Dmitry Safonov <0x7f454c46@gmail.com> wrote:
>
>> By now there isn't any subcommand for mod.
>>
>> Before:
>> sh$ echo '*:mod:ipv6:a' > set_ftrace_filter
>> sh$ echo '*:mod:ipv6' > set_ftrace_filter
>> had the same results, but now first will result in:
>> sh$ echo '*:mod:ipv6:a' > set_ftrace_filter
>> -bash: echo: write error: Invalid argument
>>
>> Also, I clarified ftrace_mod_callback code a little.
>
> Thanks for the patches. I don't have time to look at them at the moment
> as I'm trying to finish up some stuff before I leave for LinuxCon EU.
>
> If you don't hear from me by Monday, feel free to ping me again. I'll
> be in Dublin (for LinuxCon), but I should be able to take a look at the
> patches while I'm there. What do you think keynotes are for ;-)
>
> -- Steve
>
>>
>> Signed-off-by: Dmitry Safonov <0x7f454c46@gmail.com>
>> ---
>> kernel/trace/ftrace.c | 17 ++++++-----------
>> 1 file changed, 6 insertions(+), 11 deletions(-)
>>
>> diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
>> index b0623ac..f87401b 100644
>> --- a/kernel/trace/ftrace.c
>> +++ b/kernel/trace/ftrace.c
>> @@ -3564,8 +3564,7 @@ static int
>> ftrace_mod_callback(struct ftrace_hash *hash,
>> char *func, char *cmd, char *param, int enable)
>> {
>> - char *mod;
>> - int ret = -EINVAL;
>> + int ret;
>>
>> /*
>> * cmd == 'mod' because we only registered this func
>> @@ -3576,16 +3575,12 @@ ftrace_mod_callback(struct ftrace_hash *hash,
>> */
>>
>> /* we must have a module name */
>> - if (!param)
>> - return ret;
>> -
>> - mod = strsep(¶m, ":");
>> - if (!strlen(mod))
>> - return ret;
>> + if (!param || !strlen(param))
>> + return -EINVAL;
>>
>> - ret = ftrace_match_module_records(hash, func, mod);
>> - if (!ret)
>> - ret = -EINVAL;
>> + ret = ftrace_match_module_records(hash, func, param);
>> + if (ret == 0)
>> + return -EINVAL;
>> if (ret < 0)
>> return ret;
>>
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/5] ftrace: remove redundant strsep in mod_callback
2015-09-29 16:46 [PATCH 1/5] ftrace: remove redundant strsep in mod_callback Dmitry Safonov
` (4 preceding siblings ...)
2015-09-29 19:11 ` [PATCH 1/5] ftrace: remove redundant strsep in mod_callback Steven Rostedt
@ 2015-10-14 0:48 ` Steven Rostedt
2015-10-16 8:52 ` Dmitry Safonov
5 siblings, 1 reply; 11+ messages in thread
From: Steven Rostedt @ 2015-10-14 0:48 UTC (permalink / raw)
To: Dmitry Safonov; +Cc: mingo, corbet, linux-doc, linux-kernel
On Tue, 29 Sep 2015 19:46:12 +0300
Dmitry Safonov <0x7f454c46@gmail.com> wrote:
> - ret = ftrace_match_module_records(hash, func, mod);
> - if (!ret)
> - ret = -EINVAL;
> + ret = ftrace_match_module_records(hash, func, param);
> + if (ret == 0)
Small nit, personally, I prefer the if (!ret) version.
For me "== 0" is for counters and strcmp. I may change this to be
consistent with the rest of the code.
-- Steve
> + return -EINVAL;
> if (ret < 0)
> return ret;
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/5] ftrace: remove redundant strsep in mod_callback
2015-10-14 0:48 ` Steven Rostedt
@ 2015-10-16 8:52 ` Dmitry Safonov
0 siblings, 0 replies; 11+ messages in thread
From: Dmitry Safonov @ 2015-10-16 8:52 UTC (permalink / raw)
To: Steven Rostedt; +Cc: mingo, Jonathan Corbet, linux-doc, linux-kernel
2015-10-14 3:48 GMT+03:00 Steven Rostedt <rostedt@goodmis.org>:
>> - ret = ftrace_match_module_records(hash, func, mod);
>> - if (!ret)
>> - ret = -EINVAL;
>> + ret = ftrace_match_module_records(hash, func, param);
>> + if (ret == 0)
>
> Small nit, personally, I prefer the if (!ret) version.
>
> For me "== 0" is for counters and strcmp. I may change this to be
> consistent with the rest of the code.
>
> -- Steve
Ok, I thought "== 0" will be more readable near comparison "< 0",
but anyway, (!ret) is good.
>
>> + return -EINVAL;
>> if (ret < 0)
>> return ret;
>>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 3/5] ftrace: introduce ftrace_glob structure
2015-09-29 16:46 ` [PATCH 3/5] ftrace: introduce ftrace_glob structure Dmitry Safonov
@ 2015-10-16 15:05 ` Steven Rostedt
2015-10-16 22:32 ` Dmitry Safonov
0 siblings, 1 reply; 11+ messages in thread
From: Steven Rostedt @ 2015-10-16 15:05 UTC (permalink / raw)
To: Dmitry Safonov; +Cc: mingo, corbet, linux-doc, linux-kernel
On Tue, 29 Sep 2015 19:46:14 +0300
Dmitry Safonov <0x7f454c46@gmail.com> wrote:
> ftrace_match parameters are very related and I reduce the number of local
> variables & parameters with it.
> This is also preparation for module globbing as it would introduce more
> realated variables & parameters.
>
> Signed-off-by: Dmitry Safonov <0x7f454c46@gmail.com>
> ---
> kernel/trace/ftrace.c | 84 ++++++++++++++++++++++++++++-----------------------
> 1 file changed, 46 insertions(+), 38 deletions(-)
>
> diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
> index a56f028..6ffc1a2 100644
> --- a/kernel/trace/ftrace.c
> +++ b/kernel/trace/ftrace.c
> @@ -3420,27 +3420,35 @@ ftrace_notrace_open(struct inode *inode, struct file *file)
> inode, file);
> }
>
> -static int ftrace_match(char *str, char *regex, int len, int type)
> +/* Type for quick search ftrace basic regexes (globs) from filter_parse_regex */
> +struct ftrace_glob {
> + char *search;
> + unsigned len;
> + int type;
> +};
> +
> +static int ftrace_match(char *str, struct ftrace_glob *g)
> {
> int matched = 0;
> int slen;
>
> - switch (type) {
> + switch (g->type) {
> case MATCH_FULL:
> - if (strcmp(str, regex) == 0)
> + if (strcmp(str, g->search) == 0)
> matched = 1;
> break;
> case MATCH_FRONT_ONLY:
> - if (strncmp(str, regex, len) == 0)
> + if (strncmp(str, g->search, g->len) == 0)
> matched = 1;
> break;
> case MATCH_MIDDLE_ONLY:
> - if (strstr(str, regex))
> + if (strstr(str, g->search))
> matched = 1;
> break;
> case MATCH_END_ONLY:
> slen = strlen(str);
> - if (slen >= len && memcmp(str + slen - len, regex, len) == 0)
> + if (slen >= g->len && memcmp(str + slen - g->len,
> + g->search, g->len) == 0)
I'm going to modify this a little to:
if (slen >= g->len &&
memcmp(str + slen - g->len, g->search, g->len) == 0)
As it's a bit easier to read.
> matched = 1;
> break;
> }
> @@ -3472,8 +3480,8 @@ enter_record(struct ftrace_hash *hash, struct dyn_ftrace *rec, int clear_filter)
> }
>
> static int
> -ftrace_match_record(struct dyn_ftrace *rec, char *mod,
> - char *regex, int len, int type)
> +ftrace_match_record(struct dyn_ftrace *rec,
> + char *mod, struct ftrace_glob *func_g)
> {
> char str[KSYM_SYMBOL_LEN];
> char *modname;
> @@ -3486,28 +3494,27 @@ ftrace_match_record(struct dyn_ftrace *rec, char *mod,
> return 0;
>
> /* blank search means to match all funcs in the mod */
> - if (!len)
> + if (!func_g->len)
> return 1;
> }
>
> - return ftrace_match(str, regex, len, type);
> + return ftrace_match(str, func_g);
> }
>
> static int
> -match_records(struct ftrace_hash *hash, char *buff, int len, char *mod)
> +match_records(struct ftrace_hash *hash, char *func, int len, char *mod)
> {
> - unsigned search_len = 0;
> struct ftrace_page *pg;
> struct dyn_ftrace *rec;
> - int type = MATCH_FULL;
> - char *search = buff;
> + struct ftrace_glob func_g = { .type = MATCH_FULL };
> int found = 0;
> int ret;
> int clear_filter;
>
> if (len) {
> - type = filter_parse_regex(buff, len, &search, &clear_filter);
> - search_len = strlen(search);
> + func_g.type = filter_parse_regex(func, len,
> + &func_g.search, &clear_filter);
I'm reformatting this too.
> + func_g.len = strlen(func_g.search);
> }
>
> mutex_lock(&ftrace_lock);
> @@ -3516,7 +3523,7 @@ match_records(struct ftrace_hash *hash, char *buff, int len, char *mod)
> goto out_unlock;
>
> do_for_each_ftrace_rec(pg, rec) {
> - if (ftrace_match_record(rec, mod, search, search_len, type)) {
> + if (ftrace_match_record(rec, mod, &func_g)) {
> ret = enter_record(hash, rec, clear_filter);
> if (ret < 0) {
> found = ret;
> @@ -3682,14 +3689,15 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
> struct ftrace_hash *hash;
> struct ftrace_page *pg;
> struct dyn_ftrace *rec;
> - int type, len, not;
> + int not;
> unsigned long key;
> int count = 0;
> - char *search;
> int ret;
> + struct ftrace_glob func_g;
I'm moving this up to keep the "upside down x-mas tree" effect.
>
> - type = filter_parse_regex(glob, strlen(glob), &search, ¬);
> - len = strlen(search);
> + func_g.type = filter_parse_regex(glob, strlen(glob),
> + &func_g.search, ¬);
> + func_g.len = strlen(func_g.search);
>
> /* we do not support '!' for function probes */
> if (WARN_ON(not))
> @@ -3716,7 +3724,7 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
>
> do_for_each_ftrace_rec(pg, rec) {
>
> - if (!ftrace_match_record(rec, NULL, search, len, type))
> + if (!ftrace_match_record(rec, NULL, &func_g))
> continue;
>
> entry = kmalloc(sizeof(*entry), GFP_KERNEL);
> @@ -3795,18 +3803,18 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
> struct ftrace_hash *hash;
> struct hlist_node *tmp;
> char str[KSYM_SYMBOL_LEN];
> - int type = MATCH_FULL;
> - int i, len = 0;
> - char *search;
> - int ret;
> + int i, ret;
> + struct ftrace_glob func_g;
Same here.
>
> if (glob && (strcmp(glob, "*") == 0 || !strlen(glob)))
> - glob = NULL;
> + func_g.search = NULL;
> else if (glob) {
> int not;
>
> - type = filter_parse_regex(glob, strlen(glob), &search, ¬);
> - len = strlen(search);
> + func_g.type = filter_parse_regex(glob, strlen(glob),
> + &func_g.search, ¬);
And this I'm formatting a bit differently, making the &func_g.search
equal to "glob".
> + func_g.len = strlen(func_g.search);
> + func_g.search = glob;
>
> /* we do not support '!' for function probes */
> if (WARN_ON(not))
> @@ -3835,10 +3843,10 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
> continue;
>
> /* do this last, since it is the most expensive */
> - if (glob) {
> + if (func_g.search) {
> kallsyms_lookup(entry->ip, NULL, NULL,
> NULL, str);
> - if (!ftrace_match(str, glob, len, type))
> + if (!ftrace_match(str, &func_g))
> continue;
> }
>
> @@ -3867,7 +3875,7 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
> ftrace_free_entry(entry);
> }
> mutex_unlock(&ftrace_lock);
> -
> +
> out_unlock:
> mutex_unlock(&trace_probe_ops.func_hash->regex_lock);
> free_ftrace_hash(hash);
> @@ -4585,19 +4593,19 @@ ftrace_set_func(unsigned long *array, int *idx, int size, char *buffer)
> {
> struct dyn_ftrace *rec;
> struct ftrace_page *pg;
> - int search_len;
> int fail = 1;
> - int type, not;
> - char *search;
> + int not;
> bool exists;
> int i;
> + struct ftrace_glob func_g;
Again, I'm moving that up.
>
> /* decode regex */
> - type = filter_parse_regex(buffer, strlen(buffer), &search, ¬);
> + func_g.type = filter_parse_regex(buffer, strlen(buffer),
> + &func_g.search, ¬);
Format change.
OK, patch looks good, but I'm going to do the formatting changes. I'm
not changing the code itself, except for the few places I moved the
declaration of func_g up to keep the declarations in
upside-down-x-mass-tree format.
Thanks,
-- Steve
> if (!not && *idx >= size)
> return -EBUSY;
>
> - search_len = strlen(search);
> + func_g.len = strlen(func_g.search);
>
> mutex_lock(&ftrace_lock);
>
> @@ -4608,7 +4616,7 @@ ftrace_set_func(unsigned long *array, int *idx, int size, char *buffer)
>
> do_for_each_ftrace_rec(pg, rec) {
>
> - if (ftrace_match_record(rec, NULL, search, search_len, type)) {
> + if (ftrace_match_record(rec, NULL, &func_g)) {
> /* if it is in the array */
> exists = false;
> for (i = 0; i < *idx; i++) {
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 3/5] ftrace: introduce ftrace_glob structure
2015-10-16 15:05 ` Steven Rostedt
@ 2015-10-16 22:32 ` Dmitry Safonov
0 siblings, 0 replies; 11+ messages in thread
From: Dmitry Safonov @ 2015-10-16 22:32 UTC (permalink / raw)
To: Steven Rostedt; +Cc: mingo, Jonathan Corbet, linux-doc, linux-kernel
> Format change.
>
> OK, patch looks good, but I'm going to do the formatting changes. I'm
> not changing the code itself, except for the few places I moved the
> declaration of func_g up to keep the declarations in
> upside-down-x-mass-tree format.
Thank you! Seems better, I think.
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2015-10-16 22:32 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-29 16:46 [PATCH 1/5] ftrace: remove redundant strsep in mod_callback Dmitry Safonov
2015-09-29 16:46 ` [PATCH 2/5] ftrace: clarify code for mod command Dmitry Safonov
2015-09-29 16:46 ` [PATCH 3/5] ftrace: introduce ftrace_glob structure Dmitry Safonov
2015-10-16 15:05 ` Steven Rostedt
2015-10-16 22:32 ` Dmitry Safonov
2015-09-29 16:46 ` [PATCH 4/5] ftrace: add module globbing Dmitry Safonov
2015-09-29 16:46 ` [PATCH 5/5] Documentation: ftrace: module globbing usage Dmitry Safonov
2015-09-29 19:11 ` [PATCH 1/5] ftrace: remove redundant strsep in mod_callback Steven Rostedt
2015-10-05 15:16 ` Дмитрий Сафонов
2015-10-14 0:48 ` Steven Rostedt
2015-10-16 8:52 ` Dmitry Safonov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).