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 | { |
