From: Frederic Weisbecker <fweisbec@gmail.com>
To: Jason Baron <jbaron@redhat.com>
Cc: linux-kernel@vger.kernel.org, mingo@elte.hu,
laijs@cn.fujitsu.com, rostedt@goodmis.org, peterz@infradead.org,
mathieu.desnoyers@polymtl.ca, jiayingz@google.com,
mbligh@google.com, lizf@cn.fujitsu.com
Subject: Re: [PATCH 10/12] add perf counter support
Date: Tue, 11 Aug 2009 14:12:28 +0200 [thread overview]
Message-ID: <20090811121227.GF4938@nowhere> (raw)
In-Reply-To: <b9d3c5f9d0ff2fb71993530873807443a0c7eb64.1249932670.git.jbaron@redhat.com>
On Mon, Aug 10, 2009 at 04:53:02PM -0400, Jason Baron wrote:
> Make 'perf stat -e syscalls:sys_enter_blah' work with syscall style tracepoints.
It would be nice to also be able to type:
perf stat -e syscalls:blah
and then having both enter/exit counters.
Frederic.
>
> Signed-off-by: Jason Baron <jbaron@redhat.com>
>
> ---
> include/linux/perf_counter.h | 2 +
> include/linux/syscalls.h | 52 +++++++++++++++++-
> include/trace/syscall.h | 7 +++
> kernel/trace/trace_syscalls.c | 121 +++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 181 insertions(+), 1 deletions(-)
>
> diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h
> index c484834..aaf0c74 100644
> --- a/include/linux/perf_counter.h
> +++ b/include/linux/perf_counter.h
> @@ -734,6 +734,8 @@ extern int sysctl_perf_counter_mlock;
> extern int sysctl_perf_counter_sample_rate;
>
> extern void perf_counter_init(void);
> +extern void perf_tpcounter_event(int event_id, u64 addr, u64 count,
> + void *record, int entry_size);
>
> #ifndef perf_misc_flags
> #define perf_misc_flags(regs) (user_mode(regs) ? PERF_EVENT_MISC_USER : \
> diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
> index ce4b01c..5541e75 100644
> --- a/include/linux/syscalls.h
> +++ b/include/linux/syscalls.h
> @@ -98,6 +98,53 @@ struct perf_counter_attr;
> #define __SC_TEST5(t5, a5, ...) __SC_TEST(t5); __SC_TEST4(__VA_ARGS__)
> #define __SC_TEST6(t6, a6, ...) __SC_TEST(t6); __SC_TEST5(__VA_ARGS__)
>
> +#ifdef CONFIG_EVENT_PROFILE
> +#define TRACE_SYS_ENTER_PROFILE(sname) \
> +static int prof_sysenter_enable_##sname(struct ftrace_event_call *event_call) \
> +{ \
> + int ret = 0; \
> + if (!atomic_inc_return(&event_enter_##sname.profile_count)) \
> + ret = reg_prof_syscall_enter("sys"#sname); \
> + return ret; \
> +} \
> + \
> +static void prof_sysenter_disable_##sname(struct ftrace_event_call *event_call)\
> +{ \
> + if (atomic_add_negative(-1, &event_enter_##sname.profile_count)) \
> + unreg_prof_syscall_enter("sys"#sname); \
> +}
> +
> +#define TRACE_SYS_EXIT_PROFILE(sname) \
> +static int prof_sysexit_enable_##sname(struct ftrace_event_call *event_call) \
> +{ \
> + int ret = 0; \
> + if (!atomic_inc_return(&event_exit_##sname.profile_count)) \
> + ret = reg_prof_syscall_exit("sys"#sname); \
> + return ret; \
> +} \
> + \
> +static void prof_sysexit_disable_##sname(struct ftrace_event_call *event_call) \
> +{ \
> + if (atomic_add_negative(-1, &event_exit_##sname.profile_count)) \
> + unreg_prof_syscall_exit("sys"#sname); \
> +}
> +
> +#define TRACE_SYS_ENTER_PROFILE_INIT(sname) \
> + .profile_count = ATOMIC_INIT(-1), \
> + .profile_enable = prof_sysenter_enable_##sname, \
> + .profile_disable = prof_sysenter_disable_##sname,
> +
> +#define TRACE_SYS_EXIT_PROFILE_INIT(sname) \
> + .profile_count = ATOMIC_INIT(-1), \
> + .profile_enable = prof_sysexit_enable_##sname, \
> + .profile_disable = prof_sysexit_disable_##sname,
> +#else
> +#define TRACE_SYS_ENTER_PROFILE(sname)
> +#define TRACE_SYS_ENTER_PROFILE_INIT(sname)
> +#define TRACE_SYS_EXIT_PROFILE(sname)
> +#define TRACE_SYS_EXIT_PROFILE_INIT(sname)
> +#endif
> +
> #ifdef CONFIG_FTRACE_SYSCALLS
> #define __SC_STR_ADECL1(t, a) #a
> #define __SC_STR_ADECL2(t, a, ...) #a, __SC_STR_ADECL1(__VA_ARGS__)
> @@ -113,7 +160,6 @@ struct perf_counter_attr;
> #define __SC_STR_TDECL5(t, a, ...) #t, __SC_STR_TDECL4(__VA_ARGS__)
> #define __SC_STR_TDECL6(t, a, ...) #t, __SC_STR_TDECL5(__VA_ARGS__)
>
> -
> #define SYSCALL_TRACE_ENTER_EVENT(sname) \
> static struct ftrace_event_call event_enter_##sname; \
> struct trace_event enter_syscall_print_##sname = { \
> @@ -134,6 +180,7 @@ struct perf_counter_attr;
> init_preds(&event_enter_##sname); \
> return 0; \
> } \
> + TRACE_SYS_ENTER_PROFILE(sname); \
> static struct ftrace_event_call __used \
> __attribute__((__aligned__(4))) \
> __attribute__((section("_ftrace_events"))) \
> @@ -145,6 +192,7 @@ struct perf_counter_attr;
> .regfunc = reg_event_syscall_enter, \
> .unregfunc = unreg_event_syscall_enter, \
> .data = "sys"#sname, \
> + TRACE_SYS_ENTER_PROFILE_INIT(sname) \
> }
>
> #define SYSCALL_TRACE_EXIT_EVENT(sname) \
> @@ -167,6 +215,7 @@ struct perf_counter_attr;
> init_preds(&event_exit_##sname); \
> return 0; \
> } \
> + TRACE_SYS_EXIT_PROFILE(sname); \
> static struct ftrace_event_call __used \
> __attribute__((__aligned__(4))) \
> __attribute__((section("_ftrace_events"))) \
> @@ -178,6 +227,7 @@ struct perf_counter_attr;
> .regfunc = reg_event_syscall_exit, \
> .unregfunc = unreg_event_syscall_exit, \
> .data = "sys"#sname, \
> + TRACE_SYS_EXIT_PROFILE_INIT(sname) \
> }
>
> #define SYSCALL_METADATA(sname, nb) \
> diff --git a/include/trace/syscall.h b/include/trace/syscall.h
> index df62840..3ab6dd1 100644
> --- a/include/trace/syscall.h
> +++ b/include/trace/syscall.h
> @@ -58,5 +58,12 @@ extern void unreg_event_syscall_exit(void *ptr);
> enum print_line_t print_syscall_enter(struct trace_iterator *iter, int flags);
> enum print_line_t print_syscall_exit(struct trace_iterator *iter, int flags);
> #endif
> +#ifdef CONFIG_EVENT_PROFILE
> +int reg_prof_syscall_enter(char *name);
> +void unreg_prof_syscall_enter(char *name);
> +int reg_prof_syscall_exit(char *name);
> +void unreg_prof_syscall_exit(char *name);
> +
> +#endif
>
> #endif /* _TRACE_SYSCALL_H */
> diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
> index e58a9c1..f4eaec3 100644
> --- a/kernel/trace/trace_syscalls.c
> +++ b/kernel/trace/trace_syscalls.c
> @@ -1,6 +1,7 @@
> #include <trace/syscall.h>
> #include <linux/kernel.h>
> #include <linux/ftrace.h>
> +#include <linux/perf_counter.h>
> #include <asm/syscall.h>
>
> #include "trace_output.h"
> @@ -252,3 +253,123 @@ struct trace_event event_syscall_enter = {
> struct trace_event event_syscall_exit = {
> .trace = print_syscall_exit,
> };
> +
> +#ifdef CONFIG_EVENT_PROFILE
> +static DECLARE_BITMAP(enabled_prof_enter_syscalls, FTRACE_SYSCALL_MAX);
> +static DECLARE_BITMAP(enabled_prof_exit_syscalls, FTRACE_SYSCALL_MAX);
> +static int sys_prof_refcount_enter;
> +static int sys_prof_refcount_exit;
> +
> +static void prof_syscall_enter(struct pt_regs *regs, long id)
> +{
> + struct syscall_metadata *sys_data;
> + int syscall_nr;
> +
> + syscall_nr = syscall_get_nr(current, regs);
> + if (!test_bit(syscall_nr, enabled_prof_enter_syscalls))
> + return;
> +
> + sys_data = syscall_nr_to_meta(syscall_nr);
> + if (!sys_data)
> + return;
> +
> + perf_tpcounter_event(sys_data->enter_id, 0, 1, NULL, 0);
> +}
> +
> +int reg_prof_syscall_enter(char *name)
> +{
> + int ret = 0;
> + int num;
> +
> + num = syscall_name_to_nr(name);
> + if (num < 0 || num >= FTRACE_SYSCALL_MAX)
> + return -ENOSYS;
> +
> + mutex_lock(&syscall_trace_lock);
> + if (!sys_prof_refcount_enter)
> + ret = register_trace_syscall_enter(prof_syscall_enter);
> + if (ret) {
> + pr_info("event trace: Could not activate"
> + "syscall entry trace point");
> + } else {
> + set_bit(num, enabled_prof_enter_syscalls);
> + sys_prof_refcount_enter++;
> + }
> + mutex_unlock(&syscall_trace_lock);
> + return ret;
> +}
> +
> +void unreg_prof_syscall_enter(char *name)
> +{
> + int num;
> +
> + num = syscall_name_to_nr(name);
> + if (num < 0 || num >= FTRACE_SYSCALL_MAX)
> + return;
> +
> + mutex_lock(&syscall_trace_lock);
> + sys_prof_refcount_enter--;
> + clear_bit(num, enabled_prof_enter_syscalls);
> + if (!sys_prof_refcount_enter)
> + unregister_trace_syscall_enter(prof_syscall_enter);
> + mutex_unlock(&syscall_trace_lock);
> +}
> +
> +static void prof_syscall_exit(struct pt_regs *regs, long ret)
> +{
> + struct syscall_metadata *sys_data;
> + int syscall_nr;
> +
> + syscall_nr = syscall_get_nr(current, regs);
> + if (!test_bit(syscall_nr, enabled_prof_exit_syscalls))
> + return;
> +
> + sys_data = syscall_nr_to_meta(syscall_nr);
> + if (!sys_data)
> + return;
> +
> + perf_tpcounter_event(sys_data->exit_id, 0, 1, NULL, 0);
> +}
> +
> +int reg_prof_syscall_exit(char *name)
> +{
> + int ret = 0;
> + int num;
> +
> + num = syscall_name_to_nr(name);
> + if (num < 0 || num >= FTRACE_SYSCALL_MAX)
> + return -ENOSYS;
> +
> + mutex_lock(&syscall_trace_lock);
> + if (!sys_prof_refcount_exit)
> + ret = register_trace_syscall_exit(prof_syscall_exit);
> + if (ret) {
> + pr_info("event trace: Could not activate"
> + "syscall entry trace point");
> + } else {
> + set_bit(num, enabled_prof_exit_syscalls);
> + sys_prof_refcount_exit++;
> + }
> + mutex_unlock(&syscall_trace_lock);
> + return ret;
> +}
> +
> +void unreg_prof_syscall_exit(char *name)
> +{
> + int num;
> +
> + num = syscall_name_to_nr(name);
> + if (num < 0 || num >= FTRACE_SYSCALL_MAX)
> + return;
> +
> + mutex_lock(&syscall_trace_lock);
> + sys_prof_refcount_exit--;
> + clear_bit(num, enabled_prof_exit_syscalls);
> + if (!sys_prof_refcount_exit)
> + unregister_trace_syscall_exit(prof_syscall_exit);
> + mutex_unlock(&syscall_trace_lock);
> +}
> +
> +#endif
> +
> +
> --
> 1.6.2.5
>
next prev parent reply other threads:[~2009-08-11 12:12 UTC|newest]
Thread overview: 88+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-08-10 20:52 [PATCH 00/12] add syscall tracepoints V3 Jason Baron
2009-08-10 20:52 ` [PATCH 01/12] map syscall name to number Jason Baron
2009-08-10 20:52 ` [PATCH 02/12] call arch_init_ftrace_syscalls at boot Jason Baron
2009-08-10 20:52 ` [PATCH 03/12] add DECLARE_TRACE_WITH_CALLBACK() macro Jason Baron
2009-08-10 20:52 ` [PATCH 04/12] add syscall tracepoints Jason Baron
2009-08-10 20:52 ` [PATCH 05/12] update FTRACE_SYSCALL_MAX Jason Baron
2009-08-11 11:00 ` Frederic Weisbecker
2009-08-11 19:39 ` Matt Fleming
2009-08-24 13:41 ` Paul Mundt
2009-08-24 14:06 ` Jason Baron
2009-08-24 14:15 ` Paul Mundt
2009-08-24 14:34 ` Frederic Weisbecker
2009-08-24 14:37 ` Paul Mundt
2009-08-24 14:42 ` Jason Baron
2009-08-24 14:50 ` Paul Mundt
2009-08-24 18:34 ` Ingo Molnar
2009-08-10 20:52 ` [PATCH 06/12] trace_event - raw_init bailout Jason Baron
2009-08-10 20:52 ` [PATCH 07/12] add ftrace_event_call void * 'data' field Jason Baron
2009-08-11 10:09 ` Frederic Weisbecker
2009-08-17 22:19 ` Steven Rostedt
2009-08-17 23:09 ` Frederic Weisbecker
2009-08-18 0:06 ` Steven Rostedt
2009-08-10 20:52 ` [PATCH 08/12] add trace events for each syscall entry/exit Jason Baron
2009-08-11 10:50 ` Frederic Weisbecker
2009-08-11 11:45 ` Ingo Molnar
2009-08-11 12:01 ` Frederic Weisbecker
2009-08-25 12:50 ` Hendrik Brueckner
2009-08-25 14:15 ` Frederic Weisbecker
2009-08-25 16:02 ` Hendrik Brueckner
2009-08-25 16:20 ` Mathieu Desnoyers
2009-08-25 16:59 ` Frederic Weisbecker
2009-08-25 17:31 ` Frederic Weisbecker
2009-08-25 18:31 ` Mathieu Desnoyers
2009-08-25 19:42 ` Frederic Weisbecker
2009-08-25 19:51 ` Mathieu Desnoyers
2009-08-26 0:19 ` Frederic Weisbecker
2009-08-26 0:42 ` Mathieu Desnoyers
2009-08-26 7:28 ` Ingo Molnar
2009-08-26 17:11 ` Mathieu Desnoyers
2009-08-26 6:48 ` Peter Zijlstra
2009-08-25 22:04 ` Martin Schwidefsky
2009-08-26 7:38 ` Heiko Carstens
2009-08-26 12:32 ` Frederic Weisbecker
2009-08-26 6:21 ` Peter Zijlstra
2009-08-26 17:08 ` Mathieu Desnoyers
2009-08-26 18:41 ` Christoph Hellwig
2009-08-26 18:42 ` Christoph Hellwig
2009-08-26 19:01 ` Mathieu Desnoyers
2009-08-26 7:10 ` Peter Zijlstra
2009-08-26 17:10 ` Mathieu Desnoyers
2009-08-26 17:24 ` H. Peter Anvin
2009-08-25 17:04 ` Jason Baron
2009-08-25 18:15 ` Mathieu Desnoyers
2009-08-26 12:35 ` Frederic Weisbecker
2009-08-26 12:59 ` Heiko Carstens
2009-08-26 13:30 ` Frederic Weisbecker
2009-08-26 13:48 ` Steven Rostedt
2009-08-26 13:53 ` Frederic Weisbecker
2009-08-26 14:44 ` Steven Rostedt
2009-08-26 13:56 ` Peter Zijlstra
2009-08-26 14:41 ` Steven Rostedt
2009-08-26 14:10 ` Heiko Carstens
2009-08-26 14:27 ` Frederic Weisbecker
2009-08-26 14:43 ` Steven Rostedt
2009-08-26 16:14 ` Frederic Weisbecker
2009-08-26 14:43 ` Steven Rostedt
2009-08-26 14:41 ` Hendrik Brueckner
2009-08-28 12:28 ` [tip:tracing/core] tracing: Don't trace kernel thread syscalls tip-bot for Hendrik Brueckner
2009-08-25 21:40 ` [PATCH 08/12] add trace events for each syscall entry/exit Frederic Weisbecker
2009-08-25 22:09 ` Frederic Weisbecker
2009-08-26 7:47 ` Heiko Carstens
2009-08-28 12:27 ` [tip:tracing/core] tracing: Check invalid syscall nr while tracing syscalls tip-bot for Hendrik Brueckner
2009-08-10 20:52 ` [PATCH 09/12] add support traceopint ids Jason Baron
2009-08-11 11:28 ` Frederic Weisbecker
2009-08-10 20:53 ` [PATCH 10/12] add perf counter support Jason Baron
2009-08-11 12:12 ` Frederic Weisbecker [this message]
2009-08-11 12:17 ` Ingo Molnar
2009-08-11 12:25 ` Frederic Weisbecker
2009-08-10 20:53 ` [PATCH 11/12] add more namespace area to 'perf list' output Jason Baron
2009-08-10 20:53 ` [PATCH 12/12] convert x86_64 mmap and uname to use DEFINE_SYSCALL Jason Baron
2009-08-25 12:31 ` [PATCH 00/12] add syscall tracepoints V3 - s390 arch update Hendrik Brueckner
2009-08-25 13:52 ` Frederic Weisbecker
2009-08-25 14:39 ` Heiko Carstens
2009-08-25 19:52 ` Frederic Weisbecker
2009-08-25 15:38 ` Hendrik Brueckner
2009-08-26 16:53 ` Frederic Weisbecker
2009-08-27 7:27 ` [PATCH]: tracing: s390 arch updates for tracing syscalls Hendrik Brueckner
2009-08-28 12:27 ` [tip:tracing/core] tracing: Add syscall tracepoints - s390 arch update tip-bot for Hendrik Brueckner
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=20090811121227.GF4938@nowhere \
--to=fweisbec@gmail.com \
--cc=jbaron@redhat.com \
--cc=jiayingz@google.com \
--cc=laijs@cn.fujitsu.com \
--cc=linux-kernel@vger.kernel.org \
--cc=lizf@cn.fujitsu.com \
--cc=mathieu.desnoyers@polymtl.ca \
--cc=mbligh@google.com \
--cc=mingo@elte.hu \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox