aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Richter <robert.richter@amd.com>2010-09-29 09:42:30 -0400
committerRobert Richter <robert.richter@amd.com>2010-10-04 04:54:05 -0400
commit4d1814f48edec31f12737609cd1c871864c8298b (patch)
tree26cf216f99555256af0d39507219d8263919b981
parent5140434d5f82f2e2119926272ada2e9731ec04f1 (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.c53
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
351void 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
351int __init oprofile_arch_init(struct oprofile_operations *ops) 370int __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
397out: 417out:
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
407void __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
426int __init oprofile_arch_init(struct oprofile_operations *ops) 425int __init oprofile_arch_init(struct oprofile_operations *ops)
427{ 426{