* [PATCHv3 0/3] tracing - adding common method for reading/parsing user input
@ 2009-09-11 15:29 jolsa
2009-09-11 15:29 ` [PATCHv3 1/3] [PATCHv3 1/3] tracing - trace parser definition, parsing function jolsa
` (3 more replies)
0 siblings, 4 replies; 10+ messages in thread
From: jolsa @ 2009-09-11 15:29 UTC (permalink / raw)
To: mingo, rostedt; +Cc: linux-kernel
As 3 different places for 4 user input files were using the same way
of reading and parsing user's input, I made one common routine to be
used.
The mentioned files are:
set_graph_function
set_event
set_ftrace_filter
set_ftrace_notrace
wbr,
jirka
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
---
kernel/trace/ftrace.c | 150 +++++++++++-------------------------------
kernel/trace/trace.c | 106 ++++++++++++++++++++++++++++++
kernel/trace/trace.h | 35 ++++++++++
kernel/trace/trace_events.c | 60 ++++-------------
4 files changed, 194 insertions(+), 157 deletions(-)
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCHv3 1/3] [PATCHv3 1/3] tracing - trace parser definition, parsing function 2009-09-11 15:29 [PATCHv3 0/3] tracing - adding common method for reading/parsing user input jolsa @ 2009-09-11 15:29 ` jolsa 2009-09-12 7:54 ` [tip:tracing/core] tracing: create generic trace parser tip-bot for jolsa@redhat.com 2009-09-11 15:29 ` [PATCHv3 2/3] [PATCHv3 2/3] tracing - trace parser support for set_event jolsa ` (2 subsequent siblings) 3 siblings, 1 reply; 10+ messages in thread From: jolsa @ 2009-09-11 15:29 UTC (permalink / raw) To: mingo, rostedt; +Cc: linux-kernel Defined 'trace_parser' structure to carry the properties of the input, through the multiple writes. The 'trace_get_user' reads the user input string separated by spaces (matched by isspace(ch)). For each string found the 'struct trace_parser' is updated, and the function returns. wbr, jirka Signed-off-by: Jiri Olsa <jolsa@redhat.com> --- kernel/trace/trace.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++ kernel/trace/trace.h | 35 ++++++++++++++++ 2 files changed, 141 insertions(+), 0 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 5c75dee..9c57165 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -339,6 +339,112 @@ static struct { int trace_clock_id; +/* + * trace_parser_get_init - gets the buffer for trace parser + */ +int trace_parser_get_init(struct trace_parser *parser, int size) +{ + memset(parser, 0, sizeof(*parser)); + + parser->buffer = kmalloc(size, GFP_KERNEL); + if (!parser->buffer) + return 1; + + parser->size = size; + return 0; +} + +/* + * trace_parser_put - frees the buffer for trace parser + */ +void trace_parser_put(struct trace_parser *parser) +{ + kfree(parser->buffer); +} + +/* + * trace_get_user - reads the user input string separated by space + * (matched by isspace(ch)) + * + * For each string found the 'struct trace_parser' is updated, + * and the function returns. + * + * Returns number of bytes read. + * + * See kernel/trace/trace.h for 'struct trace_parser' details. + */ +int trace_get_user(struct trace_parser *parser, const char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + char ch; + size_t read = 0; + ssize_t ret; + + if (!*ppos) + trace_parser_clear(parser); + + ret = get_user(ch, ubuf++); + if (ret) + goto out; + + read++; + cnt--; + + /* + * The parser is not finished with the last write, + * continue reading the user input without skipping spaces. + */ + if (!parser->cont) { + /* skip white space */ + while (cnt && isspace(ch)) { + ret = get_user(ch, ubuf++); + if (ret) + goto out; + read++; + cnt--; + } + + /* only spaces were written */ + if (isspace(ch)) { + *ppos += read; + ret = read; + goto out; + } + + parser->idx = 0; + } + + /* read the non-space input */ + while (cnt && !isspace(ch)) { + if (parser->idx < parser->size) + parser->buffer[parser->idx++] = ch; + else { + ret = -EINVAL; + goto out; + } + ret = get_user(ch, ubuf++); + if (ret) + goto out; + read++; + cnt--; + } + + /* We either got finished input or we have to wait for another call. */ + if (isspace(ch)) { + parser->buffer[parser->idx] = 0; + parser->cont = false; + } else { + parser->cont = true; + parser->buffer[parser->idx++] = ch; + } + + *ppos += read; + ret = read; + +out: + return ret; +} + ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, size_t cnt) { int len; diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index ea7e0bc..711641c 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -656,6 +656,41 @@ static inline int ftrace_trace_task(struct task_struct *task) #endif /* + * struct trace_parser - servers for reading the user input separated by spaces + * @cont: set if the input is not complete - no final space char was found + * @buffer: holds the parsed user input + * @idx: user input lenght + * @size: buffer size + */ +struct trace_parser { + bool cont; + char *buffer; + unsigned idx; + unsigned size; +}; + +static inline bool trace_parser_loaded(struct trace_parser *parser) +{ + return (parser->idx != 0); +} + +static inline bool trace_parser_cont(struct trace_parser *parser) +{ + return parser->cont; +} + +static inline void trace_parser_clear(struct trace_parser *parser) +{ + parser->cont = false; + parser->idx = 0; +} + +extern int trace_parser_get_init(struct trace_parser *parser, int size); +extern void trace_parser_put(struct trace_parser *parser); +extern int trace_get_user(struct trace_parser *parser, const char __user *ubuf, + size_t cnt, loff_t *ppos); + +/* * trace_iterator_flags is an enumeration that defines bit * positions into trace_flags that controls the output. * -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [tip:tracing/core] tracing: create generic trace parser 2009-09-11 15:29 ` [PATCHv3 1/3] [PATCHv3 1/3] tracing - trace parser definition, parsing function jolsa @ 2009-09-12 7:54 ` tip-bot for jolsa@redhat.com 0 siblings, 0 replies; 10+ messages in thread From: tip-bot for jolsa@redhat.com @ 2009-09-12 7:54 UTC (permalink / raw) To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, rostedt, tglx, jolsa Commit-ID: b63f39ea50330f836e301ddda21c6a93dcf0d6a3 Gitweb: http://git.kernel.org/tip/b63f39ea50330f836e301ddda21c6a93dcf0d6a3 Author: jolsa@redhat.com <jolsa@redhat.com> AuthorDate: Fri, 11 Sep 2009 17:29:27 +0200 Committer: Steven Rostedt <rostedt@goodmis.org> CommitDate: Fri, 11 Sep 2009 14:46:55 -0400 tracing: create generic trace parser Create a "trace_parser" that can parse the user space input for separate words. struct trace_parser is the descriptor. Generic "trace_get_user" function that can be a helper to read multiple words passed in by user space. Signed-off-by: Jiri Olsa <jolsa@redhat.com> LKML-Reference: <1252682969-3366-2-git-send-email-jolsa@redhat.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> --- kernel/trace/trace.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++ kernel/trace/trace.h | 35 ++++++++++++++++ 2 files changed, 141 insertions(+), 0 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 3b91828..45c3f03 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -339,6 +339,112 @@ static struct { int trace_clock_id; +/* + * trace_parser_get_init - gets the buffer for trace parser + */ +int trace_parser_get_init(struct trace_parser *parser, int size) +{ + memset(parser, 0, sizeof(*parser)); + + parser->buffer = kmalloc(size, GFP_KERNEL); + if (!parser->buffer) + return 1; + + parser->size = size; + return 0; +} + +/* + * trace_parser_put - frees the buffer for trace parser + */ +void trace_parser_put(struct trace_parser *parser) +{ + kfree(parser->buffer); +} + +/* + * trace_get_user - reads the user input string separated by space + * (matched by isspace(ch)) + * + * For each string found the 'struct trace_parser' is updated, + * and the function returns. + * + * Returns number of bytes read. + * + * See kernel/trace/trace.h for 'struct trace_parser' details. + */ +int trace_get_user(struct trace_parser *parser, const char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + char ch; + size_t read = 0; + ssize_t ret; + + if (!*ppos) + trace_parser_clear(parser); + + ret = get_user(ch, ubuf++); + if (ret) + goto out; + + read++; + cnt--; + + /* + * The parser is not finished with the last write, + * continue reading the user input without skipping spaces. + */ + if (!parser->cont) { + /* skip white space */ + while (cnt && isspace(ch)) { + ret = get_user(ch, ubuf++); + if (ret) + goto out; + read++; + cnt--; + } + + /* only spaces were written */ + if (isspace(ch)) { + *ppos += read; + ret = read; + goto out; + } + + parser->idx = 0; + } + + /* read the non-space input */ + while (cnt && !isspace(ch)) { + if (parser->idx < parser->size) + parser->buffer[parser->idx++] = ch; + else { + ret = -EINVAL; + goto out; + } + ret = get_user(ch, ubuf++); + if (ret) + goto out; + read++; + cnt--; + } + + /* We either got finished input or we have to wait for another call. */ + if (isspace(ch)) { + parser->buffer[parser->idx] = 0; + parser->cont = false; + } else { + parser->cont = true; + parser->buffer[parser->idx++] = ch; + } + + *ppos += read; + ret = read; + +out: + return ret; +} + ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, size_t cnt) { int len; diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index b69697b..28247ce 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -616,6 +616,41 @@ static inline int ftrace_trace_task(struct task_struct *task) #endif /* + * struct trace_parser - servers for reading the user input separated by spaces + * @cont: set if the input is not complete - no final space char was found + * @buffer: holds the parsed user input + * @idx: user input lenght + * @size: buffer size + */ +struct trace_parser { + bool cont; + char *buffer; + unsigned idx; + unsigned size; +}; + +static inline bool trace_parser_loaded(struct trace_parser *parser) +{ + return (parser->idx != 0); +} + +static inline bool trace_parser_cont(struct trace_parser *parser) +{ + return parser->cont; +} + +static inline void trace_parser_clear(struct trace_parser *parser) +{ + parser->cont = false; + parser->idx = 0; +} + +extern int trace_parser_get_init(struct trace_parser *parser, int size); +extern void trace_parser_put(struct trace_parser *parser); +extern int trace_get_user(struct trace_parser *parser, const char __user *ubuf, + size_t cnt, loff_t *ppos); + +/* * trace_iterator_flags is an enumeration that defines bit * positions into trace_flags that controls the output. * ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCHv3 2/3] [PATCHv3 2/3] tracing - trace parser support for set_event 2009-09-11 15:29 [PATCHv3 0/3] tracing - adding common method for reading/parsing user input jolsa 2009-09-11 15:29 ` [PATCHv3 1/3] [PATCHv3 1/3] tracing - trace parser definition, parsing function jolsa @ 2009-09-11 15:29 ` jolsa 2009-09-12 7:54 ` [tip:tracing/core] tracing: " tip-bot for jolsa@redhat.com 2009-09-11 15:29 ` [PATCHv3 3/3] [PATCHv3 3/3] tracing - trace parser support for set_graph_function set_ftrace_filter set_ftrace_notrace jolsa 2009-09-11 15:32 ` [PATCHv3 0/3] tracing - adding common method for reading/parsing user input Steven Rostedt 3 siblings, 1 reply; 10+ messages in thread From: jolsa @ 2009-09-11 15:29 UTC (permalink / raw) To: mingo, rostedt; +Cc: linux-kernel Updated 'set_event' write method to use the 'trace_get_user' function. wbr, jirka Signed-off-by: Jiri Olsa <jolsa@redhat.com> --- kernel/trace/trace_events.c | 60 +++++++++--------------------------------- 1 files changed, 13 insertions(+), 47 deletions(-) diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 78b1ed2..db0f75c 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -230,11 +230,9 @@ static ssize_t ftrace_event_write(struct file *file, const char __user *ubuf, size_t cnt, loff_t *ppos) { + struct trace_parser parser; size_t read = 0; - int i, set = 1; ssize_t ret; - char *buf; - char ch; if (!cnt || cnt < 0) return 0; @@ -243,60 +241,28 @@ ftrace_event_write(struct file *file, const char __user *ubuf, if (ret < 0) return ret; - ret = get_user(ch, ubuf++); - if (ret) - return ret; - read++; - cnt--; - - /* skip white space */ - while (cnt && isspace(ch)) { - ret = get_user(ch, ubuf++); - if (ret) - return ret; - read++; - cnt--; - } - - /* Only white space found? */ - if (isspace(ch)) { - file->f_pos += read; - ret = read; - return ret; - } - - buf = kmalloc(EVENT_BUF_SIZE+1, GFP_KERNEL); - if (!buf) + if (trace_parser_get_init(&parser, EVENT_BUF_SIZE + 1)) return -ENOMEM; - if (cnt > EVENT_BUF_SIZE) - cnt = EVENT_BUF_SIZE; + read = trace_get_user(&parser, ubuf, cnt, ppos); + + if (trace_parser_loaded((&parser))) { + int set = 1; - i = 0; - while (cnt && !isspace(ch)) { - if (!i && ch == '!') + if (*parser.buffer == '!') set = 0; - else - buf[i++] = ch; - ret = get_user(ch, ubuf++); + parser.buffer[parser.idx] = 0; + + ret = ftrace_set_clr_event(parser.buffer + !set, set); if (ret) - goto out_free; - read++; - cnt--; + goto out_put; } - buf[i] = 0; - - file->f_pos += read; - - ret = ftrace_set_clr_event(buf, set); - if (ret) - goto out_free; ret = read; - out_free: - kfree(buf); + out_put: + trace_parser_put(&parser); return ret; } -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [tip:tracing/core] tracing: trace parser support for set_event 2009-09-11 15:29 ` [PATCHv3 2/3] [PATCHv3 2/3] tracing - trace parser support for set_event jolsa @ 2009-09-12 7:54 ` tip-bot for jolsa@redhat.com 0 siblings, 0 replies; 10+ messages in thread From: tip-bot for jolsa@redhat.com @ 2009-09-12 7:54 UTC (permalink / raw) To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, rostedt, tglx, jolsa Commit-ID: 489663644c35d50a20f58d468a7cbc705e6a29ce Gitweb: http://git.kernel.org/tip/489663644c35d50a20f58d468a7cbc705e6a29ce Author: jolsa@redhat.com <jolsa@redhat.com> AuthorDate: Fri, 11 Sep 2009 17:29:28 +0200 Committer: Steven Rostedt <rostedt@goodmis.org> CommitDate: Fri, 11 Sep 2009 14:47:11 -0400 tracing: trace parser support for set_event Convert the parsing of the file 'set_event' to use the generic trace_praser 'trace_get_user' function. Signed-off-by: Jiri Olsa <jolsa@redhat.com> LKML-Reference: <1252682969-3366-3-git-send-email-jolsa@redhat.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> --- kernel/trace/trace_events.c | 60 +++++++++--------------------------------- 1 files changed, 13 insertions(+), 47 deletions(-) diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 975f324..f46d14c 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -230,11 +230,9 @@ static ssize_t ftrace_event_write(struct file *file, const char __user *ubuf, size_t cnt, loff_t *ppos) { + struct trace_parser parser; size_t read = 0; - int i, set = 1; ssize_t ret; - char *buf; - char ch; if (!cnt || cnt < 0) return 0; @@ -243,60 +241,28 @@ ftrace_event_write(struct file *file, const char __user *ubuf, if (ret < 0) return ret; - ret = get_user(ch, ubuf++); - if (ret) - return ret; - read++; - cnt--; - - /* skip white space */ - while (cnt && isspace(ch)) { - ret = get_user(ch, ubuf++); - if (ret) - return ret; - read++; - cnt--; - } - - /* Only white space found? */ - if (isspace(ch)) { - file->f_pos += read; - ret = read; - return ret; - } - - buf = kmalloc(EVENT_BUF_SIZE+1, GFP_KERNEL); - if (!buf) + if (trace_parser_get_init(&parser, EVENT_BUF_SIZE + 1)) return -ENOMEM; - if (cnt > EVENT_BUF_SIZE) - cnt = EVENT_BUF_SIZE; + read = trace_get_user(&parser, ubuf, cnt, ppos); + + if (trace_parser_loaded((&parser))) { + int set = 1; - i = 0; - while (cnt && !isspace(ch)) { - if (!i && ch == '!') + if (*parser.buffer == '!') set = 0; - else - buf[i++] = ch; - ret = get_user(ch, ubuf++); + parser.buffer[parser.idx] = 0; + + ret = ftrace_set_clr_event(parser.buffer + !set, set); if (ret) - goto out_free; - read++; - cnt--; + goto out_put; } - buf[i] = 0; - - file->f_pos += read; - - ret = ftrace_set_clr_event(buf, set); - if (ret) - goto out_free; ret = read; - out_free: - kfree(buf); + out_put: + trace_parser_put(&parser); return ret; } ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCHv3 3/3] [PATCHv3 3/3] tracing - trace parser support for set_graph_function set_ftrace_filter set_ftrace_notrace 2009-09-11 15:29 [PATCHv3 0/3] tracing - adding common method for reading/parsing user input jolsa 2009-09-11 15:29 ` [PATCHv3 1/3] [PATCHv3 1/3] tracing - trace parser definition, parsing function jolsa 2009-09-11 15:29 ` [PATCHv3 2/3] [PATCHv3 2/3] tracing - trace parser support for set_event jolsa @ 2009-09-11 15:29 ` jolsa 2009-09-11 19:20 ` Steven Rostedt 2009-09-12 7:55 ` [tip:tracing/core] tracing: trace parser support for function and graph tip-bot for jolsa@redhat.com 2009-09-11 15:32 ` [PATCHv3 0/3] tracing - adding common method for reading/parsing user input Steven Rostedt 3 siblings, 2 replies; 10+ messages in thread From: jolsa @ 2009-09-11 15:29 UTC (permalink / raw) To: mingo, rostedt; +Cc: linux-kernel Updated 'set_graph_function', 'set_ftrace_filter', 'set_ftrace_notrace' write methods to use the 'trace_get_user' function. Removed FTRACE_ITER_CONT flag, since it's not needed after this change. Fixed minor in set_graph_function display - g_show function. wbr, jirka Signed-off-by: Jiri Olsa <jolsa@redhat.com> --- kernel/trace/ftrace.c | 150 +++++++++++++------------------------------------ 1 files changed, 40 insertions(+), 110 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 8c804e2..7d68163 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -1323,11 +1323,10 @@ static int __init ftrace_dyn_table_alloc(unsigned long num_to_init) enum { FTRACE_ITER_FILTER = (1 << 0), - FTRACE_ITER_CONT = (1 << 1), - FTRACE_ITER_NOTRACE = (1 << 2), - FTRACE_ITER_FAILURES = (1 << 3), - FTRACE_ITER_PRINTALL = (1 << 4), - FTRACE_ITER_HASH = (1 << 5), + FTRACE_ITER_NOTRACE = (1 << 1), + FTRACE_ITER_FAILURES = (1 << 2), + FTRACE_ITER_PRINTALL = (1 << 3), + FTRACE_ITER_HASH = (1 << 4), }; #define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */ @@ -1337,8 +1336,7 @@ struct ftrace_iterator { int hidx; int idx; unsigned flags; - unsigned char buffer[FTRACE_BUFF_MAX+1]; - unsigned buffer_idx; + struct trace_parser parser; }; static void * @@ -1604,6 +1602,11 @@ ftrace_regex_open(struct inode *inode, struct file *file, int enable) if (!iter) return -ENOMEM; + if (trace_parser_get_init(&iter->parser, FTRACE_BUFF_MAX)) { + kfree(iter); + return -ENOMEM; + } + mutex_lock(&ftrace_regex_lock); if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) @@ -2196,9 +2199,8 @@ ftrace_regex_write(struct file *file, const char __user *ubuf, size_t cnt, loff_t *ppos, int enable) { struct ftrace_iterator *iter; - char ch; - size_t read = 0; - ssize_t ret; + struct trace_parser *parser; + ssize_t ret, read; if (!cnt || cnt < 0) return 0; @@ -2211,72 +2213,23 @@ ftrace_regex_write(struct file *file, const char __user *ubuf, } else iter = file->private_data; - if (!*ppos) { - iter->flags &= ~FTRACE_ITER_CONT; - iter->buffer_idx = 0; - } - - ret = get_user(ch, ubuf++); - if (ret) - goto out; - read++; - cnt--; - - /* - * If the parser haven't finished with the last write, - * continue reading the user input without skipping spaces. - */ - if (!(iter->flags & FTRACE_ITER_CONT)) { - /* skip white space */ - while (cnt && isspace(ch)) { - ret = get_user(ch, ubuf++); - if (ret) - goto out; - read++; - cnt--; - } + parser = &iter->parser; + read = trace_get_user(parser, ubuf, cnt, ppos); - /* only spaces were written */ - if (isspace(ch)) { - *ppos += read; - ret = read; - goto out; - } - - iter->buffer_idx = 0; - } - - while (cnt && !isspace(ch)) { - if (iter->buffer_idx < FTRACE_BUFF_MAX) - iter->buffer[iter->buffer_idx++] = ch; - else { - ret = -EINVAL; - goto out; - } - ret = get_user(ch, ubuf++); + if (trace_parser_loaded(parser) && + !trace_parser_cont(parser)) { + ret = ftrace_process_regex(parser->buffer, + parser->idx, enable); if (ret) goto out; - read++; - cnt--; - } - if (isspace(ch)) { - iter->buffer[iter->buffer_idx] = 0; - ret = ftrace_process_regex(iter->buffer, - iter->buffer_idx, enable); - if (ret) - goto out; - iter->buffer_idx = 0; - } else { - iter->flags |= FTRACE_ITER_CONT; - iter->buffer[iter->buffer_idx++] = ch; + trace_parser_clear(parser); } - *ppos += read; ret = read; - out: - mutex_unlock(&ftrace_regex_lock); + mutex_unlock(&ftrace_regex_lock); +out: return ret; } @@ -2381,6 +2334,7 @@ ftrace_regex_release(struct inode *inode, struct file *file, int enable) { struct seq_file *m = (struct seq_file *)file->private_data; struct ftrace_iterator *iter; + struct trace_parser *parser; mutex_lock(&ftrace_regex_lock); if (file->f_mode & FMODE_READ) { @@ -2390,9 +2344,10 @@ ftrace_regex_release(struct inode *inode, struct file *file, int enable) } else iter = file->private_data; - if (iter->buffer_idx) { - iter->buffer[iter->buffer_idx] = 0; - ftrace_match_records(iter->buffer, iter->buffer_idx, enable); + parser = &iter->parser; + if (trace_parser_loaded(parser)) { + parser->buffer[parser->idx] = 0; + ftrace_match_records(parser->buffer, parser->idx, enable); } mutex_lock(&ftrace_lock); @@ -2400,7 +2355,9 @@ ftrace_regex_release(struct inode *inode, struct file *file, int enable) ftrace_run_update_code(FTRACE_ENABLE_CALLS); mutex_unlock(&ftrace_lock); + trace_parser_put(parser); kfree(iter); + mutex_unlock(&ftrace_regex_lock); return 0; } @@ -2499,7 +2456,7 @@ static int g_show(struct seq_file *m, void *v) return 0; } - seq_printf(m, "%pf\n", v); + seq_printf(m, "%p\n", (void *) *ptr); return 0; } @@ -2602,12 +2559,10 @@ static ssize_t ftrace_graph_write(struct file *file, const char __user *ubuf, size_t cnt, loff_t *ppos) { - unsigned char buffer[FTRACE_BUFF_MAX+1]; + struct trace_parser parser; unsigned long *array; size_t read = 0; ssize_t ret; - int index = 0; - char ch; if (!cnt || cnt < 0) return 0; @@ -2625,51 +2580,26 @@ ftrace_graph_write(struct file *file, const char __user *ubuf, } else array = file->private_data; - ret = get_user(ch, ubuf++); - if (ret) + if (trace_parser_get_init(&parser, FTRACE_BUFF_MAX)) { + ret = -ENOMEM; goto out; - read++; - cnt--; - - /* skip white space */ - while (cnt && isspace(ch)) { - ret = get_user(ch, ubuf++); - if (ret) - goto out; - read++; - cnt--; } - if (isspace(ch)) { - *ppos += read; - ret = read; - goto out; - } + read = trace_get_user(&parser, ubuf, cnt, ppos); - while (cnt && !isspace(ch)) { - if (index < FTRACE_BUFF_MAX) - buffer[index++] = ch; - else { - ret = -EINVAL; - goto out; - } - ret = get_user(ch, ubuf++); + if (trace_parser_loaded((&parser))) { + parser.buffer[parser.idx] = 0; + + /* we allow only one expression at a time */ + ret = ftrace_set_func(array, &ftrace_graph_count, + parser.buffer); if (ret) goto out; - read++; - cnt--; } - buffer[index] = 0; - - /* we allow only one expression at a time */ - ret = ftrace_set_func(array, &ftrace_graph_count, buffer); - if (ret) - goto out; - - file->f_pos += read; ret = read; out: + trace_parser_put(&parser); mutex_unlock(&graph_lock); return ret; -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCHv3 3/3] [PATCHv3 3/3] tracing - trace parser support for set_graph_function set_ftrace_filter set_ftrace_notrace 2009-09-11 15:29 ` [PATCHv3 3/3] [PATCHv3 3/3] tracing - trace parser support for set_graph_function set_ftrace_filter set_ftrace_notrace jolsa @ 2009-09-11 19:20 ` Steven Rostedt 2009-09-14 6:33 ` Jiri Olsa 2009-09-12 7:55 ` [tip:tracing/core] tracing: trace parser support for function and graph tip-bot for jolsa@redhat.com 1 sibling, 1 reply; 10+ messages in thread From: Steven Rostedt @ 2009-09-11 19:20 UTC (permalink / raw) To: jolsa; +Cc: mingo, linux-kernel Nit - fix your scripts again. The subject duplicates the [PATCHv3 3/3]. On Fri, 2009-09-11 at 17:29 +0200, jolsa@redhat.com wrote: > Fixed minor in set_graph_function display - g_show function. > @@ -2499,7 +2456,7 @@ static int g_show(struct seq_file *m, void *v) > return 0; > } > > - seq_printf(m, "%pf\n", v); > + seq_printf(m, "%p\n", (void *) *ptr); > > return 0; > } I changed this, because it has a bug itself. You just changed the way set_graph_function works. It use to do: # echo sys_open > set_graph_function # cat set_graph_function sys_open After this change, it does # echo sys_open > set_graph_function # cat set_graph_function ffffffff811020d0 Which is not very helpful. But, you did catch a bug. Another clean up patch, made it from *ptr to v, which is wrong. Half that change is correct ;-) Thus I modified this patch with the following change: diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 7d68163..8b23d56 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -2456,7 +2456,7 @@ static int g_show(struct seq_file *m, void *v) return 0; } - seq_printf(m, "%p\n", (void *) *ptr); + seq_printf(m, "%pf\n", (void *)*ptr); return 0; } -- Steve ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCHv3 3/3] [PATCHv3 3/3] tracing - trace parser support for set_graph_function set_ftrace_filter set_ftrace_notrace 2009-09-11 19:20 ` Steven Rostedt @ 2009-09-14 6:33 ` Jiri Olsa 0 siblings, 0 replies; 10+ messages in thread From: Jiri Olsa @ 2009-09-14 6:33 UTC (permalink / raw) To: Steven Rostedt; +Cc: mingo, linux-kernel On Fri, Sep 11, 2009 at 03:20:10PM -0400, Steven Rostedt wrote: > Nit - fix your scripts again. The subject duplicates the [PATCHv3 3/3]. oh crap, sry > > On Fri, 2009-09-11 at 17:29 +0200, jolsa@redhat.com wrote: > > > Fixed minor in set_graph_function display - g_show function. > > > @@ -2499,7 +2456,7 @@ static int g_show(struct seq_file *m, void *v) > > return 0; > > } > > > > - seq_printf(m, "%pf\n", v); > > + seq_printf(m, "%p\n", (void *) *ptr); > > > > return 0; > > } > > > I changed this, because it has a bug itself. You just changed the way > set_graph_function works. > > It use to do: > > # echo sys_open > set_graph_function > # cat set_graph_function > sys_open > > After this change, it does > > # echo sys_open > set_graph_function > # cat set_graph_function > ffffffff811020d0 > > Which is not very helpful. holly crap on a cracker... I did not know vsnprintf has the %pf spec.. cool ;) thanks, jirka ^ permalink raw reply [flat|nested] 10+ messages in thread
* [tip:tracing/core] tracing: trace parser support for function and graph 2009-09-11 15:29 ` [PATCHv3 3/3] [PATCHv3 3/3] tracing - trace parser support for set_graph_function set_ftrace_filter set_ftrace_notrace jolsa 2009-09-11 19:20 ` Steven Rostedt @ 2009-09-12 7:55 ` tip-bot for jolsa@redhat.com 1 sibling, 0 replies; 10+ messages in thread From: tip-bot for jolsa@redhat.com @ 2009-09-12 7:55 UTC (permalink / raw) To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, rostedt, tglx, jolsa Commit-ID: 689fd8b65d669b96d612ccc37d6fb87bf7ed6907 Gitweb: http://git.kernel.org/tip/689fd8b65d669b96d612ccc37d6fb87bf7ed6907 Author: jolsa@redhat.com <jolsa@redhat.com> AuthorDate: Fri, 11 Sep 2009 17:29:29 +0200 Committer: Steven Rostedt <rostedt@goodmis.org> CommitDate: Fri, 11 Sep 2009 15:20:18 -0400 tracing: trace parser support for function and graph Convert the writing to 'set_graph_function', 'set_ftrace_filter' and 'set_ftrace_notrace' to use the generic trace_parser 'trace_get_user' function. Removed FTRACE_ITER_CONT flag, since it's not needed after this change. Minor fix in set_graph_function display - g_show function. Signed-off-by: Jiri Olsa <jolsa@redhat.com> LKML-Reference: <1252682969-3366-4-git-send-email-jolsa@redhat.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> --- kernel/trace/ftrace.c | 150 +++++++++++++------------------------------------ 1 files changed, 40 insertions(+), 110 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 8c804e2..8b23d56 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -1323,11 +1323,10 @@ static int __init ftrace_dyn_table_alloc(unsigned long num_to_init) enum { FTRACE_ITER_FILTER = (1 << 0), - FTRACE_ITER_CONT = (1 << 1), - FTRACE_ITER_NOTRACE = (1 << 2), - FTRACE_ITER_FAILURES = (1 << 3), - FTRACE_ITER_PRINTALL = (1 << 4), - FTRACE_ITER_HASH = (1 << 5), + FTRACE_ITER_NOTRACE = (1 << 1), + FTRACE_ITER_FAILURES = (1 << 2), + FTRACE_ITER_PRINTALL = (1 << 3), + FTRACE_ITER_HASH = (1 << 4), }; #define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */ @@ -1337,8 +1336,7 @@ struct ftrace_iterator { int hidx; int idx; unsigned flags; - unsigned char buffer[FTRACE_BUFF_MAX+1]; - unsigned buffer_idx; + struct trace_parser parser; }; static void * @@ -1604,6 +1602,11 @@ ftrace_regex_open(struct inode *inode, struct file *file, int enable) if (!iter) return -ENOMEM; + if (trace_parser_get_init(&iter->parser, FTRACE_BUFF_MAX)) { + kfree(iter); + return -ENOMEM; + } + mutex_lock(&ftrace_regex_lock); if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) @@ -2196,9 +2199,8 @@ ftrace_regex_write(struct file *file, const char __user *ubuf, size_t cnt, loff_t *ppos, int enable) { struct ftrace_iterator *iter; - char ch; - size_t read = 0; - ssize_t ret; + struct trace_parser *parser; + ssize_t ret, read; if (!cnt || cnt < 0) return 0; @@ -2211,72 +2213,23 @@ ftrace_regex_write(struct file *file, const char __user *ubuf, } else iter = file->private_data; - if (!*ppos) { - iter->flags &= ~FTRACE_ITER_CONT; - iter->buffer_idx = 0; - } - - ret = get_user(ch, ubuf++); - if (ret) - goto out; - read++; - cnt--; - - /* - * If the parser haven't finished with the last write, - * continue reading the user input without skipping spaces. - */ - if (!(iter->flags & FTRACE_ITER_CONT)) { - /* skip white space */ - while (cnt && isspace(ch)) { - ret = get_user(ch, ubuf++); - if (ret) - goto out; - read++; - cnt--; - } + parser = &iter->parser; + read = trace_get_user(parser, ubuf, cnt, ppos); - /* only spaces were written */ - if (isspace(ch)) { - *ppos += read; - ret = read; - goto out; - } - - iter->buffer_idx = 0; - } - - while (cnt && !isspace(ch)) { - if (iter->buffer_idx < FTRACE_BUFF_MAX) - iter->buffer[iter->buffer_idx++] = ch; - else { - ret = -EINVAL; - goto out; - } - ret = get_user(ch, ubuf++); + if (trace_parser_loaded(parser) && + !trace_parser_cont(parser)) { + ret = ftrace_process_regex(parser->buffer, + parser->idx, enable); if (ret) goto out; - read++; - cnt--; - } - if (isspace(ch)) { - iter->buffer[iter->buffer_idx] = 0; - ret = ftrace_process_regex(iter->buffer, - iter->buffer_idx, enable); - if (ret) - goto out; - iter->buffer_idx = 0; - } else { - iter->flags |= FTRACE_ITER_CONT; - iter->buffer[iter->buffer_idx++] = ch; + trace_parser_clear(parser); } - *ppos += read; ret = read; - out: - mutex_unlock(&ftrace_regex_lock); + mutex_unlock(&ftrace_regex_lock); +out: return ret; } @@ -2381,6 +2334,7 @@ ftrace_regex_release(struct inode *inode, struct file *file, int enable) { struct seq_file *m = (struct seq_file *)file->private_data; struct ftrace_iterator *iter; + struct trace_parser *parser; mutex_lock(&ftrace_regex_lock); if (file->f_mode & FMODE_READ) { @@ -2390,9 +2344,10 @@ ftrace_regex_release(struct inode *inode, struct file *file, int enable) } else iter = file->private_data; - if (iter->buffer_idx) { - iter->buffer[iter->buffer_idx] = 0; - ftrace_match_records(iter->buffer, iter->buffer_idx, enable); + parser = &iter->parser; + if (trace_parser_loaded(parser)) { + parser->buffer[parser->idx] = 0; + ftrace_match_records(parser->buffer, parser->idx, enable); } mutex_lock(&ftrace_lock); @@ -2400,7 +2355,9 @@ ftrace_regex_release(struct inode *inode, struct file *file, int enable) ftrace_run_update_code(FTRACE_ENABLE_CALLS); mutex_unlock(&ftrace_lock); + trace_parser_put(parser); kfree(iter); + mutex_unlock(&ftrace_regex_lock); return 0; } @@ -2499,7 +2456,7 @@ static int g_show(struct seq_file *m, void *v) return 0; } - seq_printf(m, "%pf\n", v); + seq_printf(m, "%pf\n", (void *)*ptr); return 0; } @@ -2602,12 +2559,10 @@ static ssize_t ftrace_graph_write(struct file *file, const char __user *ubuf, size_t cnt, loff_t *ppos) { - unsigned char buffer[FTRACE_BUFF_MAX+1]; + struct trace_parser parser; unsigned long *array; size_t read = 0; ssize_t ret; - int index = 0; - char ch; if (!cnt || cnt < 0) return 0; @@ -2625,51 +2580,26 @@ ftrace_graph_write(struct file *file, const char __user *ubuf, } else array = file->private_data; - ret = get_user(ch, ubuf++); - if (ret) + if (trace_parser_get_init(&parser, FTRACE_BUFF_MAX)) { + ret = -ENOMEM; goto out; - read++; - cnt--; - - /* skip white space */ - while (cnt && isspace(ch)) { - ret = get_user(ch, ubuf++); - if (ret) - goto out; - read++; - cnt--; } - if (isspace(ch)) { - *ppos += read; - ret = read; - goto out; - } + read = trace_get_user(&parser, ubuf, cnt, ppos); - while (cnt && !isspace(ch)) { - if (index < FTRACE_BUFF_MAX) - buffer[index++] = ch; - else { - ret = -EINVAL; - goto out; - } - ret = get_user(ch, ubuf++); + if (trace_parser_loaded((&parser))) { + parser.buffer[parser.idx] = 0; + + /* we allow only one expression at a time */ + ret = ftrace_set_func(array, &ftrace_graph_count, + parser.buffer); if (ret) goto out; - read++; - cnt--; } - buffer[index] = 0; - - /* we allow only one expression at a time */ - ret = ftrace_set_func(array, &ftrace_graph_count, buffer); - if (ret) - goto out; - - file->f_pos += read; ret = read; out: + trace_parser_put(&parser); mutex_unlock(&graph_lock); return ret; ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCHv3 0/3] tracing - adding common method for reading/parsing user input 2009-09-11 15:29 [PATCHv3 0/3] tracing - adding common method for reading/parsing user input jolsa ` (2 preceding siblings ...) 2009-09-11 15:29 ` [PATCHv3 3/3] [PATCHv3 3/3] tracing - trace parser support for set_graph_function set_ftrace_filter set_ftrace_notrace jolsa @ 2009-09-11 15:32 ` Steven Rostedt 3 siblings, 0 replies; 10+ messages in thread From: Steven Rostedt @ 2009-09-11 15:32 UTC (permalink / raw) To: jolsa; +Cc: mingo, linux-kernel On Fri, 2009-09-11 at 17:29 +0200, jolsa@redhat.com wrote: > As 3 different places for 4 user input files were using the same way > of reading and parsing user's input, I made one common routine to be > used. > > The mentioned files are: > set_graph_function > set_event > set_ftrace_filter > set_ftrace_notrace > > wbr, > jirka Thanks Jirka, much better. I'll pull them in and try them out. -- Steve ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2009-09-14 6:33 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-09-11 15:29 [PATCHv3 0/3] tracing - adding common method for reading/parsing user input jolsa 2009-09-11 15:29 ` [PATCHv3 1/3] [PATCHv3 1/3] tracing - trace parser definition, parsing function jolsa 2009-09-12 7:54 ` [tip:tracing/core] tracing: create generic trace parser tip-bot for jolsa@redhat.com 2009-09-11 15:29 ` [PATCHv3 2/3] [PATCHv3 2/3] tracing - trace parser support for set_event jolsa 2009-09-12 7:54 ` [tip:tracing/core] tracing: " tip-bot for jolsa@redhat.com 2009-09-11 15:29 ` [PATCHv3 3/3] [PATCHv3 3/3] tracing - trace parser support for set_graph_function set_ftrace_filter set_ftrace_notrace jolsa 2009-09-11 19:20 ` Steven Rostedt 2009-09-14 6:33 ` Jiri Olsa 2009-09-12 7:55 ` [tip:tracing/core] tracing: trace parser support for function and graph tip-bot for jolsa@redhat.com 2009-09-11 15:32 ` [PATCHv3 0/3] tracing - adding common method for reading/parsing user input Steven Rostedt
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox