diff options
author | Robert Richter <robert.richter@amd.com> | 2010-09-29 16:52:25 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2010-09-30 09:14:25 +0200 |
commit | 98d943b02f6f1b57787ff1aa6f34d019a407e3ee (patch) | |
tree | 164e086eae181e38b7ab25751f0b05928a4c2366 /arch/arm | |
parent | c7a27aa4652c63172489a73f3961455650a79a7f (diff) | |
download | linux-3.10-98d943b02f6f1b57787ff1aa6f34d019a407e3ee.tar.gz linux-3.10-98d943b02f6f1b57787ff1aa6f34d019a407e3ee.tar.bz2 linux-3.10-98d943b02f6f1b57787ff1aa6f34d019a407e3ee.zip |
oprofile, ARM: Release resources on failure
This patch fixes a resource leak on failure, where the
oprofilefs and some counters may not released properly.
Signed-off-by: Robert Richter <robert.richter@amd.com>
Acked-by: Will Deacon <will.deacon@arm.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: <stable@kernel.org> # .35.x
LKML-Reference: <20100929145225.GJ13563@erda.amd.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/oprofile/common.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c index 0691176899f..72e09eb642d 100644 --- a/arch/arm/oprofile/common.c +++ b/arch/arm/oprofile/common.c @@ -102,6 +102,7 @@ static int op_create_counter(int cpu, int event) if (IS_ERR(pevent)) { ret = PTR_ERR(pevent); } else if (pevent->state != PERF_EVENT_STATE_ACTIVE) { + perf_event_release_kernel(pevent); pr_warning("oprofile: failed to enable event %d " "on CPU %d\n", event, cpu); ret = -EBUSY; @@ -365,6 +366,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) ret = init_driverfs(); if (ret) { kfree(counter_config); + counter_config = NULL; return ret; } @@ -402,7 +404,6 @@ void oprofile_arch_exit(void) struct perf_event *event; if (*perf_events) { - exit_driverfs(); for_each_possible_cpu(cpu) { for (id = 0; id < perf_num_counters; ++id) { event = perf_events[cpu][id]; @@ -413,8 +414,10 @@ void oprofile_arch_exit(void) } } - if (counter_config) + if (counter_config) { kfree(counter_config); + exit_driverfs(); + } } #else int __init oprofile_arch_init(struct oprofile_operations *ops) |