diff options
Diffstat (limited to 'arch/x86/oprofile/op_model_p4.c')
-rw-r--r-- | arch/x86/oprofile/op_model_p4.c | 52 |
1 files changed, 31 insertions, 21 deletions
diff --git a/arch/x86/oprofile/op_model_p4.c b/arch/x86/oprofile/op_model_p4.c index e6a160a4684..182558dd551 100644 --- a/arch/x86/oprofile/op_model_p4.c +++ b/arch/x86/oprofile/op_model_p4.c | |||
@@ -385,8 +385,26 @@ static unsigned int get_stagger(void) | |||
385 | 385 | ||
386 | static unsigned long reset_value[NUM_COUNTERS_NON_HT]; | 386 | static unsigned long reset_value[NUM_COUNTERS_NON_HT]; |
387 | 387 | ||
388 | static void p4_shutdown(struct op_msrs const * const msrs) | ||
389 | { | ||
390 | int i; | ||
388 | 391 | ||
389 | static void p4_fill_in_addresses(struct op_msrs * const msrs) | 392 | for (i = 0; i < num_counters; ++i) { |
393 | if (msrs->counters[i].addr) | ||
394 | release_perfctr_nmi(msrs->counters[i].addr); | ||
395 | } | ||
396 | /* | ||
397 | * some of the control registers are specially reserved in | ||
398 | * conjunction with the counter registers (hence the starting offset). | ||
399 | * This saves a few bits. | ||
400 | */ | ||
401 | for (i = num_counters; i < num_controls; ++i) { | ||
402 | if (msrs->controls[i].addr) | ||
403 | release_evntsel_nmi(msrs->controls[i].addr); | ||
404 | } | ||
405 | } | ||
406 | |||
407 | static int p4_fill_in_addresses(struct op_msrs * const msrs) | ||
390 | { | 408 | { |
391 | unsigned int i; | 409 | unsigned int i; |
392 | unsigned int addr, cccraddr, stag; | 410 | unsigned int addr, cccraddr, stag; |
@@ -468,6 +486,18 @@ static void p4_fill_in_addresses(struct op_msrs * const msrs) | |||
468 | msrs->controls[i++].addr = MSR_P4_CRU_ESCR5; | 486 | msrs->controls[i++].addr = MSR_P4_CRU_ESCR5; |
469 | } | 487 | } |
470 | } | 488 | } |
489 | |||
490 | for (i = 0; i < num_counters; ++i) { | ||
491 | if (!counter_config[i].enabled) | ||
492 | continue; | ||
493 | if (msrs->controls[i].addr) | ||
494 | continue; | ||
495 | op_x86_warn_reserved(i); | ||
496 | p4_shutdown(msrs); | ||
497 | return -EBUSY; | ||
498 | } | ||
499 | |||
500 | return 0; | ||
471 | } | 501 | } |
472 | 502 | ||
473 | 503 | ||
@@ -668,26 +698,6 @@ static void p4_stop(struct op_msrs const * const msrs) | |||
668 | } | 698 | } |
669 | } | 699 | } |
670 | 700 | ||
671 | static void p4_shutdown(struct op_msrs const * const msrs) | ||
672 | { | ||
673 | int i; | ||
674 | |||
675 | for (i = 0; i < num_counters; ++i) { | ||
676 | if (msrs->counters[i].addr) | ||
677 | release_perfctr_nmi(msrs->counters[i].addr); | ||
678 | } | ||
679 | /* | ||
680 | * some of the control registers are specially reserved in | ||
681 | * conjunction with the counter registers (hence the starting offset). | ||
682 | * This saves a few bits. | ||
683 | */ | ||
684 | for (i = num_counters; i < num_controls; ++i) { | ||
685 | if (msrs->controls[i].addr) | ||
686 | release_evntsel_nmi(msrs->controls[i].addr); | ||
687 | } | ||
688 | } | ||
689 | |||
690 | |||
691 | #ifdef CONFIG_SMP | 701 | #ifdef CONFIG_SMP |
692 | struct op_x86_model_spec op_p4_ht2_spec = { | 702 | struct op_x86_model_spec op_p4_ht2_spec = { |
693 | .num_counters = NUM_COUNTERS_HT2, | 703 | .num_counters = NUM_COUNTERS_HT2, |