aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/oprofile/common.c47
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
278static void exit_driverfs(void) 278static 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
394out:
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
399void oprofile_arch_exit(void) 404void __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
420int __init oprofile_arch_init(struct oprofile_operations *ops) 423int __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}
425void oprofile_arch_exit(void) {} 428void __exit oprofile_arch_exit(void) {}
426#endif /* CONFIG_HW_PERF_EVENTS */ 429#endif /* CONFIG_HW_PERF_EVENTS */