diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-02-22 11:55:32 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-02-22 11:55:32 -0500 |
commit | bee415ce427d1eab6cfb30221461c7d20cbf1903 (patch) | |
tree | 406b70a86768535105b226c2b2f0a59b301cc52e | |
parent | 627fa177a1502ad24390d945851209ac022f3a36 (diff) | |
parent | 388c3aab5d4f1b0bbfe2d5f47e7cd681866bc573 (diff) |
Merge branch 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
perf probe: Init struct probe_point and set counter correctly
hw-breakpoint: Keep track of dr7 local enable bits
hw-breakpoints: Accept breakpoints on NULL address
perf_events: Fix FORK events
-rw-r--r-- | arch/x86/include/asm/processor.h | 2 | ||||
-rw-r--r-- | arch/x86/kernel/hw_breakpoint.c | 30 | ||||
-rw-r--r-- | arch/x86/kernel/ptrace.c | 7 | ||||
-rw-r--r-- | kernel/perf_event.c | 11 | ||||
-rw-r--r-- | tools/perf/util/probe-event.c | 3 |
5 files changed, 22 insertions, 31 deletions
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index fc801bab1b3b..b753ea59703a 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h | |||
@@ -450,6 +450,8 @@ struct thread_struct { | |||
450 | struct perf_event *ptrace_bps[HBP_NUM]; | 450 | struct perf_event *ptrace_bps[HBP_NUM]; |
451 | /* Debug status used for traps, single steps, etc... */ | 451 | /* Debug status used for traps, single steps, etc... */ |
452 | unsigned long debugreg6; | 452 | unsigned long debugreg6; |
453 | /* Keep track of the exact dr7 value set by the user */ | ||
454 | unsigned long ptrace_dr7; | ||
453 | /* Fault info: */ | 455 | /* Fault info: */ |
454 | unsigned long cr2; | 456 | unsigned long cr2; |
455 | unsigned long trap_no; | 457 | unsigned long trap_no; |
diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c index 05d5fec64a94..bb6006e3e295 100644 --- a/arch/x86/kernel/hw_breakpoint.c +++ b/arch/x86/kernel/hw_breakpoint.c | |||
@@ -212,25 +212,6 @@ static int arch_check_va_in_kernelspace(unsigned long va, u8 hbp_len) | |||
212 | return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE); | 212 | return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE); |
213 | } | 213 | } |
214 | 214 | ||
215 | /* | ||
216 | * Store a breakpoint's encoded address, length, and type. | ||
217 | */ | ||
218 | static int arch_store_info(struct perf_event *bp) | ||
219 | { | ||
220 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); | ||
221 | /* | ||
222 | * For kernel-addresses, either the address or symbol name can be | ||
223 | * specified. | ||
224 | */ | ||
225 | if (info->name) | ||
226 | info->address = (unsigned long) | ||
227 | kallsyms_lookup_name(info->name); | ||
228 | if (info->address) | ||
229 | return 0; | ||
230 | |||
231 | return -EINVAL; | ||
232 | } | ||
233 | |||
234 | int arch_bp_generic_fields(int x86_len, int x86_type, | 215 | int arch_bp_generic_fields(int x86_len, int x86_type, |
235 | int *gen_len, int *gen_type) | 216 | int *gen_len, int *gen_type) |
236 | { | 217 | { |
@@ -362,10 +343,13 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp, | |||
362 | return ret; | 343 | return ret; |
363 | } | 344 | } |
364 | 345 | ||
365 | ret = arch_store_info(bp); | 346 | /* |
366 | 347 | * For kernel-addresses, either the address or symbol name can be | |
367 | if (ret < 0) | 348 | * specified. |
368 | return ret; | 349 | */ |
350 | if (info->name) | ||
351 | info->address = (unsigned long) | ||
352 | kallsyms_lookup_name(info->name); | ||
369 | /* | 353 | /* |
370 | * Check that the low-order bits of the address are appropriate | 354 | * Check that the low-order bits of the address are appropriate |
371 | * for the alignment implied by len. | 355 | * for the alignment implied by len. |
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 017d937639fe..0c1033d61e59 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c | |||
@@ -702,7 +702,7 @@ static unsigned long ptrace_get_debugreg(struct task_struct *tsk, int n) | |||
702 | } else if (n == 6) { | 702 | } else if (n == 6) { |
703 | val = thread->debugreg6; | 703 | val = thread->debugreg6; |
704 | } else if (n == 7) { | 704 | } else if (n == 7) { |
705 | val = ptrace_get_dr7(thread->ptrace_bps); | 705 | val = thread->ptrace_dr7; |
706 | } | 706 | } |
707 | return val; | 707 | return val; |
708 | } | 708 | } |
@@ -778,8 +778,11 @@ int ptrace_set_debugreg(struct task_struct *tsk, int n, unsigned long val) | |||
778 | return rc; | 778 | return rc; |
779 | } | 779 | } |
780 | /* All that's left is DR7 */ | 780 | /* All that's left is DR7 */ |
781 | if (n == 7) | 781 | if (n == 7) { |
782 | rc = ptrace_write_dr7(tsk, val); | 782 | rc = ptrace_write_dr7(tsk, val); |
783 | if (!rc) | ||
784 | thread->ptrace_dr7 = val; | ||
785 | } | ||
783 | 786 | ||
784 | ret_path: | 787 | ret_path: |
785 | return rc; | 788 | return rc; |
diff --git a/kernel/perf_event.c b/kernel/perf_event.c index 2b19297742cb..2ae7409bf38f 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c | |||
@@ -3259,8 +3259,6 @@ static void perf_event_task_output(struct perf_event *event, | |||
3259 | task_event->event_id.tid = perf_event_tid(event, task); | 3259 | task_event->event_id.tid = perf_event_tid(event, task); |
3260 | task_event->event_id.ptid = perf_event_tid(event, current); | 3260 | task_event->event_id.ptid = perf_event_tid(event, current); |
3261 | 3261 | ||
3262 | task_event->event_id.time = perf_clock(); | ||
3263 | |||
3264 | perf_output_put(&handle, task_event->event_id); | 3262 | perf_output_put(&handle, task_event->event_id); |
3265 | 3263 | ||
3266 | perf_output_end(&handle); | 3264 | perf_output_end(&handle); |
@@ -3268,7 +3266,7 @@ static void perf_event_task_output(struct perf_event *event, | |||
3268 | 3266 | ||
3269 | static int perf_event_task_match(struct perf_event *event) | 3267 | static int perf_event_task_match(struct perf_event *event) |
3270 | { | 3268 | { |
3271 | if (event->state != PERF_EVENT_STATE_ACTIVE) | 3269 | if (event->state < PERF_EVENT_STATE_INACTIVE) |
3272 | return 0; | 3270 | return 0; |
3273 | 3271 | ||
3274 | if (event->cpu != -1 && event->cpu != smp_processor_id()) | 3272 | if (event->cpu != -1 && event->cpu != smp_processor_id()) |
@@ -3300,7 +3298,7 @@ static void perf_event_task_event(struct perf_task_event *task_event) | |||
3300 | cpuctx = &get_cpu_var(perf_cpu_context); | 3298 | cpuctx = &get_cpu_var(perf_cpu_context); |
3301 | perf_event_task_ctx(&cpuctx->ctx, task_event); | 3299 | perf_event_task_ctx(&cpuctx->ctx, task_event); |
3302 | if (!ctx) | 3300 | if (!ctx) |
3303 | ctx = rcu_dereference(task_event->task->perf_event_ctxp); | 3301 | ctx = rcu_dereference(current->perf_event_ctxp); |
3304 | if (ctx) | 3302 | if (ctx) |
3305 | perf_event_task_ctx(ctx, task_event); | 3303 | perf_event_task_ctx(ctx, task_event); |
3306 | put_cpu_var(perf_cpu_context); | 3304 | put_cpu_var(perf_cpu_context); |
@@ -3331,6 +3329,7 @@ static void perf_event_task(struct task_struct *task, | |||
3331 | /* .ppid */ | 3329 | /* .ppid */ |
3332 | /* .tid */ | 3330 | /* .tid */ |
3333 | /* .ptid */ | 3331 | /* .ptid */ |
3332 | .time = perf_clock(), | ||
3334 | }, | 3333 | }, |
3335 | }; | 3334 | }; |
3336 | 3335 | ||
@@ -3380,7 +3379,7 @@ static void perf_event_comm_output(struct perf_event *event, | |||
3380 | 3379 | ||
3381 | static int perf_event_comm_match(struct perf_event *event) | 3380 | static int perf_event_comm_match(struct perf_event *event) |
3382 | { | 3381 | { |
3383 | if (event->state != PERF_EVENT_STATE_ACTIVE) | 3382 | if (event->state < PERF_EVENT_STATE_INACTIVE) |
3384 | return 0; | 3383 | return 0; |
3385 | 3384 | ||
3386 | if (event->cpu != -1 && event->cpu != smp_processor_id()) | 3385 | if (event->cpu != -1 && event->cpu != smp_processor_id()) |
@@ -3500,7 +3499,7 @@ static void perf_event_mmap_output(struct perf_event *event, | |||
3500 | static int perf_event_mmap_match(struct perf_event *event, | 3499 | static int perf_event_mmap_match(struct perf_event *event, |
3501 | struct perf_mmap_event *mmap_event) | 3500 | struct perf_mmap_event *mmap_event) |
3502 | { | 3501 | { |
3503 | if (event->state != PERF_EVENT_STATE_ACTIVE) | 3502 | if (event->state < PERF_EVENT_STATE_INACTIVE) |
3504 | return 0; | 3503 | return 0; |
3505 | 3504 | ||
3506 | if (event->cpu != -1 && event->cpu != smp_processor_id()) | 3505 | if (event->cpu != -1 && event->cpu != smp_processor_id()) |
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 29465d440043..fde17b090a47 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
@@ -272,6 +272,7 @@ int synthesize_perf_probe_point(struct probe_point *pp) | |||
272 | int ret; | 272 | int ret; |
273 | 273 | ||
274 | pp->probes[0] = buf = zalloc(MAX_CMDLEN); | 274 | pp->probes[0] = buf = zalloc(MAX_CMDLEN); |
275 | pp->found = 1; | ||
275 | if (!buf) | 276 | if (!buf) |
276 | die("Failed to allocate memory by zalloc."); | 277 | die("Failed to allocate memory by zalloc."); |
277 | if (pp->offset) { | 278 | if (pp->offset) { |
@@ -294,6 +295,7 @@ int synthesize_perf_probe_point(struct probe_point *pp) | |||
294 | error: | 295 | error: |
295 | free(pp->probes[0]); | 296 | free(pp->probes[0]); |
296 | pp->probes[0] = NULL; | 297 | pp->probes[0] = NULL; |
298 | pp->found = 0; | ||
297 | } | 299 | } |
298 | return ret; | 300 | return ret; |
299 | } | 301 | } |
@@ -455,6 +457,7 @@ void show_perf_probe_events(void) | |||
455 | struct strlist *rawlist; | 457 | struct strlist *rawlist; |
456 | struct str_node *ent; | 458 | struct str_node *ent; |
457 | 459 | ||
460 | memset(&pp, 0, sizeof(pp)); | ||
458 | fd = open_kprobe_events(O_RDONLY, 0); | 461 | fd = open_kprobe_events(O_RDONLY, 0); |
459 | rawlist = get_trace_kprobe_event_rawlist(fd); | 462 | rawlist = get_trace_kprobe_event_rawlist(fd); |
460 | close(fd); | 463 | close(fd); |