diff options
| -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(); |
