oprofile, ARM: Use oprofile_arch_exit() to cleanup on failure
authorRobert Richter <robert.richter@amd.com>
Wed, 29 Sep 2010 13:42:30 +0000 (15:42 +0200)
committerRobert Richter <robert.richter@amd.com>
Mon, 4 Oct 2010 08:54:05 +0000 (10:54 +0200)
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>
arch/arm/oprofile/common.c

index bd7426ffedd0fbc632032c54b00c915ba7d4ccd6..7ae9eebe7efc44f0e80f771f61967f40a3aa9a6d 100644 (file)
@@ -348,10 +348,33 @@ static void arm_backtrace(struct pt_regs * const regs, unsigned int depth)
                tail = user_backtrace(tail);
 }
 
+void oprofile_arch_exit(void)
+{
+       int cpu, id;
+       struct perf_event *event;
+
+       for_each_possible_cpu(cpu) {
+               for (id = 0; id < perf_num_counters; ++id) {
+                       event = perf_events[cpu][id];
+                       if (event)
+                               perf_event_release_kernel(event);
+               }
+
+               kfree(perf_events[cpu]);
+       }
+
+       kfree(counter_config);
+       exit_driverfs();
+}
+
 int __init oprofile_arch_init(struct oprofile_operations *ops)
 {
        int cpu, ret = 0;
 
+       ret = init_driverfs();
+       if (ret)
+               return ret;
+
        memset(&perf_events, 0, sizeof(perf_events));
 
        perf_num_counters = armpmu_get_max_events();
@@ -363,13 +386,10 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
                pr_info("oprofile: failed to allocate %d "
                                "counters\n", perf_num_counters);
                ret = -ENOMEM;
+               perf_num_counters = 0;
                goto out;
        }
 
-       ret = init_driverfs();
-       if (ret)
-               goto out;
-
        for_each_possible_cpu(cpu) {
                perf_events[cpu] = kcalloc(perf_num_counters,
                                sizeof(struct perf_event *), GFP_KERNEL);
@@ -395,33 +415,12 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
                pr_info("oprofile: using %s\n", ops->cpu_type);
 
 out:
-       if (ret) {
-               for_each_possible_cpu(cpu)
-                       kfree(perf_events[cpu]);
-               kfree(counter_config);
-       }
+       if (ret)
+               oprofile_arch_exit();
 
        return ret;
 }
 
-void __exit oprofile_arch_exit(void)
-{
-       int cpu, id;
-       struct perf_event *event;
-
-       for_each_possible_cpu(cpu) {
-               for (id = 0; id < perf_num_counters; ++id) {
-                       event = perf_events[cpu][id];
-                       if (event)
-                               perf_event_release_kernel(event);
-               }
-
-               kfree(perf_events[cpu]);
-       }
-
-       kfree(counter_config);
-       exit_driverfs();
-}
 #else
 int __init oprofile_arch_init(struct oprofile_operations *ops)
 {