diff options
-rw-r--r-- | init/Kconfig | 2 | ||||
-rw-r--r-- | kernel/fork.c | 9 | ||||
-rw-r--r-- | kernel/perf_counter.c | 29 | ||||
-rw-r--r-- | tools/perf/builtin-record.c | 10 | ||||
-rw-r--r-- | tools/perf/builtin-report.c | 4 | ||||
-rw-r--r-- | tools/perf/util/parse-events.c | 2 |
6 files changed, 35 insertions, 21 deletions
diff --git a/init/Kconfig b/init/Kconfig index 1ce05a4cb5f6..cb2c09270226 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -962,7 +962,7 @@ config PERF_COUNTERS | |||
962 | 962 | ||
963 | config EVENT_PROFILE | 963 | config EVENT_PROFILE |
964 | bool "Tracepoint profile sources" | 964 | bool "Tracepoint profile sources" |
965 | depends on PERF_COUNTERS && EVENT_TRACER | 965 | depends on PERF_COUNTERS && EVENT_TRACING |
966 | default y | 966 | default y |
967 | 967 | ||
968 | endmenu | 968 | endmenu |
diff --git a/kernel/fork.c b/kernel/fork.c index 467746b3f0aa..4812d60b29f8 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -1408,14 +1408,11 @@ long do_fork(unsigned long clone_flags, | |||
1408 | if (clone_flags & CLONE_VFORK) { | 1408 | if (clone_flags & CLONE_VFORK) { |
1409 | p->vfork_done = &vfork; | 1409 | p->vfork_done = &vfork; |
1410 | init_completion(&vfork); | 1410 | init_completion(&vfork); |
1411 | } else if (!(clone_flags & CLONE_VM)) { | ||
1412 | /* | ||
1413 | * vfork will do an exec which will call | ||
1414 | * set_task_comm() | ||
1415 | */ | ||
1416 | perf_counter_fork(p); | ||
1417 | } | 1411 | } |
1418 | 1412 | ||
1413 | if (!(clone_flags & CLONE_THREAD)) | ||
1414 | perf_counter_fork(p); | ||
1415 | |||
1419 | audit_finish_fork(p); | 1416 | audit_finish_fork(p); |
1420 | tracehook_report_clone(regs, clone_flags, nr, p); | 1417 | tracehook_report_clone(regs, clone_flags, nr, p); |
1421 | 1418 | ||
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 8bf997d86bf4..5c6fae4f43d8 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) | |||
2969 | struct perf_cpu_context *cpuctx; | 2969 | struct perf_cpu_context *cpuctx; |
2970 | struct perf_counter_context *ctx; | 2970 | struct perf_counter_context *ctx; |
2971 | unsigned int size; | 2971 | unsigned int size; |
2972 | char *comm = comm_event->task->comm; | 2972 | char comm[TASK_COMM_LEN]; |
2973 | 2973 | ||
2974 | memset(comm, 0, sizeof(comm)); | ||
2975 | strncpy(comm, comm_event->task->comm, sizeof(comm)); | ||
2974 | size = ALIGN(strlen(comm)+1, sizeof(u64)); | 2976 | size = ALIGN(strlen(comm)+1, sizeof(u64)); |
2975 | 2977 | ||
2976 | comm_event->comm = comm; | 2978 | comm_event->comm = comm; |
@@ -3089,8 +3091,15 @@ static void perf_counter_mmap_event(struct perf_mmap_event *mmap_event) | |||
3089 | char *buf = NULL; | 3091 | char *buf = NULL; |
3090 | const char *name; | 3092 | const char *name; |
3091 | 3093 | ||
3094 | memset(tmp, 0, sizeof(tmp)); | ||
3095 | |||
3092 | if (file) { | 3096 | if (file) { |
3093 | buf = kzalloc(PATH_MAX, GFP_KERNEL); | 3097 | /* |
3098 | * d_path works from the end of the buffer backwards, so we | ||
3099 | * need to add enough zero bytes after the string to handle | ||
3100 | * the 64bit alignment we do later. | ||
3101 | */ | ||
3102 | buf = kzalloc(PATH_MAX + sizeof(u64), GFP_KERNEL); | ||
3094 | if (!buf) { | 3103 | if (!buf) { |
3095 | name = strncpy(tmp, "//enomem", sizeof(tmp)); | 3104 | name = strncpy(tmp, "//enomem", sizeof(tmp)); |
3096 | goto got_name; | 3105 | goto got_name; |
@@ -3101,9 +3110,11 @@ static void perf_counter_mmap_event(struct perf_mmap_event *mmap_event) | |||
3101 | goto got_name; | 3110 | goto got_name; |
3102 | } | 3111 | } |
3103 | } else { | 3112 | } else { |
3104 | name = arch_vma_name(mmap_event->vma); | 3113 | if (arch_vma_name(mmap_event->vma)) { |
3105 | if (name) | 3114 | name = strncpy(tmp, arch_vma_name(mmap_event->vma), |
3115 | sizeof(tmp)); | ||
3106 | goto got_name; | 3116 | goto got_name; |
3117 | } | ||
3107 | 3118 | ||
3108 | if (!vma->vm_mm) { | 3119 | if (!vma->vm_mm) { |
3109 | name = strncpy(tmp, "[vdso]", sizeof(tmp)); | 3120 | name = strncpy(tmp, "[vdso]", sizeof(tmp)); |
@@ -3672,7 +3683,7 @@ static const struct pmu perf_ops_task_clock = { | |||
3672 | void perf_tpcounter_event(int event_id) | 3683 | void perf_tpcounter_event(int event_id) |
3673 | { | 3684 | { |
3674 | struct perf_sample_data data = { | 3685 | struct perf_sample_data data = { |
3675 | .regs = get_irq_regs(); | 3686 | .regs = get_irq_regs(), |
3676 | .addr = 0, | 3687 | .addr = 0, |
3677 | }; | 3688 | }; |
3678 | 3689 | ||
@@ -3688,16 +3699,12 @@ extern void ftrace_profile_disable(int); | |||
3688 | 3699 | ||
3689 | static void tp_perf_counter_destroy(struct perf_counter *counter) | 3700 | static void tp_perf_counter_destroy(struct perf_counter *counter) |
3690 | { | 3701 | { |
3691 | ftrace_profile_disable(perf_event_id(&counter->attr)); | 3702 | ftrace_profile_disable(counter->attr.config); |
3692 | } | 3703 | } |
3693 | 3704 | ||
3694 | static const struct pmu *tp_perf_counter_init(struct perf_counter *counter) | 3705 | static const struct pmu *tp_perf_counter_init(struct perf_counter *counter) |
3695 | { | 3706 | { |
3696 | int event_id = perf_event_id(&counter->attr); | 3707 | if (ftrace_profile_enable(counter->attr.config)) |
3697 | int ret; | ||
3698 | |||
3699 | ret = ftrace_profile_enable(event_id); | ||
3700 | if (ret) | ||
3701 | return NULL; | 3708 | return NULL; |
3702 | 3709 | ||
3703 | counter->destroy = tp_perf_counter_destroy; | 3710 | counter->destroy = tp_perf_counter_destroy; |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 4ef78a5e6f32..68a9be0d1513 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -43,6 +43,7 @@ static int call_graph = 0; | |||
43 | static int verbose = 0; | 43 | static int verbose = 0; |
44 | static int inherit_stat = 0; | 44 | static int inherit_stat = 0; |
45 | static int no_samples = 0; | 45 | static int no_samples = 0; |
46 | static int sample_address = 0; | ||
46 | 47 | ||
47 | static long samples; | 48 | static long samples; |
48 | static struct timeval last_read; | 49 | static struct timeval last_read; |
@@ -313,6 +314,10 @@ static void pid_synthesize_mmap_samples(pid_t pid) | |||
313 | if (*pbf == 'x') { /* vm_exec */ | 314 | if (*pbf == 'x') { /* vm_exec */ |
314 | char *execname = strchr(bf, '/'); | 315 | char *execname = strchr(bf, '/'); |
315 | 316 | ||
317 | /* Catch VDSO */ | ||
318 | if (execname == NULL) | ||
319 | execname = strstr(bf, "[vdso]"); | ||
320 | |||
316 | if (execname == NULL) | 321 | if (execname == NULL) |
317 | continue; | 322 | continue; |
318 | 323 | ||
@@ -401,6 +406,9 @@ static void create_counter(int counter, int cpu, pid_t pid) | |||
401 | if (inherit_stat) | 406 | if (inherit_stat) |
402 | attr->inherit_stat = 1; | 407 | attr->inherit_stat = 1; |
403 | 408 | ||
409 | if (sample_address) | ||
410 | attr->sample_type |= PERF_SAMPLE_ADDR; | ||
411 | |||
404 | if (call_graph) | 412 | if (call_graph) |
405 | attr->sample_type |= PERF_SAMPLE_CALLCHAIN; | 413 | attr->sample_type |= PERF_SAMPLE_CALLCHAIN; |
406 | 414 | ||
@@ -645,6 +653,8 @@ static const struct option options[] = { | |||
645 | "be more verbose (show counter open errors, etc)"), | 653 | "be more verbose (show counter open errors, etc)"), |
646 | OPT_BOOLEAN('s', "stat", &inherit_stat, | 654 | OPT_BOOLEAN('s', "stat", &inherit_stat, |
647 | "per thread counts"), | 655 | "per thread counts"), |
656 | OPT_BOOLEAN('d', "data", &sample_address, | ||
657 | "Sample addresses"), | ||
648 | OPT_BOOLEAN('n', "no-samples", &no_samples, | 658 | OPT_BOOLEAN('n', "no-samples", &no_samples, |
649 | "don't sample"), | 659 | "don't sample"), |
650 | OPT_END() | 660 | OPT_END() |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 430a195b8589..a118bc77286d 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -2005,9 +2005,9 @@ static const struct option options[] = { | |||
2005 | "regex filter to identify parent, see: '--sort parent'"), | 2005 | "regex filter to identify parent, see: '--sort parent'"), |
2006 | OPT_BOOLEAN('x', "exclude-other", &exclude_other, | 2006 | OPT_BOOLEAN('x', "exclude-other", &exclude_other, |
2007 | "Only display entries with parent-match"), | 2007 | "Only display entries with parent-match"), |
2008 | OPT_CALLBACK_DEFAULT('c', "callchain", NULL, "output_type,min_percent", | 2008 | OPT_CALLBACK_DEFAULT('g', "call-graph", NULL, "output_type,min_percent", |
2009 | "Display callchains using output_type and min percent threshold. " | 2009 | "Display callchains using output_type and min percent threshold. " |
2010 | "Default: flat,0", &parse_callchain_opt, callchain_default_opt), | 2010 | "Default: fractal,0.5", &parse_callchain_opt, callchain_default_opt), |
2011 | OPT_STRING('d', "dsos", &dso_list_str, "dso[,dso...]", | 2011 | OPT_STRING('d', "dsos", &dso_list_str, "dso[,dso...]", |
2012 | "only consider symbols in these dsos"), | 2012 | "only consider symbols in these dsos"), |
2013 | OPT_STRING('C', "comms", &comm_list_str, "comm[,comm...]", | 2013 | 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 518a33affe1a..d18c98edd00d 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
@@ -436,7 +436,7 @@ void print_events(void) | |||
436 | 436 | ||
437 | for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) { | 437 | for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) { |
438 | type = syms->type + 1; | 438 | type = syms->type + 1; |
439 | if (type > ARRAY_SIZE(event_type_descriptors)) | 439 | if (type >= ARRAY_SIZE(event_type_descriptors)) |
440 | type = 0; | 440 | type = 0; |
441 | 441 | ||
442 | if (type != prev_type) | 442 | if (type != prev_type) |