* [tip:perf/urgent] perf core: Add a 'nr' field to perf_event_callchain_context
@ 2016-05-20 6:46 tip-bot for Arnaldo Carvalho de Melo
0 siblings, 0 replies; only message in thread
From: tip-bot for Arnaldo Carvalho de Melo @ 2016-05-20 6:46 UTC (permalink / raw)
To: linux-tip-commits
Cc: hpa, namhyung, peterz, mingo, jolsa, tglx, acme, fweisbec,
dsahern, linux-kernel
Commit-ID: 3b1fff08038bd0792b1aa1e9703b2dd0512a3fd0
Gitweb: http://git.kernel.org/tip/3b1fff08038bd0792b1aa1e9703b2dd0512a3fd0
Author: Arnaldo Carvalho de Melo <acme@redhat.com>
AuthorDate: Tue, 10 May 2016 18:08:32 -0300
Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 16 May 2016 23:11:51 -0300
perf core: Add a 'nr' field to perf_event_callchain_context
We will use it to count how many addresses are in the entry->ip[] array,
excluding PERF_CONTEXT_{KERNEL,USER,etc} entries, so that we can really
return the number of entries specified by the user via the relevant
sysctl, kernel.perf_event_max_contexts, or via the per event
perf_event_attr.sample_max_stack knob.
This way we keep the perf_sample->ip_callchain->nr meaning, that is the
number of entries, be it real addresses or PERF_CONTEXT_ entries, while
honouring the max_stack knobs, i.e. the end result will be max_stack
entries if we have at least that many entries in a given stack trace.
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/n/tip-s8teto51tdqvlfhefndtat9r@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
arch/arm/kernel/perf_callchain.c | 2 +-
arch/arm64/kernel/perf_callchain.c | 4 ++--
arch/metag/kernel/perf_callchain.c | 2 +-
arch/mips/kernel/perf_event.c | 4 ++--
arch/powerpc/perf/callchain.c | 4 ++--
arch/sparc/kernel/perf_event.c | 6 +++---
arch/x86/events/core.c | 4 ++--
include/linux/perf_event.h | 6 ++++--
kernel/events/callchain.c | 3 +--
9 files changed, 18 insertions(+), 17 deletions(-)
diff --git a/arch/arm/kernel/perf_callchain.c b/arch/arm/kernel/perf_callchain.c
index bc552e8..22bf1f6 100644
--- a/arch/arm/kernel/perf_callchain.c
+++ b/arch/arm/kernel/perf_callchain.c
@@ -75,7 +75,7 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs
tail = (struct frame_tail __user *)regs->ARM_fp - 1;
- while ((entry->entry->nr < entry->max_stack) &&
+ while ((entry->nr < entry->max_stack) &&
tail && !((unsigned long)tail & 0x3))
tail = user_backtrace(tail, entry);
}
diff --git a/arch/arm64/kernel/perf_callchain.c b/arch/arm64/kernel/perf_callchain.c
index 0d60150..713ca82 100644
--- a/arch/arm64/kernel/perf_callchain.c
+++ b/arch/arm64/kernel/perf_callchain.c
@@ -122,7 +122,7 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
tail = (struct frame_tail __user *)regs->regs[29];
- while (entry->entry->nr < entry->max_stack &&
+ while (entry->nr < entry->max_stack &&
tail && !((unsigned long)tail & 0xf))
tail = user_backtrace(tail, entry);
} else {
@@ -132,7 +132,7 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
tail = (struct compat_frame_tail __user *)regs->compat_fp - 1;
- while ((entry->entry->nr < entry->max_stack) &&
+ while ((entry->nr < entry->max_stack) &&
tail && !((unsigned long)tail & 0x3))
tail = compat_user_backtrace(tail, entry);
#endif
diff --git a/arch/metag/kernel/perf_callchain.c b/arch/metag/kernel/perf_callchain.c
index b3261a9..3e8e048 100644
--- a/arch/metag/kernel/perf_callchain.c
+++ b/arch/metag/kernel/perf_callchain.c
@@ -65,7 +65,7 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs
--frame;
- while ((entry->entry->nr < entry->max_stack) && frame)
+ while ((entry->nr < entry->max_stack) && frame)
frame = user_backtrace(frame, entry);
}
diff --git a/arch/mips/kernel/perf_event.c b/arch/mips/kernel/perf_event.c
index 22395c7..d64056e 100644
--- a/arch/mips/kernel/perf_event.c
+++ b/arch/mips/kernel/perf_event.c
@@ -35,7 +35,7 @@ static void save_raw_perf_callchain(struct perf_callchain_entry_ctx *entry,
addr = *sp++;
if (__kernel_text_address(addr)) {
perf_callchain_store(entry, addr);
- if (entry->entry->nr >= entry->max_stack)
+ if (entry->nr >= entry->max_stack)
break;
}
}
@@ -59,7 +59,7 @@ void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
}
do {
perf_callchain_store(entry, pc);
- if (entry->entry->nr >= entry->max_stack)
+ if (entry->nr >= entry->max_stack)
break;
pc = unwind_stack(current, &sp, pc, &ra);
} while (pc);
diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
index c9260c1..f68f213 100644
--- a/arch/powerpc/perf/callchain.c
+++ b/arch/powerpc/perf/callchain.c
@@ -247,7 +247,7 @@ static void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
sp = regs->gpr[1];
perf_callchain_store(entry, next_ip);
- while (entry->entry->nr < entry->max_stack) {
+ while (entry->nr < entry->max_stack) {
fp = (unsigned long __user *) sp;
if (!valid_user_sp(sp, 1) || read_user_stack_64(fp, &next_sp))
return;
@@ -453,7 +453,7 @@ static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
sp = regs->gpr[1];
perf_callchain_store(entry, next_ip);
- while (entry->entry->nr < entry->max_stack) {
+ while (entry->nr < entry->max_stack) {
fp = (unsigned int __user *) (unsigned long) sp;
if (!valid_user_sp(sp, 0) || read_user_stack_32(fp, &next_sp))
return;
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c
index bcc5376..710f327 100644
--- a/arch/sparc/kernel/perf_event.c
+++ b/arch/sparc/kernel/perf_event.c
@@ -1756,7 +1756,7 @@ void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
}
}
#endif
- } while (entry->entry->nr < entry->max_stack);
+ } while (entry->nr < entry->max_stack);
}
static inline int
@@ -1790,7 +1790,7 @@ static void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
pc = sf.callers_pc;
ufp = (unsigned long)sf.fp + STACK_BIAS;
perf_callchain_store(entry, pc);
- } while (entry->entry->nr < entry->max_stack);
+ } while (entry->nr < entry->max_stack);
}
static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
@@ -1822,7 +1822,7 @@ static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
ufp = (unsigned long)sf.fp;
}
perf_callchain_store(entry, pc);
- } while (entry->entry->nr < entry->max_stack);
+ } while (entry->nr < entry->max_stack);
}
void
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index 07f2b01..5de96a1 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -2283,7 +2283,7 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *ent
fp = compat_ptr(ss_base + regs->bp);
pagefault_disable();
- while (entry->entry->nr < entry->max_stack) {
+ while (entry->nr < entry->max_stack) {
unsigned long bytes;
frame.next_frame = 0;
frame.return_address = 0;
@@ -2343,7 +2343,7 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs
return;
pagefault_disable();
- while (entry->entry->nr < entry->max_stack) {
+ while (entry->nr < entry->max_stack) {
unsigned long bytes;
frame.next_frame = NULL;
frame.return_address = 0;
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index dbd1824..3803bb1 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -64,6 +64,7 @@ struct perf_callchain_entry {
struct perf_callchain_entry_ctx {
struct perf_callchain_entry *entry;
u32 max_stack;
+ u32 nr;
};
struct perf_raw_record {
@@ -1080,9 +1081,10 @@ extern int sysctl_perf_event_max_stack;
static inline int perf_callchain_store(struct perf_callchain_entry_ctx *ctx, u64 ip)
{
- struct perf_callchain_entry *entry = ctx->entry;
- if (entry->nr < ctx->max_stack) {
+ if (ctx->nr < ctx->max_stack) {
+ struct perf_callchain_entry *entry = ctx->entry;
entry->ip[entry->nr++] = ip;
+ ++ctx->nr;
return 0;
} else {
return -1; /* no more room, stop walking the stack */
diff --git a/kernel/events/callchain.c b/kernel/events/callchain.c
index af95ad9..8774ff8 100644
--- a/kernel/events/callchain.c
+++ b/kernel/events/callchain.c
@@ -196,8 +196,7 @@ get_perf_callchain(struct pt_regs *regs, u32 init_nr, bool kernel, bool user,
ctx.entry = entry;
ctx.max_stack = max_stack;
-
- entry->nr = init_nr;
+ ctx.nr = entry->nr = init_nr;
if (kernel && !user_mode(regs)) {
if (add_mark)
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2016-05-20 6:46 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-05-20 6:46 [tip:perf/urgent] perf core: Add a 'nr' field to perf_event_callchain_context tip-bot for Arnaldo Carvalho de Melo
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.