Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1251143 > unrolled thread
| Started by | Andi Kleen <andi@firstfloor.org> |
|---|---|
| First post | 2015-10-20 01:00 +0200 |
| Last post | 2015-10-20 19:40 +0200 |
| Articles | 3 — 2 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
[PATCH 2/2] x86, perf: Optimize stack walk user accesses Andi Kleen <andi@firstfloor.org> - 2015-10-20 01:00 +0200
Re: [PATCH 2/2] x86, perf: Optimize stack walk user accesses Peter Zijlstra <peterz@infradead.org> - 2015-10-20 13:10 +0200
Re: [PATCH 2/2] x86, perf: Optimize stack walk user accesses Andi Kleen <andi@firstfloor.org> - 2015-10-20 19:40 +0200
| From | Andi Kleen <andi@firstfloor.org> |
|---|---|
| Date | 2015-10-20 01:00 +0200 |
| Subject | [PATCH 2/2] x86, perf: Optimize stack walk user accesses |
| Message-ID | <qlrzk-1Mv-21@gated-at.bofh.it> |
From: Andi Kleen <ak@linux.intel.com> Change the perf user stack walking to use the new __copy_from_user_nmi, and split each access into word sized transfer sizes. This allows to inline the complete access and optimize it all into a single load. The main advantage is that this avoids the overhead of double page faults. When normal copy_from_user fails it reexecutes the copy to compute an accurate number of non copied bytes. This leads to executing the expensive page fault twice. While walking stacks having a fault at some point is relatively common (typically when some part of the program isn't compiled with frame pointers), so this is a large overhead. With the optimized copies we avoid this problem because they only do all accesses once. And of course they're much faster too when the access does not fault because they're just single instructions instead of complex function calls. While profiling a kernel build with -g, the patch brings down the average time of the PMI handler from 966ns to 552ns (-43%) Signed-off-by: Andi Kleen <ak@linux.intel.com> --- arch/x86/kernel/cpu/perf_event.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 4562cf0..15bf8b3 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -2255,7 +2255,12 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry) frame.next_frame = 0; frame.return_address = 0; - bytes = copy_from_user_nmi(&frame, fp, sizeof(frame)); + if (!access_ok(VERIFY_READ, fp, 8)) + break; + bytes = __copy_from_user_nmi(&frame.next_frame, fp, 4); + if (bytes != 0) + break; + bytes = __copy_from_user_nmi(&frame.return_address, fp+4, 4); if (bytes != 0) break; @@ -2307,7 +2312,13 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) frame.next_frame = NULL; frame.return_address = 0; - bytes = copy_from_user_nmi(&frame, fp, sizeof(frame)); + if (!access_ok(VERIFY_READ, fp, 16)) + break; + + bytes = __copy_from_user_nmi(&frame.next_frame, fp, 8); + if (bytes != 0) + break; + bytes = __copy_from_user_nmi(&frame.return_address, fp+8, 8); if (bytes != 0) break; -- 2.4.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2015-10-20 13:10 +0200 |
| Message-ID | <qlCXM-1Tf-5@gated-at.bofh.it> |
| In reply to | #1251143 |
On Mon, Oct 19, 2015 at 03:54:29PM -0700, Andi Kleen wrote: > @@ -2307,7 +2312,13 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) > frame.next_frame = NULL; > frame.return_address = 0; > > - bytes = copy_from_user_nmi(&frame, fp, sizeof(frame)); > + if (!access_ok(VERIFY_READ, fp, 16)) > + break; > + > + bytes = __copy_from_user_nmi(&frame.next_frame, fp, 8); > + if (bytes != 0) > + break; > + bytes = __copy_from_user_nmi(&frame.return_address, fp+8, 8); > if (bytes != 0) > break; > The previous patch that introduces this function states that any caller must have pagefault_disable() or be from interrupt context. Perf can call this function from !interrupt context (imagine a tracepoint or other software event), should we therefore not add a pagefault_disable()/enable() pair around the entire while() loop? -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Andi Kleen <andi@firstfloor.org> |
|---|---|
| Date | 2015-10-20 19:40 +0200 |
| Message-ID | <qlJ3c-2aM-23@gated-at.bofh.it> |
| In reply to | #1251589 |
> Perf can call this function from !interrupt context (imagine a > tracepoint or other software event), should we therefore not add a > pagefault_disable()/enable() pair around the entire while() loop? That's true. I'll add the pagefault_disable/enable. -Andi -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web