diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2010-10-01 13:52:44 +1000 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2010-10-01 13:52:44 +1000 |
commit | ac071b82000269a090046d161477b33543134b82 (patch) | |
tree | 395af561a233a2554282347a4fce46346476dcf5 /arch | |
parent | 410a55f8fdbfe28537970cdef61acc722452a3e7 (diff) | |
parent | b24a023edafabf430c2a84130e7720bb8e315e8f (diff) |
Merge remote branch 'oprofile/for-next'
Conflicts:
arch/arm/oprofile/common.c
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/oprofile/common.c | 52 |
1 files changed, 28 insertions, 24 deletions
diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c index d1fb5b2f5218..56c347acd52d 100644 --- a/arch/arm/oprofile/common.c +++ b/arch/arm/oprofile/common.c @@ -276,7 +276,7 @@ out: return ret; } -static void exit_driverfs(void) +static void __exit exit_driverfs(void) { platform_device_unregister(oprofile_pdev); platform_driver_unregister(&oprofile_driver); @@ -352,6 +352,8 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) { int cpu, ret = 0; + memset(&perf_events, 0, sizeof(perf_events)); + perf_num_counters = armpmu_get_max_events(); counter_config = kcalloc(perf_num_counters, @@ -360,15 +362,13 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) if (!counter_config) { pr_info("oprofile: failed to allocate %d " "counters\n", perf_num_counters); - return -ENOMEM; + ret = -ENOMEM; + goto out; } ret = init_driverfs(); - if (ret) { - kfree(counter_config); - counter_config = NULL; - return ret; - } + if (ret) + goto out; for_each_possible_cpu(cpu) { perf_events[cpu] = kcalloc(perf_num_counters, @@ -376,9 +376,8 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) if (!perf_events[cpu]) { pr_info("oprofile: failed to allocate %d perf events " "for cpu %d\n", perf_num_counters, cpu); - while (--cpu >= 0) - kfree(perf_events[cpu]); - return -ENOMEM; + ret = -ENOMEM; + goto out; } } @@ -395,29 +394,34 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) else pr_info("oprofile: using %s\n", ops->cpu_type); +out: + if (ret) { + for_each_possible_cpu(cpu) + kfree(perf_events[cpu]); + kfree(counter_config); + counter_config = NULL; + } + return ret; } -void oprofile_arch_exit(void) +void __exit oprofile_arch_exit(void) { int cpu, id; struct perf_event *event; - if (*perf_events) { - for_each_possible_cpu(cpu) { - for (id = 0; id < perf_num_counters; ++id) { - event = perf_events[cpu][id]; - if (event != NULL) - perf_event_release_kernel(event); - } - kfree(perf_events[cpu]); + 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); } - } - if (counter_config) { - kfree(counter_config); - exit_driverfs(); + kfree(perf_events[cpu]); } + + kfree(counter_config); + exit_driverfs(); } #else int __init oprofile_arch_init(struct oprofile_operations *ops) @@ -425,5 +429,5 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) pr_info("oprofile: hardware counters not available\n"); return -ENODEV; } -void oprofile_arch_exit(void) {} +void __exit oprofile_arch_exit(void) {} #endif /* CONFIG_HW_PERF_EVENTS */ |