From: Andy Lutomirski <luto@amacapital.net> To: "Jiri Olsa" <jolsa@redhat.com>, "Ingo Molnar" <mingo@redhat.com>, "Peter Zijlstra" <peterz@infradead.org>, "秦承刚(承刚)" <chenggang.qcg@alibaba-inc.com> Cc: "Andy Lutomirski" <luto@amacapital.net>, "Stephane Eranian" <eranian@google.com>, root <chenggang.qin@gmail.com>, "Andrew Morton" <akpm@linux-foundation.org>, "秦承刚(承刚)" <chenggang.qcg@taobao.com>, "Wu Fengguang" <fengguang.wu@intel.com>, "Namhyung Kim" <namhyung@gmail.com>, "Mike Galbraith" <efault@gmx.de>, "Arjan van de Ven" <arjan@linux.intel.com>, linux-kernel <linux-kernel@vger.kernel.org>, "David Ahern" <dsahern@gmail.com>, "Paul Mackerras" <paulus@samba.org>, "Yanmin Zhang" <yanmin.zhang@intel.com> Subject: [PATCH 1/2] perf: Move task_pt_regs sampling into arch code Date: Sun, 4 Jan 2015 10:36:19 -0800 [thread overview] Message-ID: <e431cd4c18c2e1c44c774f10758527fb2d1025c4.1420396372.git.luto@amacapital.net> (raw) In-Reply-To: <cover.1420396372.git.luto@amacapital.net> In-Reply-To: <cover.1420396372.git.luto@amacapital.net> On x86_64, at least, task_pt_regs may be only partially initialized in many contexts, so x86_64 should not use it without extra care from interrupt context, let alone NMI context. This will allow x86_64 to override the logic and will supply some scratch space to use to make a cleaner copy of user regs. Signed-off-by: Andy Lutomirski <luto@amacapital.net> --- arch/arm/kernel/perf_regs.c | 8 ++++++++ arch/arm64/kernel/perf_regs.c | 8 ++++++++ arch/x86/kernel/perf_regs.c | 16 ++++++++++++++++ include/linux/perf_event.h | 12 +++++++----- include/linux/perf_regs.h | 16 ++++++++++++++++ kernel/events/core.c | 19 ++++++++----------- 6 files changed, 63 insertions(+), 16 deletions(-) diff --git a/arch/arm/kernel/perf_regs.c b/arch/arm/kernel/perf_regs.c index 6e4379c67cbc..592dda3f21ff 100644 --- a/arch/arm/kernel/perf_regs.c +++ b/arch/arm/kernel/perf_regs.c @@ -28,3 +28,11 @@ u64 perf_reg_abi(struct task_struct *task) { return PERF_SAMPLE_REGS_ABI_32; } + +void perf_get_regs_user(struct perf_regs *regs_user, + struct pt_regs *regs, + struct pt_regs *regs_user_copy) +{ + regs_user->regs = task_pt_regs(current); + regs_user->abi = perf_reg_abi(current); +} diff --git a/arch/arm64/kernel/perf_regs.c b/arch/arm64/kernel/perf_regs.c index 6762ad705587..3f62b35fb6f1 100644 --- a/arch/arm64/kernel/perf_regs.c +++ b/arch/arm64/kernel/perf_regs.c @@ -50,3 +50,11 @@ u64 perf_reg_abi(struct task_struct *task) else return PERF_SAMPLE_REGS_ABI_64; } + +void perf_get_regs_user(struct perf_regs *regs_user, + struct pt_regs *regs, + struct pt_regs *regs_user_copy) +{ + regs_user->regs = task_pt_regs(current); + regs_user->abi = perf_reg_abi(current); +} diff --git a/arch/x86/kernel/perf_regs.c b/arch/x86/kernel/perf_regs.c index e309cc5c276e..3bbbb1a4fb52 100644 --- a/arch/x86/kernel/perf_regs.c +++ b/arch/x86/kernel/perf_regs.c @@ -78,6 +78,14 @@ u64 perf_reg_abi(struct task_struct *task) { return PERF_SAMPLE_REGS_ABI_32; } + +void perf_get_regs_user(struct perf_regs *regs_user, + struct pt_regs *regs, + struct pt_regs *regs_user_copy) +{ + regs_user->regs = task_pt_regs(current); + regs_user->abi = perf_reg_abi(current); +} #else /* CONFIG_X86_64 */ #define REG_NOSUPPORT ((1ULL << PERF_REG_X86_DS) | \ (1ULL << PERF_REG_X86_ES) | \ @@ -102,4 +110,12 @@ u64 perf_reg_abi(struct task_struct *task) else return PERF_SAMPLE_REGS_ABI_64; } + +void perf_get_regs_user(struct perf_regs *regs_user, + struct pt_regs *regs, + struct pt_regs *regs_user_copy) +{ + regs_user->regs = task_pt_regs(current); + regs_user->abi = perf_reg_abi(current); +} #endif /* CONFIG_X86_32 */ diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 486e84ccb1f9..4f7a61ca4b39 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -79,11 +79,6 @@ struct perf_branch_stack { struct perf_branch_entry entries[0]; }; -struct perf_regs { - __u64 abi; - struct pt_regs *regs; -}; - struct task_struct; /* @@ -610,7 +605,14 @@ struct perf_sample_data { u32 reserved; } cpu_entry; struct perf_callchain_entry *callchain; + + /* + * regs_user may point to task_pt_regs or to regs_user_copy, depending + * on arch details. + */ struct perf_regs regs_user; + struct pt_regs regs_user_copy; + struct perf_regs regs_intr; u64 stack_user_size; } ____cacheline_aligned; diff --git a/include/linux/perf_regs.h b/include/linux/perf_regs.h index 3c73d5fe18be..a5f98d53d732 100644 --- a/include/linux/perf_regs.h +++ b/include/linux/perf_regs.h @@ -1,11 +1,19 @@ #ifndef _LINUX_PERF_REGS_H #define _LINUX_PERF_REGS_H +struct perf_regs { + __u64 abi; + struct pt_regs *regs; +}; + #ifdef CONFIG_HAVE_PERF_REGS #include <asm/perf_regs.h> u64 perf_reg_value(struct pt_regs *regs, int idx); int perf_reg_validate(u64 mask); u64 perf_reg_abi(struct task_struct *task); +void perf_get_regs_user(struct perf_regs *regs_user, + struct pt_regs *regs, + struct pt_regs *regs_user_copy); #else static inline u64 perf_reg_value(struct pt_regs *regs, int idx) { @@ -21,5 +29,13 @@ static inline u64 perf_reg_abi(struct task_struct *task) { return PERF_SAMPLE_REGS_ABI_NONE; } + +static inline void perf_get_regs_user(struct perf_regs *regs_user, + struct pt_regs *regs, + struct pt_regs *regs_user_copy) +{ + regs_user->regs = task_pt_regs(current); + regs_user->abi = perf_reg_abi(current); +} #endif /* CONFIG_HAVE_PERF_REGS */ #endif /* _LINUX_PERF_REGS_H */ diff --git a/kernel/events/core.c b/kernel/events/core.c index 4c1ee7f2bebc..882f835a0d85 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -4461,18 +4461,14 @@ perf_output_sample_regs(struct perf_output_handle *handle, } static void perf_sample_regs_user(struct perf_regs *regs_user, - struct pt_regs *regs) + struct pt_regs *regs, + struct pt_regs *regs_user_copy) { - if (!user_mode(regs)) { - if (current->mm) - regs = task_pt_regs(current); - else - regs = NULL; - } - - if (regs) { - regs_user->abi = perf_reg_abi(current); + if (user_mode(regs)) { + regs_user->abi = perf_reg_abi(current); regs_user->regs = regs; + } else if (current->mm) { + perf_get_regs_user(regs_user, regs, regs_user_copy); } else { regs_user->abi = PERF_SAMPLE_REGS_ABI_NONE; regs_user->regs = NULL; @@ -4951,7 +4947,8 @@ void perf_prepare_sample(struct perf_event_header *header, } if (sample_type & (PERF_SAMPLE_REGS_USER | PERF_SAMPLE_STACK_USER)) - perf_sample_regs_user(&data->regs_user, regs); + perf_sample_regs_user(&data->regs_user, regs, + &data->regs_user_copy); if (sample_type & PERF_SAMPLE_REGS_USER) { /* regs dump ABI info */ -- 2.1.0
next prev parent reply other threads:[~2015-01-04 18:36 UTC|newest] Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top 2014-12-23 6:22 [PATCH] perf core: Use KSTK_ESP() instead of pt_regs->sp while output user regs root 2014-12-23 8:30 ` Andy Lutomirski [not found] ` <c027bde0-5f4f-441f-8d45-3e7f6f702231@alibaba-inc.com> 2014-12-25 15:48 ` 答复:[PATCH] " Andy Lutomirski 2014-12-25 16:21 ` Andy Lutomirski 2014-12-30 19:03 ` Peter Zijlstra 2014-12-30 23:29 ` Andy Lutomirski 2014-12-31 2:00 ` Andy Lutomirski 2015-01-02 16:11 ` Jan Beulich 2015-01-02 18:03 ` Andy Lutomirski 2015-01-05 8:47 ` Jan Beulich 2015-01-04 16:10 ` Jiri Olsa 2015-01-04 17:18 ` Andy Lutomirski 2015-01-04 17:41 ` Jiri Olsa 2015-01-04 18:36 ` [PATCH 0/2] perf: Improve user regs sampling Andy Lutomirski 2015-01-04 18:36 ` Andy Lutomirski [this message] 2015-01-05 14:07 ` [PATCH 1/2] perf: Move task_pt_regs sampling into arch code Peter Zijlstra 2015-01-05 16:13 ` Andy Lutomirski 2015-01-05 16:44 ` Peter Zijlstra 2015-01-05 18:28 ` Andy Lutomirski 2015-01-09 12:32 ` [tip:perf/urgent] " tip-bot for Andy Lutomirski 2015-01-04 18:36 ` [PATCH 2/2] x86_64, perf: Improve user regs sampling Andy Lutomirski 2015-01-09 12:32 ` [tip:perf/urgent] perf/x86_64: " tip-bot for Andy Lutomirski 2015-01-05 10:46 ` [PATCH 0/2] perf: " Jiri Olsa
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=e431cd4c18c2e1c44c774f10758527fb2d1025c4.1420396372.git.luto@amacapital.net \ --to=luto@amacapital.net \ --cc=akpm@linux-foundation.org \ --cc=arjan@linux.intel.com \ --cc=chenggang.qcg@alibaba-inc.com \ --cc=chenggang.qcg@taobao.com \ --cc=chenggang.qin@gmail.com \ --cc=dsahern@gmail.com \ --cc=efault@gmx.de \ --cc=eranian@google.com \ --cc=fengguang.wu@intel.com \ --cc=jolsa@redhat.com \ --cc=linux-kernel@vger.kernel.org \ --cc=mingo@redhat.com \ --cc=namhyung@gmail.com \ --cc=paulus@samba.org \ --cc=peterz@infradead.org \ --cc=yanmin.zhang@intel.com \ --subject='Re: [PATCH 1/2] perf: Move task_pt_regs sampling into arch code' \ /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
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.