* [PATCH 1/7] tracing/events: don't increment @pos in s_start()
2009-06-24 1:52 [PATCH 0/7] tracing: seqfile fixes, take 2 Li Zefan
@ 2009-06-24 1:52 ` Li Zefan
2009-06-24 9:45 ` [tip:tracing/urgent] tracing/events: Don't " tip-bot for Li Zefan
2009-06-24 1:52 ` [PATCH 2/7] tracing_bprintk: don't increment @pos in t_start() Li Zefan
` (6 subsequent siblings)
7 siblings, 1 reply; 16+ messages in thread
From: Li Zefan @ 2009-06-24 1:52 UTC (permalink / raw)
To: Ingo Molnar; +Cc: Steven Rostedt, Frederic Weisbecker, Liming Wang, LKML
While testing syscall tracepoints posted by Jason, I found 3 entries
were missing when reading available_events. The output size of
available_events is < 4 pages, which means we lost 1 entry per page.
The cause is, it's wrong to increment @pos in s_start().
Actually there's another bug here -- reading avaiable_events/set_events
can race with module unload:
# cat available_events |
s_start() |
s_stop() |
| # rmmod foo.ko
s_start() |
call = list_entry(m->private) |
@call might be freed and accessing it will lead to crash.
[ Impact fix missing entries when reading available_events/set_events ]
Reviewed-by: Liming Wang <liming.wang@windriver.com>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
---
kernel/trace/trace_events.c | 28 ++++++++++++++++++++++------
1 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index aa08be6..53c8fd3 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -300,10 +300,18 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
static void *t_start(struct seq_file *m, loff_t *pos)
{
+ struct ftrace_event_call *call = NULL;
+ loff_t l;
+
mutex_lock(&event_mutex);
- if (*pos == 0)
- m->private = ftrace_events.next;
- return t_next(m, NULL, pos);
+
+ m->private = ftrace_events.next;
+ for (l = 0; l <= *pos; ) {
+ call = t_next(m, NULL, &l);
+ if (!call)
+ break;
+ }
+ return call;
}
static void *
@@ -332,10 +340,18 @@ s_next(struct seq_file *m, void *v, loff_t *pos)
static void *s_start(struct seq_file *m, loff_t *pos)
{
+ struct ftrace_event_call *call = NULL;
+ loff_t l;
+
mutex_lock(&event_mutex);
- if (*pos == 0)
- m->private = ftrace_events.next;
- return s_next(m, NULL, pos);
+
+ m->private = ftrace_events.next;
+ for (l = 0; l <= *pos; ) {
+ call = s_next(m, NULL, &l);
+ if (!call)
+ break;
+ }
+ return call;
}
static int t_show(struct seq_file *m, void *v)
--
1.5.4.rc3
^ permalink raw reply related [flat|nested] 16+ messages in thread* [tip:tracing/urgent] tracing/events: Don't increment @pos in s_start()
2009-06-24 1:52 ` [PATCH 1/7] tracing/events: don't increment @pos in s_start() Li Zefan
@ 2009-06-24 9:45 ` tip-bot for Li Zefan
0 siblings, 0 replies; 16+ messages in thread
From: tip-bot for Li Zefan @ 2009-06-24 9:45 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, hpa, mingo, lizf, fweisbec, rostedt, tglx,
liming.wang, mingo
Commit-ID: e1c7e2a6e67fe9db19dd15e71614526a31b5fdb1
Gitweb: http://git.kernel.org/tip/e1c7e2a6e67fe9db19dd15e71614526a31b5fdb1
Author: Li Zefan <lizf@cn.fujitsu.com>
AuthorDate: Wed, 24 Jun 2009 09:52:29 +0800
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Wed, 24 Jun 2009 11:02:49 +0200
tracing/events: Don't increment @pos in s_start()
While testing syscall tracepoints posted by Jason, I found 3 entries
were missing when reading available_events. The output size of
available_events is < 4 pages, which means we lost 1 entry per page.
The cause is, it's wrong to increment @pos in s_start().
Actually there's another bug here -- reading avaiable_events/set_events
can race with module unload:
# cat available_events |
s_start() |
s_stop() |
| # rmmod foo.ko
s_start() |
call = list_entry(m->private) |
@call might be freed and accessing it will lead to crash.
Reviewed-by: Liming Wang <liming.wang@windriver.com>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <4A4186DD.6090405@cn.fujitsu.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
kernel/trace/trace_events.c | 28 ++++++++++++++++++++++------
1 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index aa08be6..53c8fd3 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -300,10 +300,18 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
static void *t_start(struct seq_file *m, loff_t *pos)
{
+ struct ftrace_event_call *call = NULL;
+ loff_t l;
+
mutex_lock(&event_mutex);
- if (*pos == 0)
- m->private = ftrace_events.next;
- return t_next(m, NULL, pos);
+
+ m->private = ftrace_events.next;
+ for (l = 0; l <= *pos; ) {
+ call = t_next(m, NULL, &l);
+ if (!call)
+ break;
+ }
+ return call;
}
static void *
@@ -332,10 +340,18 @@ s_next(struct seq_file *m, void *v, loff_t *pos)
static void *s_start(struct seq_file *m, loff_t *pos)
{
+ struct ftrace_event_call *call = NULL;
+ loff_t l;
+
mutex_lock(&event_mutex);
- if (*pos == 0)
- m->private = ftrace_events.next;
- return s_next(m, NULL, pos);
+
+ m->private = ftrace_events.next;
+ for (l = 0; l <= *pos; ) {
+ call = s_next(m, NULL, &l);
+ if (!call)
+ break;
+ }
+ return call;
}
static int t_show(struct seq_file *m, void *v)
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 2/7] tracing_bprintk: don't increment @pos in t_start()
2009-06-24 1:52 [PATCH 0/7] tracing: seqfile fixes, take 2 Li Zefan
2009-06-24 1:52 ` [PATCH 1/7] tracing/events: don't increment @pos in s_start() Li Zefan
@ 2009-06-24 1:52 ` Li Zefan
2009-06-24 9:45 ` [tip:tracing/urgent] tracing_bprintk: Don't " tip-bot for Li Zefan
2009-06-24 1:53 ` [PATCH 3/7] trace_stat: don't increment @pos in seq start() Li Zefan
` (5 subsequent siblings)
7 siblings, 1 reply; 16+ messages in thread
From: Li Zefan @ 2009-06-24 1:52 UTC (permalink / raw)
To: Ingo Molnar
Cc: Steven Rostedt, Frederic Weisbecker, Liming Wang, LKML,
Lai Jiangshan
It's wrong to increment @pos in t_start(), otherwise we'll lose
some entries when reading printk_formats, if the output is larger
than PAGE_SIZE.
[ Impact: fix missing entries when reading printk_formats ]
Reported-by: Lai Jiangshan <laijs@cn.fujitsu.com>
Reviewed-by: Liming Wang <liming.wang@windriver.com>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
---
kernel/trace/trace_printk.c | 26 ++++++--------------------
1 files changed, 6 insertions(+), 20 deletions(-)
diff --git a/kernel/trace/trace_printk.c b/kernel/trace/trace_printk.c
index 9bece96..7b62781 100644
--- a/kernel/trace/trace_printk.c
+++ b/kernel/trace/trace_printk.c
@@ -155,25 +155,19 @@ int __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap)
EXPORT_SYMBOL_GPL(__ftrace_vprintk);
static void *
-t_next(struct seq_file *m, void *v, loff_t *pos)
+t_start(struct seq_file *m, loff_t *pos)
{
- const char **fmt = m->private;
- const char **next = fmt;
-
- (*pos)++;
+ const char **fmt = __start___trace_bprintk_fmt + *pos;
if ((unsigned long)fmt >= (unsigned long)__stop___trace_bprintk_fmt)
return NULL;
-
- next = fmt;
- m->private = ++next;
-
return fmt;
}
-static void *t_start(struct seq_file *m, loff_t *pos)
+static void *t_next(struct seq_file *m, void * v, loff_t *pos)
{
- return t_next(m, NULL, pos);
+ (*pos)++;
+ return t_start(m, pos);
}
static int t_show(struct seq_file *m, void *v)
@@ -224,15 +218,7 @@ static const struct seq_operations show_format_seq_ops = {
static int
ftrace_formats_open(struct inode *inode, struct file *file)
{
- int ret;
-
- ret = seq_open(file, &show_format_seq_ops);
- if (!ret) {
- struct seq_file *m = file->private_data;
-
- m->private = __start___trace_bprintk_fmt;
- }
- return ret;
+ return seq_open(file, &show_format_seq_ops);
}
static const struct file_operations ftrace_formats_fops = {
--
1.5.4.rc3
^ permalink raw reply related [flat|nested] 16+ messages in thread* [tip:tracing/urgent] tracing_bprintk: Don't increment @pos in t_start()
2009-06-24 1:52 ` [PATCH 2/7] tracing_bprintk: don't increment @pos in t_start() Li Zefan
@ 2009-06-24 9:45 ` tip-bot for Li Zefan
0 siblings, 0 replies; 16+ messages in thread
From: tip-bot for Li Zefan @ 2009-06-24 9:45 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, hpa, mingo, lizf, fweisbec, rostedt, tglx, laijs,
liming.wang, mingo
Commit-ID: c8961ec6da22ea010bf4470a8e0fb3fdad0f11c4
Gitweb: http://git.kernel.org/tip/c8961ec6da22ea010bf4470a8e0fb3fdad0f11c4
Author: Li Zefan <lizf@cn.fujitsu.com>
AuthorDate: Wed, 24 Jun 2009 09:52:58 +0800
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Wed, 24 Jun 2009 11:02:50 +0200
tracing_bprintk: Don't increment @pos in t_start()
It's wrong to increment @pos in t_start(), otherwise we'll lose
some entries when reading printk_formats, if the output is larger
than PAGE_SIZE.
Reported-by: Lai Jiangshan <laijs@cn.fujitsu.com>
Reviewed-by: Liming Wang <liming.wang@windriver.com>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <4A4186FA.1020106@cn.fujitsu.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
kernel/trace/trace_printk.c | 26 ++++++--------------------
1 files changed, 6 insertions(+), 20 deletions(-)
diff --git a/kernel/trace/trace_printk.c b/kernel/trace/trace_printk.c
index 9bece96..7b62781 100644
--- a/kernel/trace/trace_printk.c
+++ b/kernel/trace/trace_printk.c
@@ -155,25 +155,19 @@ int __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap)
EXPORT_SYMBOL_GPL(__ftrace_vprintk);
static void *
-t_next(struct seq_file *m, void *v, loff_t *pos)
+t_start(struct seq_file *m, loff_t *pos)
{
- const char **fmt = m->private;
- const char **next = fmt;
-
- (*pos)++;
+ const char **fmt = __start___trace_bprintk_fmt + *pos;
if ((unsigned long)fmt >= (unsigned long)__stop___trace_bprintk_fmt)
return NULL;
-
- next = fmt;
- m->private = ++next;
-
return fmt;
}
-static void *t_start(struct seq_file *m, loff_t *pos)
+static void *t_next(struct seq_file *m, void * v, loff_t *pos)
{
- return t_next(m, NULL, pos);
+ (*pos)++;
+ return t_start(m, pos);
}
static int t_show(struct seq_file *m, void *v)
@@ -224,15 +218,7 @@ static const struct seq_operations show_format_seq_ops = {
static int
ftrace_formats_open(struct inode *inode, struct file *file)
{
- int ret;
-
- ret = seq_open(file, &show_format_seq_ops);
- if (!ret) {
- struct seq_file *m = file->private_data;
-
- m->private = __start___trace_bprintk_fmt;
- }
- return ret;
+ return seq_open(file, &show_format_seq_ops);
}
static const struct file_operations ftrace_formats_fops = {
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 3/7] trace_stat: don't increment @pos in seq start()
2009-06-24 1:52 [PATCH 0/7] tracing: seqfile fixes, take 2 Li Zefan
2009-06-24 1:52 ` [PATCH 1/7] tracing/events: don't increment @pos in s_start() Li Zefan
2009-06-24 1:52 ` [PATCH 2/7] tracing_bprintk: don't increment @pos in t_start() Li Zefan
@ 2009-06-24 1:53 ` Li Zefan
2009-06-24 9:46 ` [tip:tracing/urgent] trace_stat: Don't " tip-bot for Li Zefan
2009-06-24 1:53 ` [PATCH 4/7] tracing: reset iterator in t_start() Li Zefan
` (4 subsequent siblings)
7 siblings, 1 reply; 16+ messages in thread
From: Li Zefan @ 2009-06-24 1:53 UTC (permalink / raw)
To: Ingo Molnar; +Cc: Steven Rostedt, Frederic Weisbecker, Liming Wang, LKML
It's wrong to increment @pos in stat_seq_start(). It causes some
stat entries lost when reading stat file, if the output of the file
is larger than PAGE_SIZE.
[ Impact: fix missing entries when reading stat file ]
Reviewed-by: Liming Wang <liming.wang@windriver.com>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
---
kernel/trace/trace_stat.c | 6 +-----
1 files changed, 1 insertions(+), 5 deletions(-)
diff --git a/kernel/trace/trace_stat.c b/kernel/trace/trace_stat.c
index c006437..e66f5e4 100644
--- a/kernel/trace/trace_stat.c
+++ b/kernel/trace/trace_stat.c
@@ -199,17 +199,13 @@ static void *stat_seq_start(struct seq_file *s, loff_t *pos)
mutex_lock(&session->stat_mutex);
/* If we are in the beginning of the file, print the headers */
- if (!*pos && session->ts->stat_headers) {
- (*pos)++;
+ if (!*pos && session->ts->stat_headers)
return SEQ_START_TOKEN;
- }
node = rb_first(&session->stat_root);
for (i = 0; node && i < *pos; i++)
node = rb_next(node);
- (*pos)++;
-
return node;
}
--
1.5.4.rc3
^ permalink raw reply related [flat|nested] 16+ messages in thread* [tip:tracing/urgent] trace_stat: Don't increment @pos in seq start()
2009-06-24 1:53 ` [PATCH 3/7] trace_stat: don't increment @pos in seq start() Li Zefan
@ 2009-06-24 9:46 ` tip-bot for Li Zefan
0 siblings, 0 replies; 16+ messages in thread
From: tip-bot for Li Zefan @ 2009-06-24 9:46 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, hpa, mingo, lizf, fweisbec, rostedt, tglx,
liming.wang, mingo
Commit-ID: 2961bf345fd1b736c3db46cad0f69855f67fbe9c
Gitweb: http://git.kernel.org/tip/2961bf345fd1b736c3db46cad0f69855f67fbe9c
Author: Li Zefan <lizf@cn.fujitsu.com>
AuthorDate: Wed, 24 Jun 2009 09:53:26 +0800
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Wed, 24 Jun 2009 11:02:51 +0200
trace_stat: Don't increment @pos in seq start()
It's wrong to increment @pos in stat_seq_start(). It causes some
stat entries lost when reading stat file, if the output of the file
is larger than PAGE_SIZE.
Reviewed-by: Liming Wang <liming.wang@windriver.com>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <4A418716.90209@cn.fujitsu.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
kernel/trace/trace_stat.c | 6 +-----
1 files changed, 1 insertions(+), 5 deletions(-)
diff --git a/kernel/trace/trace_stat.c b/kernel/trace/trace_stat.c
index c006437..e66f5e4 100644
--- a/kernel/trace/trace_stat.c
+++ b/kernel/trace/trace_stat.c
@@ -199,17 +199,13 @@ static void *stat_seq_start(struct seq_file *s, loff_t *pos)
mutex_lock(&session->stat_mutex);
/* If we are in the beginning of the file, print the headers */
- if (!*pos && session->ts->stat_headers) {
- (*pos)++;
+ if (!*pos && session->ts->stat_headers)
return SEQ_START_TOKEN;
- }
node = rb_first(&session->stat_root);
for (i = 0; node && i < *pos; i++)
node = rb_next(node);
- (*pos)++;
-
return node;
}
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 4/7] tracing: reset iterator in t_start()
2009-06-24 1:52 [PATCH 0/7] tracing: seqfile fixes, take 2 Li Zefan
` (2 preceding siblings ...)
2009-06-24 1:53 ` [PATCH 3/7] trace_stat: don't increment @pos in seq start() Li Zefan
@ 2009-06-24 1:53 ` Li Zefan
2009-06-24 9:46 ` [tip:tracing/urgent] tracing: Reset " tip-bot for Li Zefan
2009-06-24 1:54 ` [PATCH 5/7] ftrace: don't increment @pos in g_start() Li Zefan
` (3 subsequent siblings)
7 siblings, 1 reply; 16+ messages in thread
From: Li Zefan @ 2009-06-24 1:53 UTC (permalink / raw)
To: Ingo Molnar; +Cc: Steven Rostedt, Frederic Weisbecker, Liming Wang, LKML
The iterator is m->private, but it's not reset to trace_types in
t_start(). If the output is larger than PAGE_SIZE and t_start()
is called the 2nd time, things will go wrong.
[ Impact: fix output of current_tracer if it's larger than PAGE_SIZE ]
Reviewed-by: Liming Wang <liming.wang@windriver.com>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
---
kernel/trace/trace.c | 18 ++++--------------
1 files changed, 4 insertions(+), 14 deletions(-)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 076fa6f..3bb3100 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -2053,25 +2053,23 @@ static int tracing_open(struct inode *inode, struct file *file)
static void *
t_next(struct seq_file *m, void *v, loff_t *pos)
{
- struct tracer *t = m->private;
+ struct tracer *t = v;
(*pos)++;
if (t)
t = t->next;
- m->private = t;
-
return t;
}
static void *t_start(struct seq_file *m, loff_t *pos)
{
- struct tracer *t = m->private;
+ struct tracer *t;
loff_t l = 0;
mutex_lock(&trace_types_lock);
- for (; t && l < *pos; t = t_next(m, t, &l))
+ for (t = trace_types; t && l < *pos; t = t_next(m, t, &l))
;
return t;
@@ -2107,18 +2105,10 @@ static struct seq_operations show_traces_seq_ops = {
static int show_traces_open(struct inode *inode, struct file *file)
{
- int ret;
-
if (tracing_disabled)
return -ENODEV;
- ret = seq_open(file, &show_traces_seq_ops);
- if (!ret) {
- struct seq_file *m = file->private_data;
- m->private = trace_types;
- }
-
- return ret;
+ return seq_open(file, &show_traces_seq_ops);
}
static ssize_t
--
1.5.4.rc3
^ permalink raw reply related [flat|nested] 16+ messages in thread* [tip:tracing/urgent] tracing: Reset iterator in t_start()
2009-06-24 1:53 ` [PATCH 4/7] tracing: reset iterator in t_start() Li Zefan
@ 2009-06-24 9:46 ` tip-bot for Li Zefan
0 siblings, 0 replies; 16+ messages in thread
From: tip-bot for Li Zefan @ 2009-06-24 9:46 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, hpa, mingo, lizf, fweisbec, rostedt, tglx,
liming.wang, mingo
Commit-ID: f129e965bef40c6153e4fe505f1e408286213424
Gitweb: http://git.kernel.org/tip/f129e965bef40c6153e4fe505f1e408286213424
Author: Li Zefan <lizf@cn.fujitsu.com>
AuthorDate: Wed, 24 Jun 2009 09:53:44 +0800
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Wed, 24 Jun 2009 11:02:51 +0200
tracing: Reset iterator in t_start()
The iterator is m->private, but it's not reset to trace_types in
t_start(). If the output is larger than PAGE_SIZE and t_start()
is called the 2nd time, things will go wrong.
Reviewed-by: Liming Wang <liming.wang@windriver.com>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <4A418728.5020506@cn.fujitsu.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
kernel/trace/trace.c | 18 ++++--------------
1 files changed, 4 insertions(+), 14 deletions(-)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 076fa6f..3bb3100 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -2053,25 +2053,23 @@ static int tracing_open(struct inode *inode, struct file *file)
static void *
t_next(struct seq_file *m, void *v, loff_t *pos)
{
- struct tracer *t = m->private;
+ struct tracer *t = v;
(*pos)++;
if (t)
t = t->next;
- m->private = t;
-
return t;
}
static void *t_start(struct seq_file *m, loff_t *pos)
{
- struct tracer *t = m->private;
+ struct tracer *t;
loff_t l = 0;
mutex_lock(&trace_types_lock);
- for (; t && l < *pos; t = t_next(m, t, &l))
+ for (t = trace_types; t && l < *pos; t = t_next(m, t, &l))
;
return t;
@@ -2107,18 +2105,10 @@ static struct seq_operations show_traces_seq_ops = {
static int show_traces_open(struct inode *inode, struct file *file)
{
- int ret;
-
if (tracing_disabled)
return -ENODEV;
- ret = seq_open(file, &show_traces_seq_ops);
- if (!ret) {
- struct seq_file *m = file->private_data;
- m->private = trace_types;
- }
-
- return ret;
+ return seq_open(file, &show_traces_seq_ops);
}
static ssize_t
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 5/7] ftrace: don't increment @pos in g_start()
2009-06-24 1:52 [PATCH 0/7] tracing: seqfile fixes, take 2 Li Zefan
` (3 preceding siblings ...)
2009-06-24 1:53 ` [PATCH 4/7] tracing: reset iterator in t_start() Li Zefan
@ 2009-06-24 1:54 ` Li Zefan
2009-06-24 9:46 ` [tip:tracing/urgent] ftrace: Don't " tip-bot for Li Zefan
2009-06-24 1:54 ` [PATCH 6/7] ftrace: don't manipulate @pos in t_start() Li Zefan
` (2 subsequent siblings)
7 siblings, 1 reply; 16+ messages in thread
From: Li Zefan @ 2009-06-24 1:54 UTC (permalink / raw)
To: Ingo Molnar; +Cc: Steven Rostedt, Frederic Weisbecker, Liming Wang, LKML
It's wrong to increment @pos in g_start(). It causes some entries
lost when reading set_graph_function, if the output of the file
is large than PAGE_SIZE.
[ Impact: fix missing entries when reading set_graph_function ]
Reviewed-by: Liming Wang <liming.wang@windriver.com>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
---
kernel/trace/ftrace.c | 21 ++++++++++-----------
1 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 561cafc..c06e9ab 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -2499,32 +2499,31 @@ int ftrace_graph_count;
unsigned long ftrace_graph_funcs[FTRACE_GRAPH_MAX_FUNCS] __read_mostly;
static void *
-g_next(struct seq_file *m, void *v, loff_t *pos)
+__g_next(struct seq_file *m, loff_t *pos)
{
unsigned long *array = m->private;
- int index = *pos;
-
- (*pos)++;
- if (index >= ftrace_graph_count)
+ if (*pos >= ftrace_graph_count)
return NULL;
+ return &array[*pos];
+}
- return &array[index];
+static void *
+g_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ (*pos)++;
+ return __g_next(m, pos);
}
static void *g_start(struct seq_file *m, loff_t *pos)
{
- void *p = NULL;
-
mutex_lock(&graph_lock);
/* Nothing, tell g_show to print all functions are enabled */
if (!ftrace_graph_count && !*pos)
return (void *)1;
- p = g_next(m, p, pos);
-
- return p;
+ return __g_next(m, pos);
}
static void g_stop(struct seq_file *m, void *p)
--
1.5.4.rc3
^ permalink raw reply related [flat|nested] 16+ messages in thread* [tip:tracing/urgent] ftrace: Don't increment @pos in g_start()
2009-06-24 1:54 ` [PATCH 5/7] ftrace: don't increment @pos in g_start() Li Zefan
@ 2009-06-24 9:46 ` tip-bot for Li Zefan
0 siblings, 0 replies; 16+ messages in thread
From: tip-bot for Li Zefan @ 2009-06-24 9:46 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, hpa, mingo, lizf, fweisbec, rostedt, tglx,
liming.wang, mingo
Commit-ID: 85951842a1020669f0a9eb0f0d1853b41341f097
Gitweb: http://git.kernel.org/tip/85951842a1020669f0a9eb0f0d1853b41341f097
Author: Li Zefan <lizf@cn.fujitsu.com>
AuthorDate: Wed, 24 Jun 2009 09:54:00 +0800
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Wed, 24 Jun 2009 11:02:52 +0200
ftrace: Don't increment @pos in g_start()
It's wrong to increment @pos in g_start(). It causes some entries
lost when reading set_graph_function, if the output of the file
is larger than PAGE_SIZE.
Reviewed-by: Liming Wang <liming.wang@windriver.com>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <4A418738.7090401@cn.fujitsu.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
kernel/trace/ftrace.c | 21 ++++++++++-----------
1 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 3718d55..cde74b9 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -2500,32 +2500,31 @@ int ftrace_graph_count;
unsigned long ftrace_graph_funcs[FTRACE_GRAPH_MAX_FUNCS] __read_mostly;
static void *
-g_next(struct seq_file *m, void *v, loff_t *pos)
+__g_next(struct seq_file *m, loff_t *pos)
{
unsigned long *array = m->private;
- int index = *pos;
-
- (*pos)++;
- if (index >= ftrace_graph_count)
+ if (*pos >= ftrace_graph_count)
return NULL;
+ return &array[*pos];
+}
- return &array[index];
+static void *
+g_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ (*pos)++;
+ return __g_next(m, pos);
}
static void *g_start(struct seq_file *m, loff_t *pos)
{
- void *p = NULL;
-
mutex_lock(&graph_lock);
/* Nothing, tell g_show to print all functions are enabled */
if (!ftrace_graph_count && !*pos)
return (void *)1;
- p = g_next(m, p, pos);
-
- return p;
+ return __g_next(m, pos);
}
static void g_stop(struct seq_file *m, void *p)
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 6/7] ftrace: don't manipulate @pos in t_start()
2009-06-24 1:52 [PATCH 0/7] tracing: seqfile fixes, take 2 Li Zefan
` (4 preceding siblings ...)
2009-06-24 1:54 ` [PATCH 5/7] ftrace: don't increment @pos in g_start() Li Zefan
@ 2009-06-24 1:54 ` Li Zefan
2009-06-24 9:46 ` [tip:tracing/urgent] ftrace: Don't " tip-bot for Li Zefan
2009-06-24 1:54 ` [PATCH 7/7] ftrace: fix t_hash_start() Li Zefan
2009-06-24 9:03 ` [PATCH 0/7] tracing: seqfile fixes, take 2 Ingo Molnar
7 siblings, 1 reply; 16+ messages in thread
From: Li Zefan @ 2009-06-24 1:54 UTC (permalink / raw)
To: Ingo Molnar; +Cc: Steven Rostedt, Frederic Weisbecker, Liming Wang, LKML
It's rather confusing that in t_start(), in some cases @pos is
incremented, and in some cases it's decremented and then incremented.
This patch rewrites t_start() in a much more general way.
Thus we fix a bug that if ftrace_filtered == 1, functions have tracer
hooks won't be printed, because the branch is always unreachable:
static void *t_start(...)
{
...
if (!p)
return t_hash_start(m, pos);
return p;
}
Before:
# echo 'sys_open' > /mnt/tracing/set_ftrace_filter
# echo 'sys_write:traceon:4' >> /mnt/tracing/set_ftrace_filter
sys_open
After:
# echo 'sys_open' > /mnt/tracing/set_ftrace_filter
# echo 'sys_write:traceon:4' >> /mnt/tracing/set_ftrace_filter
sys_open
sys_write:traceon:count=4
[ Impact: show selected functions when filter is on ]
Reviewed-by: Liming Wang <liming.wang@windriver.com>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
---
kernel/trace/ftrace.c | 19 ++++++++-----------
1 files changed, 8 insertions(+), 11 deletions(-)
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index c06e9ab..7946938 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -1466,8 +1466,6 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
iter->pg = iter->pg->next;
iter->idx = 0;
goto retry;
- } else {
- iter->idx = -1;
}
} else {
rec = &iter->pg->records[iter->idx++];
@@ -1496,6 +1494,7 @@ static void *t_start(struct seq_file *m, loff_t *pos)
{
struct ftrace_iterator *iter = m->private;
void *p = NULL;
+ loff_t l;
mutex_lock(&ftrace_lock);
/*
@@ -1507,23 +1506,21 @@ static void *t_start(struct seq_file *m, loff_t *pos)
if (*pos > 0)
return t_hash_start(m, pos);
iter->flags |= FTRACE_ITER_PRINTALL;
- (*pos)++;
return iter;
}
if (iter->flags & FTRACE_ITER_HASH)
return t_hash_start(m, pos);
- if (*pos > 0) {
- if (iter->idx < 0)
- return p;
- (*pos)--;
- iter->idx--;
+ iter->pg = ftrace_pages_start;
+ iter->idx = 0;
+ for (l = 0; l <= *pos; ) {
+ p = t_next(m, p, &l);
+ if (!p)
+ break;
}
- p = t_next(m, p, pos);
-
- if (!p)
+ if (!p && iter->flags & FTRACE_ITER_FILTER)
return t_hash_start(m, pos);
return p;
--
1.5.4.rc3
^ permalink raw reply related [flat|nested] 16+ messages in thread* [tip:tracing/urgent] ftrace: Don't manipulate @pos in t_start()
2009-06-24 1:54 ` [PATCH 6/7] ftrace: don't manipulate @pos in t_start() Li Zefan
@ 2009-06-24 9:46 ` tip-bot for Li Zefan
0 siblings, 0 replies; 16+ messages in thread
From: tip-bot for Li Zefan @ 2009-06-24 9:46 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, hpa, mingo, lizf, fweisbec, rostedt, tglx,
liming.wang, mingo
Commit-ID: 694ce0a544fba37a60025a6803ee6265be8a2a22
Gitweb: http://git.kernel.org/tip/694ce0a544fba37a60025a6803ee6265be8a2a22
Author: Li Zefan <lizf@cn.fujitsu.com>
AuthorDate: Wed, 24 Jun 2009 09:54:19 +0800
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Wed, 24 Jun 2009 11:02:53 +0200
ftrace: Don't manipulate @pos in t_start()
It's rather confusing that in t_start(), in some cases @pos is
incremented, and in some cases it's decremented and then incremented.
This patch rewrites t_start() in a much more general way.
Thus we fix a bug that if ftrace_filtered == 1, functions have tracer
hooks won't be printed, because the branch is always unreachable:
static void *t_start(...)
{
...
if (!p)
return t_hash_start(m, pos);
return p;
}
Before:
# echo 'sys_open' > /mnt/tracing/set_ftrace_filter
# echo 'sys_write:traceon:4' >> /mnt/tracing/set_ftrace_filter
sys_open
After:
# echo 'sys_open' > /mnt/tracing/set_ftrace_filter
# echo 'sys_write:traceon:4' >> /mnt/tracing/set_ftrace_filter
sys_open
sys_write:traceon:count=4
Reviewed-by: Liming Wang <liming.wang@windriver.com>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <4A41874B.4090507@cn.fujitsu.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
kernel/trace/ftrace.c | 19 ++++++++-----------
1 files changed, 8 insertions(+), 11 deletions(-)
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index cde74b9..dc81020 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -1467,8 +1467,6 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
iter->pg = iter->pg->next;
iter->idx = 0;
goto retry;
- } else {
- iter->idx = -1;
}
} else {
rec = &iter->pg->records[iter->idx++];
@@ -1497,6 +1495,7 @@ static void *t_start(struct seq_file *m, loff_t *pos)
{
struct ftrace_iterator *iter = m->private;
void *p = NULL;
+ loff_t l;
mutex_lock(&ftrace_lock);
/*
@@ -1508,23 +1507,21 @@ static void *t_start(struct seq_file *m, loff_t *pos)
if (*pos > 0)
return t_hash_start(m, pos);
iter->flags |= FTRACE_ITER_PRINTALL;
- (*pos)++;
return iter;
}
if (iter->flags & FTRACE_ITER_HASH)
return t_hash_start(m, pos);
- if (*pos > 0) {
- if (iter->idx < 0)
- return p;
- (*pos)--;
- iter->idx--;
+ iter->pg = ftrace_pages_start;
+ iter->idx = 0;
+ for (l = 0; l <= *pos; ) {
+ p = t_next(m, p, &l);
+ if (!p)
+ break;
}
- p = t_next(m, p, pos);
-
- if (!p)
+ if (!p && iter->flags & FTRACE_ITER_FILTER)
return t_hash_start(m, pos);
return p;
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 7/7] ftrace: fix t_hash_start()
2009-06-24 1:52 [PATCH 0/7] tracing: seqfile fixes, take 2 Li Zefan
` (5 preceding siblings ...)
2009-06-24 1:54 ` [PATCH 6/7] ftrace: don't manipulate @pos in t_start() Li Zefan
@ 2009-06-24 1:54 ` Li Zefan
2009-06-24 9:46 ` [tip:tracing/urgent] ftrace: Fix t_hash_start() tip-bot for Li Zefan
2009-06-24 9:03 ` [PATCH 0/7] tracing: seqfile fixes, take 2 Ingo Molnar
7 siblings, 1 reply; 16+ messages in thread
From: Li Zefan @ 2009-06-24 1:54 UTC (permalink / raw)
To: Ingo Molnar; +Cc: Steven Rostedt, Frederic Weisbecker, Liming Wang, LKML
When the output of set_ftrace_filter is larger than PAGE_SIZE,
t_hash_start() will be called the 2nd time, and then we start
from the head of a hlist, which is wrong and causes some entries
to be outputed twice.
The worse is, if the hlist is large enough, reading set_ftrace_filter
won't stop but in a dead loop.
[ Impact: fix output of set_ftrace_filter for selected functions ]
Reviewed-by: Liming Wang <liming.wang@windriver.com>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
---
kernel/trace/ftrace.c | 12 +++++++++++-
1 files changed, 11 insertions(+), 1 deletions(-)
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 7946938..5771cc1 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -1416,10 +1416,20 @@ static void *t_hash_start(struct seq_file *m, loff_t *pos)
{
struct ftrace_iterator *iter = m->private;
void *p = NULL;
+ loff_t l;
+
+ if (!(iter->flags & FTRACE_ITER_HASH))
+ *pos = 0;
iter->flags |= FTRACE_ITER_HASH;
- return t_hash_next(m, p, pos);
+ iter->hidx = 0;
+ for (l = 0; l <= *pos; ) {
+ p = t_hash_next(m, p, &l);
+ if (!p)
+ break;
+ }
+ return p;
}
static int t_hash_show(struct seq_file *m, void *v)
--
1.5.4.rc3
^ permalink raw reply related [flat|nested] 16+ messages in thread* [tip:tracing/urgent] ftrace: Fix t_hash_start()
2009-06-24 1:54 ` [PATCH 7/7] ftrace: fix t_hash_start() Li Zefan
@ 2009-06-24 9:46 ` tip-bot for Li Zefan
0 siblings, 0 replies; 16+ messages in thread
From: tip-bot for Li Zefan @ 2009-06-24 9:46 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, hpa, mingo, lizf, fweisbec, rostedt, tglx,
liming.wang, mingo
Commit-ID: d82d62444f87e5993af2fa82ed636b2206e052ea
Gitweb: http://git.kernel.org/tip/d82d62444f87e5993af2fa82ed636b2206e052ea
Author: Li Zefan <lizf@cn.fujitsu.com>
AuthorDate: Wed, 24 Jun 2009 09:54:54 +0800
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Wed, 24 Jun 2009 11:02:53 +0200
ftrace: Fix t_hash_start()
When the output of set_ftrace_filter is larger than PAGE_SIZE,
t_hash_start() will be called the 2nd time, and then we start
from the head of a hlist, which is wrong and causes some entries
to be outputed twice.
The worse is, if the hlist is large enough, reading set_ftrace_filter
won't stop but in a dead loop.
Reviewed-by: Liming Wang <liming.wang@windriver.com>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <4A41876E.2060407@cn.fujitsu.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
kernel/trace/ftrace.c | 12 +++++++++++-
1 files changed, 11 insertions(+), 1 deletions(-)
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index dc81020..71a52c1 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -1417,10 +1417,20 @@ static void *t_hash_start(struct seq_file *m, loff_t *pos)
{
struct ftrace_iterator *iter = m->private;
void *p = NULL;
+ loff_t l;
+
+ if (!(iter->flags & FTRACE_ITER_HASH))
+ *pos = 0;
iter->flags |= FTRACE_ITER_HASH;
- return t_hash_next(m, p, pos);
+ iter->hidx = 0;
+ for (l = 0; l <= *pos; ) {
+ p = t_hash_next(m, p, &l);
+ if (!p)
+ break;
+ }
+ return p;
}
static int t_hash_show(struct seq_file *m, void *v)
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH 0/7] tracing: seqfile fixes, take 2
2009-06-24 1:52 [PATCH 0/7] tracing: seqfile fixes, take 2 Li Zefan
` (6 preceding siblings ...)
2009-06-24 1:54 ` [PATCH 7/7] ftrace: fix t_hash_start() Li Zefan
@ 2009-06-24 9:03 ` Ingo Molnar
7 siblings, 0 replies; 16+ messages in thread
From: Ingo Molnar @ 2009-06-24 9:03 UTC (permalink / raw)
To: Li Zefan; +Cc: Steven Rostedt, Frederic Weisbecker, Liming Wang, LKML
* Li Zefan <lizf@cn.fujitsu.com> wrote:
> While testing syscall tracepoints proposed by Jason, I found some
> entries were missing when reading available_events.
>
> It turned out there's bug in seqfile handling. The bug is, it's
> wrong to increment @pos in seq start().
>
> The bug exists in some other places. I also fixed some other different
> bugs.
>
> All the patches have been reviewed and tested.
>
> Thanks Liming Wang for the review.
>
> [PATCH 1/7] tracing/events: don't increment @pos in s_start()
> [PATCH 2/7] tracing_bprintk: don't increment @pos in t_start()
> [PATCH 3/7] trace_stat: don't increment @pos in seq start()
> [PATCH 4/7] tracing: reset iterator in t_start()
> [PATCH 5/7] ftrace: don't increment @pos in g_start()
> [PATCH 6/7] ftrace: don't manipulate @pos in t_start()
> [PATCH 7/7] ftrace: fix t_hash_start()
> ---
> kernel/trace/ftrace.c | 52 ++++++++++++++++++++++++-------------------
> kernel/trace/trace.c | 18 +++-----------
> kernel/trace/trace_events.c | 28 ++++++++++++++++++-----
> kernel/trace/trace_printk.c | 26 +++++----------------
> kernel/trace/trace_stat.c | 6 +----
> 5 files changed, 62 insertions(+), 68 deletions(-)
Applied to tip:tracing/urgent, thanks a lot!
Ingo
^ permalink raw reply [flat|nested] 16+ messages in thread