diff options
author | Robert Richter <robert.richter@amd.com> | 2010-09-29 09:42:30 -0400 |
---|---|---|
committer | Robert Richter <robert.richter@amd.com> | 2010-10-04 04:54:05 -0400 |
commit | 4d1814f48edec31f12737609cd1c871864c8298b (patch) | |
tree | 26cf216f99555256af0d39507219d8263919b981 | |
parent | 5140434d5f82f2e2119926272ada2e9731ec04f1 (diff) |
oprofile, ARM: Use oprofile_arch_exit() to cleanup on failure
There is duplicate cleanup code in the init and exit functions. Now,
oprofile_arch_exit() is also used if oprofile_arch_init() fails.
Acked-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Robert Richter <robert.richter@amd.com>
-rw-r--r-- | arch/arm/oprofile/common.c | 53 |
1 files changed, 26 insertions, 27 deletions
diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c index bd7426ffedd0..7ae9eebe7efc 100644 --- a/arch/arm/oprofile/common.c +++ b/arch/arm/oprofile/common.c | |||
@@ -348,10 +348,33 @@ static void arm_backtrace(struct pt_regs * const regs, unsigned int depth) | |||
348 | tail = user_backtrace(tail); | 348 | tail = user_backtrace(tail); |
349 | } | 349 | } |
350 | 350 | ||
351 | void oprofile_arch_exit(void) | ||
352 | { | ||
353 | int cpu, id; | ||
354 | struct perf_event *event; | ||
355 | |||
356 | for_each_possible_cpu(cpu) { | ||
357 | for (id = 0; id < perf_num_counters; ++id) { | ||
358 | event = perf_events[cpu][id]; | ||
359 | if (event) | ||
360 | perf_event_release_kernel(event); | ||
361 | } | ||
362 | |||
363 | kfree(perf_events[cpu]); | ||
364 | } | ||
365 | |||
366 | kfree(counter_config); | ||
367 | exit_driverfs(); | ||
368 | } | ||
369 | |||
351 | int __init oprofile_arch_init(struct oprofile_operations *ops) | 370 | int __init oprofile_arch_init(struct oprofile_operations *ops) |
352 | { | 371 | { |
353 | int cpu, ret = 0; | 372 | int cpu, ret = 0; |
354 | 373 | ||
374 | ret = init_driverfs(); | ||
375 | if (ret) | ||
376 | return ret; | ||
377 | |||
355 | memset(&perf_events, 0, sizeof(perf_events)); | 378 | memset(&perf_events, 0, sizeof(perf_events)); |
356 | 379 | ||
357 | perf_num_counters = armpmu_get_max_events(); | 380 | perf_num_counters = armpmu_get_max_events(); |
@@ -363,13 +386,10 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
363 | pr_info("oprofile: failed to allocate %d " | 386 | pr_info("oprofile: failed to allocate %d " |
364 | "counters\n", perf_num_counters); | 387 | "counters\n", perf_num_counters); |
365 | ret = -ENOMEM; | 388 | ret = -ENOMEM; |
389 | perf_num_counters = 0; | ||
366 | goto out; | 390 | goto out; |
367 | } | 391 | } |
368 | 392 | ||
369 | ret = init_driverfs(); | ||
370 | if (ret) | ||
371 | goto out; | ||
372 | |||
373 | for_each_possible_cpu(cpu) { | 393 | for_each_possible_cpu(cpu) { |
374 | perf_events[cpu] = kcalloc(perf_num_counters, | 394 | perf_events[cpu] = kcalloc(perf_num_counters, |
375 | sizeof(struct perf_event *), GFP_KERNEL); | 395 | sizeof(struct perf_event *), GFP_KERNEL); |
@@ -395,33 +415,12 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
395 | pr_info("oprofile: using %s\n", ops->cpu_type); | 415 | pr_info("oprofile: using %s\n", ops->cpu_type); |
396 | 416 | ||
397 | out: | 417 | out: |
398 | if (ret) { | 418 | if (ret) |
399 | for_each_possible_cpu(cpu) | 419 | oprofile_arch_exit(); |
400 | kfree(perf_events[cpu]); | ||
401 | kfree(counter_config); | ||
402 | } | ||
403 | 420 | ||
404 | return ret; | 421 | return ret; |
405 | } | 422 | } |
406 | 423 | ||
407 | void __exit oprofile_arch_exit(void) | ||
408 | { | ||
409 | int cpu, id; | ||
410 | struct perf_event *event; | ||
411 | |||
412 | for_each_possible_cpu(cpu) { | ||
413 | for (id = 0; id < perf_num_counters; ++id) { | ||
414 | event = perf_events[cpu][id]; | ||
415 | if (event) | ||
416 | perf_event_release_kernel(event); | ||
417 | } | ||
418 | |||
419 | kfree(perf_events[cpu]); | ||
420 | } | ||
421 | |||
422 | kfree(counter_config); | ||
423 | exit_driverfs(); | ||
424 | } | ||
425 | #else | 424 | #else |
426 | int __init oprofile_arch_init(struct oprofile_operations *ops) | 425 | int __init oprofile_arch_init(struct oprofile_operations *ops) |
427 | { | 426 | { |