* [PATCH] tracing/ftrace: fix a memory leak in stat tracing
@ 2009-01-06 20:33 Frederic Weisbecker
2009-01-06 20:43 ` Steven Rostedt
0 siblings, 1 reply; 3+ messages in thread
From: Frederic Weisbecker @ 2009-01-06 20:33 UTC (permalink / raw)
To: Steven Rostedt; +Cc: linux-kernel, mingo
This patch fixes a memory leak inside reset_stat_list(). The freeing
loop iterated only once.
Also turn the stat_list into a simple struct list_head, which
simplify the code and avoid an unused static pointer.
Reported-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
---
diff --git a/kernel/trace/trace_stat.c b/kernel/trace/trace_stat.c
index 6f194a3..4cb4ff2 100644
--- a/kernel/trace/trace_stat.c
+++ b/kernel/trace/trace_stat.c
@@ -21,7 +21,7 @@ struct trace_stat_list {
void *stat;
};
-static struct trace_stat_list stat_list;
+static LIST_HEAD(stat_list);
/*
* This is a copy of the current tracer to avoid racy
@@ -39,22 +39,12 @@ static DEFINE_MUTEX(stat_list_mutex);
static void reset_stat_list(void)
{
- struct trace_stat_list *node;
- struct list_head *next;
+ struct trace_stat_list *node, *next;
- if (list_empty(&stat_list.list))
- return;
-
- node = list_entry(stat_list.list.next, struct trace_stat_list, list);
- next = node->list.next;
-
- while (&node->list != next) {
+ list_for_each_entry_safe(node, next, &stat_list, list)
kfree(node);
- node = list_entry(next, struct trace_stat_list, list);
- }
- kfree(node);
- INIT_LIST_HEAD(&stat_list.list);
+ INIT_LIST_HEAD(&stat_list);
}
void init_tracer_stat(struct tracer *trace)
@@ -107,7 +97,7 @@ static int stat_seq_init(void)
}
INIT_LIST_HEAD(&new_entry->list);
- list_add(&new_entry->list, &stat_list.list);
+ list_add(&new_entry->list, &stat_list);
new_entry->stat = current_tracer.stat_start();
prev_stat = new_entry->stat;
@@ -130,7 +120,7 @@ static int stat_seq_init(void)
if (!new_entry->stat)
break;
- list_for_each_entry(iter_entry, &stat_list.list, list) {
+ list_for_each_entry(iter_entry, &stat_list, list) {
/* Insertion with a descendent sorting */
if (current_tracer.stat_cmp(new_entry->stat,
iter_entry->stat) > 0) {
@@ -141,7 +131,7 @@ static int stat_seq_init(void)
/* The current smaller value */
} else if (list_is_last(&iter_entry->list,
- &stat_list.list)) {
+ &stat_list)) {
list_add(&new_entry->list, &iter_entry->list);
break;
}
@@ -162,7 +152,7 @@ exit_free_list:
static void *stat_seq_start(struct seq_file *s, loff_t *pos)
{
- struct trace_stat_list *l = (struct trace_stat_list *)s->private;
+ struct list_head *l = (struct list_head *)s->private;
/* Prevent from tracer switch or stat_list modification */
mutex_lock(&stat_list_mutex);
@@ -171,14 +161,14 @@ static void *stat_seq_start(struct seq_file *s, loff_t *pos)
if (!*pos && current_tracer.stat_headers)
current_tracer.stat_headers(s);
- return seq_list_start(&l->list, *pos);
+ return seq_list_start(l, *pos);
}
static void *stat_seq_next(struct seq_file *s, void *p, loff_t *pos)
{
- struct trace_stat_list *l = (struct trace_stat_list *)s->private;
+ struct list_head *l = (struct list_head *)s->private;
- return seq_list_next(p, &l->list, pos);
+ return seq_list_next(p, l, pos);
}
static void stat_seq_stop(struct seq_file *m, void *p)
@@ -188,8 +178,10 @@ static void stat_seq_stop(struct seq_file *m, void *p)
static int stat_seq_show(struct seq_file *s, void *v)
{
- struct trace_stat_list *l = list_entry(v, struct trace_stat_list, list);
- return current_tracer.stat_show(s, l->stat);
+ struct trace_stat_list *entry =
+ list_entry(v, struct trace_stat_list, list);
+
+ return current_tracer.stat_show(s, entry->stat);
}
static const struct seq_operations trace_stat_seq_ops = {
@@ -237,7 +229,6 @@ static int __init tracing_stat_init(void)
struct dentry *d_tracing;
struct dentry *entry;
- INIT_LIST_HEAD(&stat_list.list);
d_tracing = tracing_init_dentry();
entry = debugfs_create_file("trace_stat", 0444, d_tracing,
--
1.6.0.4
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] tracing/ftrace: fix a memory leak in stat tracing
2009-01-06 20:33 [PATCH] tracing/ftrace: fix a memory leak in stat tracing Frederic Weisbecker
@ 2009-01-06 20:43 ` Steven Rostedt
2009-01-06 20:54 ` Frederic Weisbecker
0 siblings, 1 reply; 3+ messages in thread
From: Steven Rostedt @ 2009-01-06 20:43 UTC (permalink / raw)
To: Frederic Weisbecker; +Cc: linux-kernel, mingo
Thanks Frederic!
I'll just add an Impact line to this and push it off to Ingo.
The impact line will simply be:
Impact: fix memory leak
-- Steve
On Tue, 6 Jan 2009, Frederic Weisbecker wrote:
> This patch fixes a memory leak inside reset_stat_list(). The freeing
> loop iterated only once.
>
> Also turn the stat_list into a simple struct list_head, which
> simplify the code and avoid an unused static pointer.
>
> Reported-by: Steven Rostedt <rostedt@goodmis.org>
> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
> ---
> diff --git a/kernel/trace/trace_stat.c b/kernel/trace/trace_stat.c
> index 6f194a3..4cb4ff2 100644
> --- a/kernel/trace/trace_stat.c
> +++ b/kernel/trace/trace_stat.c
> @@ -21,7 +21,7 @@ struct trace_stat_list {
> void *stat;
> };
>
> -static struct trace_stat_list stat_list;
> +static LIST_HEAD(stat_list);
>
> /*
> * This is a copy of the current tracer to avoid racy
> @@ -39,22 +39,12 @@ static DEFINE_MUTEX(stat_list_mutex);
>
> static void reset_stat_list(void)
> {
> - struct trace_stat_list *node;
> - struct list_head *next;
> + struct trace_stat_list *node, *next;
>
> - if (list_empty(&stat_list.list))
> - return;
> -
> - node = list_entry(stat_list.list.next, struct trace_stat_list, list);
> - next = node->list.next;
> -
> - while (&node->list != next) {
> + list_for_each_entry_safe(node, next, &stat_list, list)
> kfree(node);
> - node = list_entry(next, struct trace_stat_list, list);
> - }
> - kfree(node);
>
> - INIT_LIST_HEAD(&stat_list.list);
> + INIT_LIST_HEAD(&stat_list);
> }
>
> void init_tracer_stat(struct tracer *trace)
> @@ -107,7 +97,7 @@ static int stat_seq_init(void)
> }
>
> INIT_LIST_HEAD(&new_entry->list);
> - list_add(&new_entry->list, &stat_list.list);
> + list_add(&new_entry->list, &stat_list);
> new_entry->stat = current_tracer.stat_start();
>
> prev_stat = new_entry->stat;
> @@ -130,7 +120,7 @@ static int stat_seq_init(void)
> if (!new_entry->stat)
> break;
>
> - list_for_each_entry(iter_entry, &stat_list.list, list) {
> + list_for_each_entry(iter_entry, &stat_list, list) {
> /* Insertion with a descendent sorting */
> if (current_tracer.stat_cmp(new_entry->stat,
> iter_entry->stat) > 0) {
> @@ -141,7 +131,7 @@ static int stat_seq_init(void)
>
> /* The current smaller value */
> } else if (list_is_last(&iter_entry->list,
> - &stat_list.list)) {
> + &stat_list)) {
> list_add(&new_entry->list, &iter_entry->list);
> break;
> }
> @@ -162,7 +152,7 @@ exit_free_list:
>
> static void *stat_seq_start(struct seq_file *s, loff_t *pos)
> {
> - struct trace_stat_list *l = (struct trace_stat_list *)s->private;
> + struct list_head *l = (struct list_head *)s->private;
>
> /* Prevent from tracer switch or stat_list modification */
> mutex_lock(&stat_list_mutex);
> @@ -171,14 +161,14 @@ static void *stat_seq_start(struct seq_file *s, loff_t *pos)
> if (!*pos && current_tracer.stat_headers)
> current_tracer.stat_headers(s);
>
> - return seq_list_start(&l->list, *pos);
> + return seq_list_start(l, *pos);
> }
>
> static void *stat_seq_next(struct seq_file *s, void *p, loff_t *pos)
> {
> - struct trace_stat_list *l = (struct trace_stat_list *)s->private;
> + struct list_head *l = (struct list_head *)s->private;
>
> - return seq_list_next(p, &l->list, pos);
> + return seq_list_next(p, l, pos);
> }
>
> static void stat_seq_stop(struct seq_file *m, void *p)
> @@ -188,8 +178,10 @@ static void stat_seq_stop(struct seq_file *m, void *p)
>
> static int stat_seq_show(struct seq_file *s, void *v)
> {
> - struct trace_stat_list *l = list_entry(v, struct trace_stat_list, list);
> - return current_tracer.stat_show(s, l->stat);
> + struct trace_stat_list *entry =
> + list_entry(v, struct trace_stat_list, list);
> +
> + return current_tracer.stat_show(s, entry->stat);
> }
>
> static const struct seq_operations trace_stat_seq_ops = {
> @@ -237,7 +229,6 @@ static int __init tracing_stat_init(void)
> struct dentry *d_tracing;
> struct dentry *entry;
>
> - INIT_LIST_HEAD(&stat_list.list);
> d_tracing = tracing_init_dentry();
>
> entry = debugfs_create_file("trace_stat", 0444, d_tracing,
> --
> 1.6.0.4
>
>
>
>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] tracing/ftrace: fix a memory leak in stat tracing
2009-01-06 20:43 ` Steven Rostedt
@ 2009-01-06 20:54 ` Frederic Weisbecker
0 siblings, 0 replies; 3+ messages in thread
From: Frederic Weisbecker @ 2009-01-06 20:54 UTC (permalink / raw)
To: Steven Rostedt; +Cc: linux-kernel, mingo
On Tue, Jan 06, 2009 at 03:43:09PM -0500, Steven Rostedt wrote:
>
> Thanks Frederic!
>
> I'll just add an Impact line to this and push it off to Ingo.
Thanks!
> The impact line will simply be:
>
> Impact: fix memory leak
Yes I wanted to put one similar to yours but I thought it duplicated
the subject line. But you're right I guess that could help those who will grep
git-log on Impact lines.
> -- Steve
>
> On Tue, 6 Jan 2009, Frederic Weisbecker wrote:
>
> > This patch fixes a memory leak inside reset_stat_list(). The freeing
> > loop iterated only once.
> >
> > Also turn the stat_list into a simple struct list_head, which
> > simplify the code and avoid an unused static pointer.
> >
> > Reported-by: Steven Rostedt <rostedt@goodmis.org>
> > Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
> > ---
> > diff --git a/kernel/trace/trace_stat.c b/kernel/trace/trace_stat.c
> > index 6f194a3..4cb4ff2 100644
> > --- a/kernel/trace/trace_stat.c
> > +++ b/kernel/trace/trace_stat.c
> > @@ -21,7 +21,7 @@ struct trace_stat_list {
> > void *stat;
> > };
> >
> > -static struct trace_stat_list stat_list;
> > +static LIST_HEAD(stat_list);
> >
> > /*
> > * This is a copy of the current tracer to avoid racy
> > @@ -39,22 +39,12 @@ static DEFINE_MUTEX(stat_list_mutex);
> >
> > static void reset_stat_list(void)
> > {
> > - struct trace_stat_list *node;
> > - struct list_head *next;
> > + struct trace_stat_list *node, *next;
> >
> > - if (list_empty(&stat_list.list))
> > - return;
> > -
> > - node = list_entry(stat_list.list.next, struct trace_stat_list, list);
> > - next = node->list.next;
> > -
> > - while (&node->list != next) {
> > + list_for_each_entry_safe(node, next, &stat_list, list)
> > kfree(node);
> > - node = list_entry(next, struct trace_stat_list, list);
> > - }
> > - kfree(node);
> >
> > - INIT_LIST_HEAD(&stat_list.list);
> > + INIT_LIST_HEAD(&stat_list);
> > }
> >
> > void init_tracer_stat(struct tracer *trace)
> > @@ -107,7 +97,7 @@ static int stat_seq_init(void)
> > }
> >
> > INIT_LIST_HEAD(&new_entry->list);
> > - list_add(&new_entry->list, &stat_list.list);
> > + list_add(&new_entry->list, &stat_list);
> > new_entry->stat = current_tracer.stat_start();
> >
> > prev_stat = new_entry->stat;
> > @@ -130,7 +120,7 @@ static int stat_seq_init(void)
> > if (!new_entry->stat)
> > break;
> >
> > - list_for_each_entry(iter_entry, &stat_list.list, list) {
> > + list_for_each_entry(iter_entry, &stat_list, list) {
> > /* Insertion with a descendent sorting */
> > if (current_tracer.stat_cmp(new_entry->stat,
> > iter_entry->stat) > 0) {
> > @@ -141,7 +131,7 @@ static int stat_seq_init(void)
> >
> > /* The current smaller value */
> > } else if (list_is_last(&iter_entry->list,
> > - &stat_list.list)) {
> > + &stat_list)) {
> > list_add(&new_entry->list, &iter_entry->list);
> > break;
> > }
> > @@ -162,7 +152,7 @@ exit_free_list:
> >
> > static void *stat_seq_start(struct seq_file *s, loff_t *pos)
> > {
> > - struct trace_stat_list *l = (struct trace_stat_list *)s->private;
> > + struct list_head *l = (struct list_head *)s->private;
> >
> > /* Prevent from tracer switch or stat_list modification */
> > mutex_lock(&stat_list_mutex);
> > @@ -171,14 +161,14 @@ static void *stat_seq_start(struct seq_file *s, loff_t *pos)
> > if (!*pos && current_tracer.stat_headers)
> > current_tracer.stat_headers(s);
> >
> > - return seq_list_start(&l->list, *pos);
> > + return seq_list_start(l, *pos);
> > }
> >
> > static void *stat_seq_next(struct seq_file *s, void *p, loff_t *pos)
> > {
> > - struct trace_stat_list *l = (struct trace_stat_list *)s->private;
> > + struct list_head *l = (struct list_head *)s->private;
> >
> > - return seq_list_next(p, &l->list, pos);
> > + return seq_list_next(p, l, pos);
> > }
> >
> > static void stat_seq_stop(struct seq_file *m, void *p)
> > @@ -188,8 +178,10 @@ static void stat_seq_stop(struct seq_file *m, void *p)
> >
> > static int stat_seq_show(struct seq_file *s, void *v)
> > {
> > - struct trace_stat_list *l = list_entry(v, struct trace_stat_list, list);
> > - return current_tracer.stat_show(s, l->stat);
> > + struct trace_stat_list *entry =
> > + list_entry(v, struct trace_stat_list, list);
> > +
> > + return current_tracer.stat_show(s, entry->stat);
> > }
> >
> > static const struct seq_operations trace_stat_seq_ops = {
> > @@ -237,7 +229,6 @@ static int __init tracing_stat_init(void)
> > struct dentry *d_tracing;
> > struct dentry *entry;
> >
> > - INIT_LIST_HEAD(&stat_list.list);
> > d_tracing = tracing_init_dentry();
> >
> > entry = debugfs_create_file("trace_stat", 0444, d_tracing,
> > --
> > 1.6.0.4
> >
> >
> >
> >
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2009-01-06 20:54 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-01-06 20:33 [PATCH] tracing/ftrace: fix a memory leak in stat tracing Frederic Weisbecker
2009-01-06 20:43 ` Steven Rostedt
2009-01-06 20:54 ` Frederic Weisbecker
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.