All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.