All of lore.kernel.org
 help / color / mirror / Atom feed
From: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
To: Oleg Nesterov <oleg@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>,
	Frederic Weisbecker <fweisbec@gmail.com>,
	Ingo Molnar <mingo@redhat.com>,
	Srikar Dronamraju <srikar@linux.vnet.ibm.com>,
	"zhangwei(Jovi)" <jovi.zhangwei@huawei.com>,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH 3/3] tracing/kprobes: Turn trace_probe->files into list_head
Date: Mon, 17 Jun 2013 15:20:17 +0900	[thread overview]
Message-ID: <51BEAAA1.20806@hitachi.com> (raw)
In-Reply-To: <20130616172152.GA8543@redhat.com>

(2013/06/17 2:21), Oleg Nesterov wrote:
> I think that "ftrace_event_file *trace_probe[]" complicates the
> code for no reason, turn it into list_head to simplify the code.
> enable_trace_probe() no longer needs synchronize_sched().

Looks cleaner :)

> 
> This needs the extra sizeof(list_head) memory for every attached
> ftrace_event_file, hopefully not a problem in this case.

I think it's no problem, because the number depends on the instances
and it could not be so much. :)

Thanks!

Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>

> 
> Signed-off-by: Oleg Nesterov <oleg@redhat.com>
> ---
>  kernel/trace/trace_kprobe.c |  138 ++++++++++++-------------------------------
>  1 files changed, 37 insertions(+), 101 deletions(-)
> 
> diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
> index 5a73de0..b95f683 100644
> --- a/kernel/trace/trace_kprobe.c
> +++ b/kernel/trace/trace_kprobe.c
> @@ -35,12 +35,17 @@ struct trace_probe {
>  	const char		*symbol;	/* symbol name */
>  	struct ftrace_event_class	class;
>  	struct ftrace_event_call	call;
> -	struct ftrace_event_file * __rcu *files;
> +	struct list_head	files;
>  	ssize_t			size;		/* trace entry size */
>  	unsigned int		nr_args;
>  	struct probe_arg	args[];
>  };
>  
> +struct event_file_link {
> +	struct ftrace_event_file	*file;
> +	struct list_head		list;
> +};
> +
>  #define SIZEOF_TRACE_PROBE(n)			\
>  	(offsetof(struct trace_probe, args) +	\
>  	(sizeof(struct probe_arg) * (n)))
> @@ -150,6 +155,7 @@ static struct trace_probe *alloc_trace_probe(const char *group,
>  		goto error;
>  
>  	INIT_LIST_HEAD(&tp->list);
> +	INIT_LIST_HEAD(&tp->files);
>  	return tp;
>  error:
>  	kfree(tp->call.name);
> @@ -184,22 +190,6 @@ static struct trace_probe *find_trace_probe(const char *event,
>  }
>  
>  /*
> - * This and enable_trace_probe/disable_trace_probe rely on event_mutex
> - * held by the caller, __ftrace_set_clr_event().
> - */
> -static int trace_probe_nr_files(struct trace_probe *tp)
> -{
> -	struct ftrace_event_file **file = rcu_dereference_raw(tp->files);
> -	int ret = 0;
> -
> -	if (file)
> -		while (*(file++))
> -			ret++;
> -
> -	return ret;
> -}
> -
> -/*
>   * Enable trace_probe
>   * if the file is NULL, enable "perf" handler, or enable "trace" handler.
>   */
> @@ -209,29 +199,18 @@ enable_trace_probe(struct trace_probe *tp, struct ftrace_event_file *file)
>  	int ret = 0;
>  
>  	if (file) {
> -		struct ftrace_event_file **new, **old;
> -		int n = trace_probe_nr_files(tp);
> -
> -		old = rcu_dereference_raw(tp->files);
> -		/* 1 is for new one and 1 is for stopper */
> -		new = kzalloc((n + 2) * sizeof(struct ftrace_event_file *),
> -			      GFP_KERNEL);
> -		if (!new) {
> +		struct event_file_link *link;
> +
> +		link = kmalloc(sizeof(*link), GFP_KERNEL);
> +		if (!link) {
>  			ret = -ENOMEM;
>  			goto out;
>  		}
> -		memcpy(new, old, n * sizeof(struct ftrace_event_file *));
> -		new[n] = file;
> -		/* The last one keeps a NULL */
>  
> -		rcu_assign_pointer(tp->files, new);
> -		tp->flags |= TP_FLAG_TRACE;
> +		link->file = file;
> +		list_add_rcu(&link->list, &tp->files);
>  
> -		if (old) {
> -			/* Make sure the probe is done with old files */
> -			synchronize_sched();
> -			kfree(old);
> -		}
> +		tp->flags |= TP_FLAG_TRACE;
>  	} else
>  		tp->flags |= TP_FLAG_PROFILE;
>  
> @@ -246,24 +225,16 @@ enable_trace_probe(struct trace_probe *tp, struct ftrace_event_file *file)
>  	return ret;
>  }
>  
> -static int
> -trace_probe_file_index(struct trace_probe *tp, struct ftrace_event_file *file)
> +static struct event_file_link *
> +find_event_file_link(struct trace_probe *tp, struct ftrace_event_file *file)
>  {
> -	struct ftrace_event_file **files;
> -	int i;
> +	struct event_file_link *link;
>  
> -	/*
> -	 * Since all tp->files updater is protected by probe_enable_lock,
> -	 * we don't need to lock an rcu_read_lock.
> -	 */
> -	files = rcu_dereference_raw(tp->files);
> -	if (files) {
> -		for (i = 0; files[i]; i++)
> -			if (files[i] == file)
> -				return i;
> -	}
> +	list_for_each_entry(link, &tp->files, list)
> +		if (link->file == file)
> +			return link;
>  
> -	return -1;
> +	return NULL;
>  }
>  
>  /*
> @@ -276,38 +247,23 @@ disable_trace_probe(struct trace_probe *tp, struct ftrace_event_file *file)
>  	int ret = 0;
>  
>  	if (file) {
> -		struct ftrace_event_file **new, **old;
> -		int n = trace_probe_nr_files(tp);
> -		int i, j;
> +		struct event_file_link *link;
>  
> -		old = rcu_dereference_raw(tp->files);
> -		if (n == 0 || trace_probe_file_index(tp, file) < 0) {
> +		link = find_event_file_link(tp, file);
> +		if (!link) {
>  			ret = -EINVAL;
>  			goto out;
>  		}
>  
> -		if (n == 1) {	/* Remove the last file */
> -			tp->flags &= ~TP_FLAG_TRACE;
> -			new = NULL;
> -		} else {
> -			new = kzalloc(n * sizeof(struct ftrace_event_file *),
> -				      GFP_KERNEL);
> -			if (!new) {
> -				ret = -ENOMEM;
> -				goto out;
> -			}
> -
> -			/* This copy & check loop copies the NULL stopper too */
> -			for (i = 0, j = 0; j < n && i < n + 1; i++)
> -				if (old[i] != file)
> -					new[j++] = old[i];
> -		}
> +		list_del_rcu(&link->list);
> +		/* synchronize with kprobe_trace_func/kretprobe_trace_func */
> +		synchronize_sched();
> +		kfree(link);
>  
> -		rcu_assign_pointer(tp->files, new);
> +		if (!list_empty(&tp->files))
> +			goto out;
>  
> -		/* Make sure the probe is done with old files */
> -		synchronize_sched();
> -		kfree(old);
> +		tp->flags &= ~TP_FLAG_TRACE;
>  	} else
>  		tp->flags &= ~TP_FLAG_PROFILE;
>  
> @@ -872,20 +828,10 @@ __kprobe_trace_func(struct trace_probe *tp, struct pt_regs *regs,
>  static __kprobes void
>  kprobe_trace_func(struct trace_probe *tp, struct pt_regs *regs)
>  {
> -	/*
> -	 * Note: preempt is already disabled around the kprobe handler.
> -	 * However, we still need an smp_read_barrier_depends() corresponding
> -	 * to smp_wmb() in rcu_assign_pointer() to access the pointer.
> -	 */
> -	struct ftrace_event_file **file = rcu_dereference_raw(tp->files);
> -
> -	if (unlikely(!file))
> -		return;
> +	struct event_file_link *link;
>  
> -	while (*file) {
> -		__kprobe_trace_func(tp, regs, *file);
> -		file++;
> -	}
> +	list_for_each_entry_rcu(link, &tp->files, list)
> +		__kprobe_trace_func(tp, regs, link->file);
>  }
>  
>  /* Kretprobe handler */
> @@ -932,20 +878,10 @@ static __kprobes void
>  kretprobe_trace_func(struct trace_probe *tp, struct kretprobe_instance *ri,
>  		     struct pt_regs *regs)
>  {
> -	/*
> -	 * Note: preempt is already disabled around the kprobe handler.
> -	 * However, we still need an smp_read_barrier_depends() corresponding
> -	 * to smp_wmb() in rcu_assign_pointer() to access the pointer.
> -	 */
> -	struct ftrace_event_file **file = rcu_dereference_raw(tp->files);
> -
> -	if (unlikely(!file))
> -		return;
> +	struct event_file_link *link;
>  
> -	while (*file) {
> -		__kretprobe_trace_func(tp, ri, regs, *file);
> -		file++;
> -	}
> +	list_for_each_entry_rcu(link, &tp->files, list)
> +		__kretprobe_trace_func(tp, ri, regs, link->file);
>  }
>  
>  /* Event entry printers */
> 


-- 
Masami HIRAMATSU
IT Management Research Dept. Linux Technology Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: masami.hiramatsu.pt@hitachi.com



  reply	other threads:[~2013-06-17  6:20 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-16 17:21 [PATCH 0/3] tracing/kprobes: trace_probe->files cleanups Oleg Nesterov
2013-06-16 17:21 ` [PATCH 1/3] tracing/kprobes: Avoid perf_trace_buf_*() if ->perf_events is empty Oleg Nesterov
2013-06-17  3:41   ` zhangwei(Jovi)
2013-06-17 13:48     ` Oleg Nesterov
2013-06-17  4:33   ` Masami Hiramatsu
2013-06-16 17:21 ` [PATCH 2/3] tracing/kprobes: Kill probe_enable_lock Oleg Nesterov
2013-06-17  4:59   ` Masami Hiramatsu
2013-06-17 15:18     ` Oleg Nesterov
2013-06-18  2:49       ` Masami Hiramatsu
2013-06-18  3:41       ` Masami Hiramatsu
2013-06-18 19:24         ` Oleg Nesterov
2013-06-19 20:30           ` [PATCH v2 " Oleg Nesterov
2013-06-19 20:34             ` [PATCH] tracing/kprobes: Don't pass addr=ip to perf_trace_buf_submit() Oleg Nesterov
2013-06-20  3:54               ` Masami Hiramatsu
2013-06-20  3:35             ` [PATCH v2 2/3] tracing/kprobes: Kill probe_enable_lock Masami Hiramatsu
2013-06-16 17:21 ` [PATCH 3/3] tracing/kprobes: Turn trace_probe->files into list_head Oleg Nesterov
2013-06-17  6:20   ` Masami Hiramatsu [this message]
2013-06-17 15:30     ` Oleg Nesterov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=51BEAAA1.20806@hitachi.com \
    --to=masami.hiramatsu.pt@hitachi.com \
    --cc=fweisbec@gmail.com \
    --cc=jovi.zhangwei@huawei.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=oleg@redhat.com \
    --cc=rostedt@goodmis.org \
    --cc=srikar@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.