diff options
| -rw-r--r-- | arch/arm/oprofile/common.c | 47 |
1 files changed, 25 insertions, 22 deletions
diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c index 0691176899ff..c3652f73fed4 100644 --- a/arch/arm/oprofile/common.c +++ b/arch/arm/oprofile/common.c | |||
| @@ -275,7 +275,7 @@ out: | |||
| 275 | return ret; | 275 | return ret; |
| 276 | } | 276 | } |
| 277 | 277 | ||
| 278 | static void exit_driverfs(void) | 278 | static void __exit exit_driverfs(void) |
| 279 | { | 279 | { |
| 280 | platform_device_unregister(oprofile_pdev); | 280 | platform_device_unregister(oprofile_pdev); |
| 281 | platform_driver_unregister(&oprofile_driver); | 281 | platform_driver_unregister(&oprofile_driver); |
| @@ -359,14 +359,13 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
| 359 | if (!counter_config) { | 359 | if (!counter_config) { |
| 360 | pr_info("oprofile: failed to allocate %d " | 360 | pr_info("oprofile: failed to allocate %d " |
| 361 | "counters\n", perf_num_counters); | 361 | "counters\n", perf_num_counters); |
| 362 | return -ENOMEM; | 362 | ret = -ENOMEM; |
| 363 | goto out; | ||
| 363 | } | 364 | } |
| 364 | 365 | ||
| 365 | ret = init_driverfs(); | 366 | ret = init_driverfs(); |
| 366 | if (ret) { | 367 | if (ret) |
| 367 | kfree(counter_config); | 368 | goto out; |
| 368 | return ret; | ||
| 369 | } | ||
| 370 | 369 | ||
| 371 | for_each_possible_cpu(cpu) { | 370 | for_each_possible_cpu(cpu) { |
| 372 | perf_events[cpu] = kcalloc(perf_num_counters, | 371 | perf_events[cpu] = kcalloc(perf_num_counters, |
| @@ -374,9 +373,8 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
| 374 | if (!perf_events[cpu]) { | 373 | if (!perf_events[cpu]) { |
| 375 | pr_info("oprofile: failed to allocate %d perf events " | 374 | pr_info("oprofile: failed to allocate %d perf events " |
| 376 | "for cpu %d\n", perf_num_counters, cpu); | 375 | "for cpu %d\n", perf_num_counters, cpu); |
| 377 | while (--cpu >= 0) | 376 | ret = -ENOMEM; |
| 378 | kfree(perf_events[cpu]); | 377 | goto out; |
| 379 | return -ENOMEM; | ||
| 380 | } | 378 | } |
| 381 | } | 379 | } |
| 382 | 380 | ||
| @@ -393,28 +391,33 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
| 393 | else | 391 | else |
| 394 | pr_info("oprofile: using %s\n", ops->cpu_type); | 392 | pr_info("oprofile: using %s\n", ops->cpu_type); |
| 395 | 393 | ||
| 394 | out: | ||
| 395 | if (ret) { | ||
| 396 | for_each_possible_cpu(cpu) | ||
| 397 | kfree(perf_events[cpu]); | ||
| 398 | kfree(counter_config); | ||
| 399 | } | ||
| 400 | |||
| 396 | return ret; | 401 | return ret; |
| 397 | } | 402 | } |
| 398 | 403 | ||
| 399 | void oprofile_arch_exit(void) | 404 | void __exit oprofile_arch_exit(void) |
| 400 | { | 405 | { |
| 401 | int cpu, id; | 406 | int cpu, id; |
| 402 | struct perf_event *event; | 407 | struct perf_event *event; |
| 403 | 408 | ||
| 404 | if (*perf_events) { | 409 | for_each_possible_cpu(cpu) { |
| 405 | exit_driverfs(); | 410 | for (id = 0; id < perf_num_counters; ++id) { |
| 406 | for_each_possible_cpu(cpu) { | 411 | event = perf_events[cpu][id]; |
| 407 | for (id = 0; id < perf_num_counters; ++id) { | 412 | if (event) |
| 408 | event = perf_events[cpu][id]; | 413 | perf_event_release_kernel(event); |
| 409 | if (event != NULL) | ||
| 410 | perf_event_release_kernel(event); | ||
| 411 | } | ||
| 412 | kfree(perf_events[cpu]); | ||
| 413 | } | 414 | } |
| 415 | |||
| 416 | kfree(perf_events[cpu]); | ||
| 414 | } | 417 | } |
| 415 | 418 | ||
| 416 | if (counter_config) | 419 | kfree(counter_config); |
| 417 | kfree(counter_config); | 420 | exit_driverfs(); |
| 418 | } | 421 | } |
| 419 | #else | 422 | #else |
| 420 | int __init oprofile_arch_init(struct oprofile_operations *ops) | 423 | int __init oprofile_arch_init(struct oprofile_operations *ops) |
| @@ -422,5 +425,5 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
| 422 | pr_info("oprofile: hardware counters not available\n"); | 425 | pr_info("oprofile: hardware counters not available\n"); |
| 423 | return -ENODEV; | 426 | return -ENODEV; |
| 424 | } | 427 | } |
| 425 | void oprofile_arch_exit(void) {} | 428 | void __exit oprofile_arch_exit(void) {} |
| 426 | #endif /* CONFIG_HW_PERF_EVENTS */ | 429 | #endif /* CONFIG_HW_PERF_EVENTS */ |
