diff options
-rw-r--r-- | kernel/events/hw_breakpoint.c | 34 |
1 files changed, 11 insertions, 23 deletions
diff --git a/kernel/events/hw_breakpoint.c b/kernel/events/hw_breakpoint.c index 9c71445328af..38418f786f36 100644 --- a/kernel/events/hw_breakpoint.c +++ b/kernel/events/hw_breakpoint.c | |||
@@ -497,8 +497,8 @@ register_wide_hw_breakpoint(struct perf_event_attr *attr, | |||
497 | perf_overflow_handler_t triggered, | 497 | perf_overflow_handler_t triggered, |
498 | void *context) | 498 | void *context) |
499 | { | 499 | { |
500 | struct perf_event * __percpu *cpu_events, **pevent, *bp; | 500 | struct perf_event * __percpu *cpu_events, *bp; |
501 | long err; | 501 | long err = 0; |
502 | int cpu; | 502 | int cpu; |
503 | 503 | ||
504 | cpu_events = alloc_percpu(typeof(*cpu_events)); | 504 | cpu_events = alloc_percpu(typeof(*cpu_events)); |
@@ -507,31 +507,21 @@ register_wide_hw_breakpoint(struct perf_event_attr *attr, | |||
507 | 507 | ||
508 | get_online_cpus(); | 508 | get_online_cpus(); |
509 | for_each_online_cpu(cpu) { | 509 | for_each_online_cpu(cpu) { |
510 | pevent = per_cpu_ptr(cpu_events, cpu); | ||
511 | bp = perf_event_create_kernel_counter(attr, cpu, NULL, | 510 | bp = perf_event_create_kernel_counter(attr, cpu, NULL, |
512 | triggered, context); | 511 | triggered, context); |
513 | |||
514 | *pevent = bp; | ||
515 | |||
516 | if (IS_ERR(bp)) { | 512 | if (IS_ERR(bp)) { |
517 | err = PTR_ERR(bp); | 513 | err = PTR_ERR(bp); |
518 | goto fail; | 514 | break; |
519 | } | 515 | } |
520 | } | ||
521 | put_online_cpus(); | ||
522 | |||
523 | return cpu_events; | ||
524 | 516 | ||
525 | fail: | 517 | per_cpu(*cpu_events, cpu) = bp; |
526 | for_each_online_cpu(cpu) { | ||
527 | pevent = per_cpu_ptr(cpu_events, cpu); | ||
528 | if (IS_ERR(*pevent)) | ||
529 | break; | ||
530 | unregister_hw_breakpoint(*pevent); | ||
531 | } | 518 | } |
532 | put_online_cpus(); | 519 | put_online_cpus(); |
533 | 520 | ||
534 | free_percpu(cpu_events); | 521 | if (likely(!err)) |
522 | return cpu_events; | ||
523 | |||
524 | unregister_wide_hw_breakpoint(cpu_events); | ||
535 | return (void __percpu __force *)ERR_PTR(err); | 525 | return (void __percpu __force *)ERR_PTR(err); |
536 | } | 526 | } |
537 | EXPORT_SYMBOL_GPL(register_wide_hw_breakpoint); | 527 | EXPORT_SYMBOL_GPL(register_wide_hw_breakpoint); |
@@ -543,12 +533,10 @@ EXPORT_SYMBOL_GPL(register_wide_hw_breakpoint); | |||
543 | void unregister_wide_hw_breakpoint(struct perf_event * __percpu *cpu_events) | 533 | void unregister_wide_hw_breakpoint(struct perf_event * __percpu *cpu_events) |
544 | { | 534 | { |
545 | int cpu; | 535 | int cpu; |
546 | struct perf_event **pevent; | ||
547 | 536 | ||
548 | for_each_possible_cpu(cpu) { | 537 | for_each_possible_cpu(cpu) |
549 | pevent = per_cpu_ptr(cpu_events, cpu); | 538 | unregister_hw_breakpoint(per_cpu(*cpu_events, cpu)); |
550 | unregister_hw_breakpoint(*pevent); | 539 | |
551 | } | ||
552 | free_percpu(cpu_events); | 540 | free_percpu(cpu_events); |
553 | } | 541 | } |
554 | EXPORT_SYMBOL_GPL(unregister_wide_hw_breakpoint); | 542 | EXPORT_SYMBOL_GPL(unregister_wide_hw_breakpoint); |