diff options
-rw-r--r-- | arch/arm/oprofile/common.c | 51 | ||||
-rw-r--r-- | drivers/oprofile/oprof.c | 11 |
2 files changed, 29 insertions, 33 deletions
diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c index 72e09eb642dd..bd7426ffedd0 100644 --- a/arch/arm/oprofile/common.c +++ b/arch/arm/oprofile/common.c | |||
@@ -276,7 +276,7 @@ out: | |||
276 | return ret; | 276 | return ret; |
277 | } | 277 | } |
278 | 278 | ||
279 | static void exit_driverfs(void) | 279 | static void __exit exit_driverfs(void) |
280 | { | 280 | { |
281 | platform_device_unregister(oprofile_pdev); | 281 | platform_device_unregister(oprofile_pdev); |
282 | platform_driver_unregister(&oprofile_driver); | 282 | platform_driver_unregister(&oprofile_driver); |
@@ -352,6 +352,8 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
352 | { | 352 | { |
353 | int cpu, ret = 0; | 353 | int cpu, ret = 0; |
354 | 354 | ||
355 | memset(&perf_events, 0, sizeof(perf_events)); | ||
356 | |||
355 | perf_num_counters = armpmu_get_max_events(); | 357 | perf_num_counters = armpmu_get_max_events(); |
356 | 358 | ||
357 | counter_config = kcalloc(perf_num_counters, | 359 | counter_config = kcalloc(perf_num_counters, |
@@ -360,15 +362,13 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
360 | if (!counter_config) { | 362 | if (!counter_config) { |
361 | pr_info("oprofile: failed to allocate %d " | 363 | pr_info("oprofile: failed to allocate %d " |
362 | "counters\n", perf_num_counters); | 364 | "counters\n", perf_num_counters); |
363 | return -ENOMEM; | 365 | ret = -ENOMEM; |
366 | goto out; | ||
364 | } | 367 | } |
365 | 368 | ||
366 | ret = init_driverfs(); | 369 | ret = init_driverfs(); |
367 | if (ret) { | 370 | if (ret) |
368 | kfree(counter_config); | 371 | goto out; |
369 | counter_config = NULL; | ||
370 | return ret; | ||
371 | } | ||
372 | 372 | ||
373 | for_each_possible_cpu(cpu) { | 373 | for_each_possible_cpu(cpu) { |
374 | perf_events[cpu] = kcalloc(perf_num_counters, | 374 | perf_events[cpu] = kcalloc(perf_num_counters, |
@@ -376,9 +376,8 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
376 | if (!perf_events[cpu]) { | 376 | if (!perf_events[cpu]) { |
377 | pr_info("oprofile: failed to allocate %d perf events " | 377 | pr_info("oprofile: failed to allocate %d perf events " |
378 | "for cpu %d\n", perf_num_counters, cpu); | 378 | "for cpu %d\n", perf_num_counters, cpu); |
379 | while (--cpu >= 0) | 379 | ret = -ENOMEM; |
380 | kfree(perf_events[cpu]); | 380 | goto out; |
381 | return -ENOMEM; | ||
382 | } | 381 | } |
383 | } | 382 | } |
384 | 383 | ||
@@ -395,29 +394,33 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
395 | else | 394 | else |
396 | pr_info("oprofile: using %s\n", ops->cpu_type); | 395 | pr_info("oprofile: using %s\n", ops->cpu_type); |
397 | 396 | ||
397 | out: | ||
398 | if (ret) { | ||
399 | for_each_possible_cpu(cpu) | ||
400 | kfree(perf_events[cpu]); | ||
401 | kfree(counter_config); | ||
402 | } | ||
403 | |||
398 | return ret; | 404 | return ret; |
399 | } | 405 | } |
400 | 406 | ||
401 | void oprofile_arch_exit(void) | 407 | void __exit oprofile_arch_exit(void) |
402 | { | 408 | { |
403 | int cpu, id; | 409 | int cpu, id; |
404 | struct perf_event *event; | 410 | struct perf_event *event; |
405 | 411 | ||
406 | if (*perf_events) { | 412 | for_each_possible_cpu(cpu) { |
407 | for_each_possible_cpu(cpu) { | 413 | for (id = 0; id < perf_num_counters; ++id) { |
408 | for (id = 0; id < perf_num_counters; ++id) { | 414 | event = perf_events[cpu][id]; |
409 | event = perf_events[cpu][id]; | 415 | if (event) |
410 | if (event != NULL) | 416 | perf_event_release_kernel(event); |
411 | perf_event_release_kernel(event); | ||
412 | } | ||
413 | kfree(perf_events[cpu]); | ||
414 | } | 417 | } |
415 | } | ||
416 | 418 | ||
417 | if (counter_config) { | 419 | kfree(perf_events[cpu]); |
418 | kfree(counter_config); | ||
419 | exit_driverfs(); | ||
420 | } | 420 | } |
421 | |||
422 | kfree(counter_config); | ||
423 | exit_driverfs(); | ||
421 | } | 424 | } |
422 | #else | 425 | #else |
423 | int __init oprofile_arch_init(struct oprofile_operations *ops) | 426 | int __init oprofile_arch_init(struct oprofile_operations *ops) |
@@ -425,5 +428,5 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
425 | pr_info("oprofile: hardware counters not available\n"); | 428 | pr_info("oprofile: hardware counters not available\n"); |
426 | return -ENODEV; | 429 | return -ENODEV; |
427 | } | 430 | } |
428 | void oprofile_arch_exit(void) {} | 431 | void __exit oprofile_arch_exit(void) {} |
429 | #endif /* CONFIG_HW_PERF_EVENTS */ | 432 | #endif /* CONFIG_HW_PERF_EVENTS */ |
diff --git a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c index b336cd9ee7a1..b4a685719dba 100644 --- a/drivers/oprofile/oprof.c +++ b/drivers/oprofile/oprof.c | |||
@@ -257,16 +257,9 @@ static int __init oprofile_init(void) | |||
257 | printk(KERN_INFO "oprofile: using timer interrupt.\n"); | 257 | printk(KERN_INFO "oprofile: using timer interrupt.\n"); |
258 | err = oprofile_timer_init(&oprofile_ops); | 258 | err = oprofile_timer_init(&oprofile_ops); |
259 | if (err) | 259 | if (err) |
260 | goto out_arch; | 260 | return err; |
261 | } | 261 | } |
262 | err = oprofilefs_register(); | 262 | return oprofilefs_register(); |
263 | if (err) | ||
264 | goto out_arch; | ||
265 | return 0; | ||
266 | |||
267 | out_arch: | ||
268 | oprofile_arch_exit(); | ||
269 | return err; | ||
270 | } | 263 | } |
271 | 264 | ||
272 | 265 | ||