diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/oprofile/nmi_int.c | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index 2c505ee71014..c0c21f200faf 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c | |||
@@ -295,6 +295,7 @@ static void free_msrs(void) | |||
295 | kfree(per_cpu(cpu_msrs, i).controls); | 295 | kfree(per_cpu(cpu_msrs, i).controls); |
296 | per_cpu(cpu_msrs, i).controls = NULL; | 296 | per_cpu(cpu_msrs, i).controls = NULL; |
297 | } | 297 | } |
298 | nmi_shutdown_mux(); | ||
298 | } | 299 | } |
299 | 300 | ||
300 | static int allocate_msrs(void) | 301 | static int allocate_msrs(void) |
@@ -307,14 +308,21 @@ static int allocate_msrs(void) | |||
307 | per_cpu(cpu_msrs, i).counters = kzalloc(counters_size, | 308 | per_cpu(cpu_msrs, i).counters = kzalloc(counters_size, |
308 | GFP_KERNEL); | 309 | GFP_KERNEL); |
309 | if (!per_cpu(cpu_msrs, i).counters) | 310 | if (!per_cpu(cpu_msrs, i).counters) |
310 | return 0; | 311 | goto fail; |
311 | per_cpu(cpu_msrs, i).controls = kzalloc(controls_size, | 312 | per_cpu(cpu_msrs, i).controls = kzalloc(controls_size, |
312 | GFP_KERNEL); | 313 | GFP_KERNEL); |
313 | if (!per_cpu(cpu_msrs, i).controls) | 314 | if (!per_cpu(cpu_msrs, i).controls) |
314 | return 0; | 315 | goto fail; |
315 | } | 316 | } |
316 | 317 | ||
318 | if (!nmi_setup_mux()) | ||
319 | goto fail; | ||
320 | |||
317 | return 1; | 321 | return 1; |
322 | |||
323 | fail: | ||
324 | free_msrs(); | ||
325 | return 0; | ||
318 | } | 326 | } |
319 | 327 | ||
320 | static void nmi_cpu_setup(void *dummy) | 328 | static void nmi_cpu_setup(void *dummy) |
@@ -342,17 +350,7 @@ static int nmi_setup(void) | |||
342 | int cpu; | 350 | int cpu; |
343 | 351 | ||
344 | if (!allocate_msrs()) | 352 | if (!allocate_msrs()) |
345 | err = -ENOMEM; | 353 | return -ENOMEM; |
346 | else if (!nmi_setup_mux()) | ||
347 | err = -ENOMEM; | ||
348 | else | ||
349 | err = register_die_notifier(&profile_exceptions_nb); | ||
350 | |||
351 | if (err) { | ||
352 | free_msrs(); | ||
353 | nmi_shutdown_mux(); | ||
354 | return err; | ||
355 | } | ||
356 | 354 | ||
357 | /* We need to serialize save and setup for HT because the subset | 355 | /* We need to serialize save and setup for HT because the subset |
358 | * of msrs are distinct for save and setup operations | 356 | * of msrs are distinct for save and setup operations |
@@ -374,9 +372,17 @@ static int nmi_setup(void) | |||
374 | 372 | ||
375 | mux_clone(cpu); | 373 | mux_clone(cpu); |
376 | } | 374 | } |
375 | |||
376 | err = register_die_notifier(&profile_exceptions_nb); | ||
377 | if (err) | ||
378 | goto fail; | ||
379 | |||
377 | on_each_cpu(nmi_cpu_setup, NULL, 1); | 380 | on_each_cpu(nmi_cpu_setup, NULL, 1); |
378 | nmi_enabled = 1; | 381 | nmi_enabled = 1; |
379 | return 0; | 382 | return 0; |
383 | fail: | ||
384 | free_msrs(); | ||
385 | return err; | ||
380 | } | 386 | } |
381 | 387 | ||
382 | static void nmi_cpu_restore_registers(struct op_msrs *msrs) | 388 | static void nmi_cpu_restore_registers(struct op_msrs *msrs) |
@@ -421,7 +427,6 @@ static void nmi_shutdown(void) | |||
421 | nmi_enabled = 0; | 427 | nmi_enabled = 0; |
422 | on_each_cpu(nmi_cpu_shutdown, NULL, 1); | 428 | on_each_cpu(nmi_cpu_shutdown, NULL, 1); |
423 | unregister_die_notifier(&profile_exceptions_nb); | 429 | unregister_die_notifier(&profile_exceptions_nb); |
424 | nmi_shutdown_mux(); | ||
425 | msrs = &get_cpu_var(cpu_msrs); | 430 | msrs = &get_cpu_var(cpu_msrs); |
426 | model->shutdown(msrs); | 431 | model->shutdown(msrs); |
427 | free_msrs(); | 432 | free_msrs(); |