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 */ |