aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--init/Kconfig2
-rw-r--r--kernel/fork.c9
-rw-r--r--kernel/perf_counter.c29
-rw-r--r--tools/perf/builtin-record.c10
-rw-r--r--tools/perf/builtin-report.c4
-rw-r--r--tools/perf/util/parse-events.c2
6 files changed, 35 insertions, 21 deletions
diff --git a/init/Kconfig b/init/Kconfig
index 1ce05a4cb5f..cb2c0927022 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -962,7 +962,7 @@ config PERF_COUNTERS
config EVENT_PROFILE
bool "Tracepoint profile sources"
- depends on PERF_COUNTERS && EVENT_TRACER
+ depends on PERF_COUNTERS && EVENT_TRACING
default y
endmenu
diff --git a/kernel/fork.c b/kernel/fork.c
index 467746b3f0a..4812d60b29f 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1408,14 +1408,11 @@ long do_fork(unsigned long clone_flags,
if (clone_flags & CLONE_VFORK) {
p->vfork_done = &vfork;
init_completion(&vfork);
- } else if (!(clone_flags & CLONE_VM)) {
- /*
- * vfork will do an exec which will call
- * set_task_comm()
- */
- perf_counter_fork(p);
}
+ if (!(clone_flags & CLONE_THREAD))
+ perf_counter_fork(p);
+
audit_finish_fork(p);
tracehook_report_clone(regs, clone_flags, nr, p);
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c
index 8bf997d86bf..5c6fae4f43d 100644
--- a/kernel/perf_counter.c
+++ b/kernel/perf_counter.c
@@ -2969,8 +2969,10 @@ static void perf_counter_comm_event(struct perf_comm_event *comm_event)
struct perf_cpu_context *cpuctx;
struct perf_counter_context *ctx;
unsigned int size;
- char *comm = comm_event->task->comm;
+ char comm[TASK_COMM_LEN];
+ memset(comm, 0, sizeof(comm));
+ strncpy(comm, comm_event->task->comm, sizeof(comm));
size = ALIGN(strlen(comm)+1, sizeof(u64));
comm_event->comm = comm;
@@ -3089,8 +3091,15 @@ static void perf_counter_mmap_event(struct perf_mmap_event *mmap_event)
char *buf = NULL;
const char *name;
+ memset(tmp, 0, sizeof(tmp));
+
if (file) {
- buf = kzalloc(PATH_MAX, GFP_KERNEL);
+ /*
+ * d_path works from the end of the buffer backwards, so we
+ * need to add enough zero bytes after the string to handle
+ * the 64bit alignment we do later.
+ */
+ buf = kzalloc(PATH_MAX + sizeof(u64), GFP_KERNEL);
if (!buf) {
name = strncpy(tmp, "//enomem", sizeof(tmp));
goto got_name;
@@ -3101,9 +3110,11 @@ static void perf_counter_mmap_event(struct perf_mmap_event *mmap_event)
goto got_name;
}
} else {
- name = arch_vma_name(mmap_event->vma);
- if (name)
+ if (arch_vma_name(mmap_event->vma)) {
+ name = strncpy(tmp, arch_vma_name(mmap_event->vma),
+ sizeof(tmp));
goto got_name;
+ }
if (!vma->vm_mm) {
name = strncpy(tmp, "[vdso]", sizeof(tmp));
@@ -3672,7 +3683,7 @@ static const struct pmu perf_ops_task_clock = {
void perf_tpcounter_event(int event_id)
{
struct perf_sample_data data = {
- .regs = get_irq_regs();
+ .regs = get_irq_regs(),
.addr = 0,
};
@@ -3688,16 +3699,12 @@ extern void ftrace_profile_disable(int);
static void tp_perf_counter_destroy(struct perf_counter *counter)
{
- ftrace_profile_disable(perf_event_id(&counter->attr));
+ ftrace_profile_disable(counter->attr.config);
}
static const struct pmu *tp_perf_counter_init(struct perf_counter *counter)
{
- int event_id = perf_event_id(&counter->attr);
- int ret;
-
- ret = ftrace_profile_enable(event_id);
- if (ret)
+ if (ftrace_profile_enable(counter->attr.config))
return NULL;
counter->destroy = tp_perf_counter_destroy;
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 4ef78a5e6f3..68a9be0d151 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -43,6 +43,7 @@ static int call_graph = 0;
static int verbose = 0;
static int inherit_stat = 0;
static int no_samples = 0;
+static int sample_address = 0;
static long samples;
static struct timeval last_read;
@@ -313,6 +314,10 @@ static void pid_synthesize_mmap_samples(pid_t pid)
if (*pbf == 'x') { /* vm_exec */
char *execname = strchr(bf, '/');
+ /* Catch VDSO */
+ if (execname == NULL)
+ execname = strstr(bf, "[vdso]");
+
if (execname == NULL)
continue;
@@ -401,6 +406,9 @@ static void create_counter(int counter, int cpu, pid_t pid)
if (inherit_stat)
attr->inherit_stat = 1;
+ if (sample_address)
+ attr->sample_type |= PERF_SAMPLE_ADDR;
+
if (call_graph)
attr->sample_type |= PERF_SAMPLE_CALLCHAIN;
@@ -645,6 +653,8 @@ static const struct option options[] = {
"be more verbose (show counter open errors, etc)"),
OPT_BOOLEAN('s', "stat", &inherit_stat,
"per thread counts"),
+ OPT_BOOLEAN('d', "data", &sample_address,
+ "Sample addresses"),
OPT_BOOLEAN('n', "no-samples", &no_samples,
"don't sample"),
OPT_END()
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 430a195b858..a118bc77286 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -2005,9 +2005,9 @@ static const struct option options[] = {
"regex filter to identify parent, see: '--sort parent'"),
OPT_BOOLEAN('x', "exclude-other", &exclude_other,
"Only display entries with parent-match"),
- OPT_CALLBACK_DEFAULT('c', "callchain", NULL, "output_type,min_percent",
+ OPT_CALLBACK_DEFAULT('g', "call-graph", NULL, "output_type,min_percent",
"Display callchains using output_type and min percent threshold. "
- "Default: flat,0", &parse_callchain_opt, callchain_default_opt),
+ "Default: fractal,0.5", &parse_callchain_opt, callchain_default_opt),
OPT_STRING('d', "dsos", &dso_list_str, "dso[,dso...]",
"only consider symbols in these dsos"),
OPT_STRING('C', "comms", &comm_list_str, "comm[,comm...]",
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 518a33affe1..d18c98edd00 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -436,7 +436,7 @@ void print_events(void)
for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) {
type = syms->type + 1;
- if (type > ARRAY_SIZE(event_type_descriptors))
+ if (type >= ARRAY_SIZE(event_type_descriptors))
type = 0;
if (type != prev_type)