diff options
| author | Ingo Molnar <mingo@elte.hu> | 2010-12-30 05:26:45 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2010-12-30 05:26:45 -0500 |
| commit | 56f4c400349157289b474a3fd49ee96acab0a4d7 (patch) | |
| tree | fe6fa38a2e4b87f301da7145cf01cd64df47e9ec | |
| parent | 32ae2ade462146729580117d9886cc9efd83dfbe (diff) | |
| parent | da169f5df2764a6a937cb3b07562e269edfb1c0e (diff) | |
Merge branch 'core' of git://git.kernel.org/pub/scm/linux/kernel/git/rric/oprofile into perf/core
| -rw-r--r-- | arch/x86/include/asm/msr-index.h | 4 | ||||
| -rw-r--r-- | arch/x86/oprofile/nmi_int.c | 3 | ||||
| -rw-r--r-- | arch/x86/oprofile/op_model_amd.c | 54 |
3 files changed, 43 insertions, 18 deletions
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 6b89f5e8602..86030f63ba0 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h | |||
| @@ -123,6 +123,10 @@ | |||
| 123 | #define MSR_AMD64_IBSCTL 0xc001103a | 123 | #define MSR_AMD64_IBSCTL 0xc001103a |
| 124 | #define MSR_AMD64_IBSBRTARGET 0xc001103b | 124 | #define MSR_AMD64_IBSBRTARGET 0xc001103b |
| 125 | 125 | ||
| 126 | /* Fam 15h MSRs */ | ||
| 127 | #define MSR_F15H_PERF_CTL 0xc0010200 | ||
| 128 | #define MSR_F15H_PERF_CTR 0xc0010201 | ||
| 129 | |||
| 126 | /* Fam 10h MSRs */ | 130 | /* Fam 10h MSRs */ |
| 127 | #define MSR_FAM10H_MMIO_CONF_BASE 0xc0010058 | 131 | #define MSR_FAM10H_MMIO_CONF_BASE 0xc0010058 |
| 128 | #define FAM10H_MMIO_CONF_ENABLE (1<<0) | 132 | #define FAM10H_MMIO_CONF_ENABLE (1<<0) |
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index 4e8baad36d3..358c8b9c96a 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c | |||
| @@ -732,6 +732,9 @@ int __init op_nmi_init(struct oprofile_operations *ops) | |||
| 732 | case 0x14: | 732 | case 0x14: |
| 733 | cpu_type = "x86-64/family14h"; | 733 | cpu_type = "x86-64/family14h"; |
| 734 | break; | 734 | break; |
| 735 | case 0x15: | ||
| 736 | cpu_type = "x86-64/family15h"; | ||
| 737 | break; | ||
| 735 | default: | 738 | default: |
| 736 | return -ENODEV; | 739 | return -ENODEV; |
| 737 | } | 740 | } |
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c index a011bcc0f94..f2984d43a6b 100644 --- a/arch/x86/oprofile/op_model_amd.c +++ b/arch/x86/oprofile/op_model_amd.c | |||
| @@ -29,11 +29,12 @@ | |||
| 29 | #include "op_x86_model.h" | 29 | #include "op_x86_model.h" |
| 30 | #include "op_counter.h" | 30 | #include "op_counter.h" |
| 31 | 31 | ||
| 32 | #define NUM_COUNTERS 4 | 32 | #define NUM_COUNTERS 4 |
| 33 | #define NUM_COUNTERS_F15H 6 | ||
| 33 | #ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX | 34 | #ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX |
| 34 | #define NUM_VIRT_COUNTERS 32 | 35 | #define NUM_VIRT_COUNTERS 32 |
| 35 | #else | 36 | #else |
| 36 | #define NUM_VIRT_COUNTERS NUM_COUNTERS | 37 | #define NUM_VIRT_COUNTERS 0 |
| 37 | #endif | 38 | #endif |
| 38 | 39 | ||
| 39 | #define OP_EVENT_MASK 0x0FFF | 40 | #define OP_EVENT_MASK 0x0FFF |
| @@ -41,7 +42,8 @@ | |||
| 41 | 42 | ||
| 42 | #define MSR_AMD_EVENTSEL_RESERVED ((0xFFFFFCF0ULL<<32)|(1ULL<<21)) | 43 | #define MSR_AMD_EVENTSEL_RESERVED ((0xFFFFFCF0ULL<<32)|(1ULL<<21)) |
| 43 | 44 | ||
| 44 | static unsigned long reset_value[NUM_VIRT_COUNTERS]; | 45 | static int num_counters; |
| 46 | static unsigned long reset_value[OP_MAX_COUNTER]; | ||
| 45 | 47 | ||
| 46 | #define IBS_FETCH_SIZE 6 | 48 | #define IBS_FETCH_SIZE 6 |
| 47 | #define IBS_OP_SIZE 12 | 49 | #define IBS_OP_SIZE 12 |
| @@ -387,7 +389,7 @@ static void op_mux_switch_ctrl(struct op_x86_model_spec const *model, | |||
| 387 | int i; | 389 | int i; |
| 388 | 390 | ||
| 389 | /* enable active counters */ | 391 | /* enable active counters */ |
| 390 | for (i = 0; i < NUM_COUNTERS; ++i) { | 392 | for (i = 0; i < num_counters; ++i) { |
| 391 | int virt = op_x86_phys_to_virt(i); | 393 | int virt = op_x86_phys_to_virt(i); |
| 392 | if (!reset_value[virt]) | 394 | if (!reset_value[virt]) |
| 393 | continue; | 395 | continue; |
| @@ -406,7 +408,7 @@ static void op_amd_shutdown(struct op_msrs const * const msrs) | |||
| 406 | { | 408 | { |
| 407 | int i; | 409 | int i; |
| 408 | 410 | ||
| 409 | for (i = 0; i < NUM_COUNTERS; ++i) { | 411 | for (i = 0; i < num_counters; ++i) { |
| 410 | if (!msrs->counters[i].addr) | 412 | if (!msrs->counters[i].addr) |
| 411 | continue; | 413 | continue; |
| 412 | release_perfctr_nmi(MSR_K7_PERFCTR0 + i); | 414 | release_perfctr_nmi(MSR_K7_PERFCTR0 + i); |
| @@ -418,7 +420,7 @@ static int op_amd_fill_in_addresses(struct op_msrs * const msrs) | |||
| 418 | { | 420 | { |
| 419 | int i; | 421 | int i; |
| 420 | 422 | ||
| 421 | for (i = 0; i < NUM_COUNTERS; i++) { | 423 | for (i = 0; i < num_counters; i++) { |
| 422 | if (!reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i)) | 424 | if (!reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i)) |
| 423 | goto fail; | 425 | goto fail; |
| 424 | if (!reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i)) { | 426 | if (!reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i)) { |
| @@ -426,8 +428,13 @@ static int op_amd_fill_in_addresses(struct op_msrs * const msrs) | |||
| 426 | goto fail; | 428 | goto fail; |
| 427 | } | 429 | } |
| 428 | /* both registers must be reserved */ | 430 | /* both registers must be reserved */ |
| 429 | msrs->counters[i].addr = MSR_K7_PERFCTR0 + i; | 431 | if (num_counters == NUM_COUNTERS_F15H) { |
| 430 | msrs->controls[i].addr = MSR_K7_EVNTSEL0 + i; | 432 | msrs->counters[i].addr = MSR_F15H_PERF_CTR + (i << 1); |
| 433 | msrs->controls[i].addr = MSR_F15H_PERF_CTL + (i << 1); | ||
| 434 | } else { | ||
| 435 | msrs->controls[i].addr = MSR_K7_EVNTSEL0 + i; | ||
| 436 | msrs->counters[i].addr = MSR_K7_PERFCTR0 + i; | ||
| 437 | } | ||
| 431 | continue; | 438 | continue; |
| 432 | fail: | 439 | fail: |
| 433 | if (!counter_config[i].enabled) | 440 | if (!counter_config[i].enabled) |
| @@ -447,7 +454,7 @@ static void op_amd_setup_ctrs(struct op_x86_model_spec const *model, | |||
| 447 | int i; | 454 | int i; |
| 448 | 455 | ||
| 449 | /* setup reset_value */ | 456 | /* setup reset_value */ |
| 450 | for (i = 0; i < NUM_VIRT_COUNTERS; ++i) { | 457 | for (i = 0; i < OP_MAX_COUNTER; ++i) { |
| 451 | if (counter_config[i].enabled | 458 | if (counter_config[i].enabled |
| 452 | && msrs->counters[op_x86_virt_to_phys(i)].addr) | 459 | && msrs->counters[op_x86_virt_to_phys(i)].addr) |
| 453 | reset_value[i] = counter_config[i].count; | 460 | reset_value[i] = counter_config[i].count; |
| @@ -456,7 +463,7 @@ static void op_amd_setup_ctrs(struct op_x86_model_spec const *model, | |||
| 456 | } | 463 | } |
| 457 | 464 | ||
| 458 | /* clear all counters */ | 465 | /* clear all counters */ |
| 459 | for (i = 0; i < NUM_COUNTERS; ++i) { | 466 | for (i = 0; i < num_counters; ++i) { |
| 460 | if (!msrs->controls[i].addr) | 467 | if (!msrs->controls[i].addr) |
| 461 | continue; | 468 | continue; |
| 462 | rdmsrl(msrs->controls[i].addr, val); | 469 | rdmsrl(msrs->controls[i].addr, val); |
| @@ -472,7 +479,7 @@ static void op_amd_setup_ctrs(struct op_x86_model_spec const *model, | |||
| 472 | } | 479 | } |
| 473 | 480 | ||
| 474 | /* enable active counters */ | 481 | /* enable active counters */ |
| 475 | for (i = 0; i < NUM_COUNTERS; ++i) { | 482 | for (i = 0; i < num_counters; ++i) { |
| 476 | int virt = op_x86_phys_to_virt(i); | 483 | int virt = op_x86_phys_to_virt(i); |
| 477 | if (!reset_value[virt]) | 484 | if (!reset_value[virt]) |
| 478 | continue; | 485 | continue; |
| @@ -503,7 +510,7 @@ static int op_amd_check_ctrs(struct pt_regs * const regs, | |||
| 503 | u64 val; | 510 | u64 val; |
| 504 | int i; | 511 | int i; |
| 505 | 512 | ||
| 506 | for (i = 0; i < NUM_COUNTERS; ++i) { | 513 | for (i = 0; i < num_counters; ++i) { |
| 507 | int virt = op_x86_phys_to_virt(i); | 514 | int virt = op_x86_phys_to_virt(i); |
| 508 | if (!reset_value[virt]) | 515 | if (!reset_value[virt]) |
| 509 | continue; | 516 | continue; |
| @@ -526,7 +533,7 @@ static void op_amd_start(struct op_msrs const * const msrs) | |||
| 526 | u64 val; | 533 | u64 val; |
| 527 | int i; | 534 | int i; |
| 528 | 535 | ||
| 529 | for (i = 0; i < NUM_COUNTERS; ++i) { | 536 | for (i = 0; i < num_counters; ++i) { |
| 530 | if (!reset_value[op_x86_phys_to_virt(i)]) | 537 | if (!reset_value[op_x86_phys_to_virt(i)]) |
| 531 | continue; | 538 | continue; |
| 532 | rdmsrl(msrs->controls[i].addr, val); | 539 | rdmsrl(msrs->controls[i].addr, val); |
| @@ -546,7 +553,7 @@ static void op_amd_stop(struct op_msrs const * const msrs) | |||
| 546 | * Subtle: stop on all counters to avoid race with setting our | 553 | * Subtle: stop on all counters to avoid race with setting our |
| 547 | * pm callback | 554 | * pm callback |
| 548 | */ | 555 | */ |
| 549 | for (i = 0; i < NUM_COUNTERS; ++i) { | 556 | for (i = 0; i < num_counters; ++i) { |
| 550 | if (!reset_value[op_x86_phys_to_virt(i)]) | 557 | if (!reset_value[op_x86_phys_to_virt(i)]) |
| 551 | continue; | 558 | continue; |
| 552 | rdmsrl(msrs->controls[i].addr, val); | 559 | rdmsrl(msrs->controls[i].addr, val); |
| @@ -698,18 +705,29 @@ static int setup_ibs_files(struct super_block *sb, struct dentry *root) | |||
| 698 | return 0; | 705 | return 0; |
| 699 | } | 706 | } |
| 700 | 707 | ||
| 708 | struct op_x86_model_spec op_amd_spec; | ||
| 709 | |||
| 701 | static int op_amd_init(struct oprofile_operations *ops) | 710 | static int op_amd_init(struct oprofile_operations *ops) |
| 702 | { | 711 | { |
| 703 | init_ibs(); | 712 | init_ibs(); |
| 704 | create_arch_files = ops->create_files; | 713 | create_arch_files = ops->create_files; |
| 705 | ops->create_files = setup_ibs_files; | 714 | ops->create_files = setup_ibs_files; |
| 715 | |||
| 716 | if (boot_cpu_data.x86 == 0x15) { | ||
| 717 | num_counters = NUM_COUNTERS_F15H; | ||
| 718 | } else { | ||
| 719 | num_counters = NUM_COUNTERS; | ||
| 720 | } | ||
| 721 | |||
| 722 | op_amd_spec.num_counters = num_counters; | ||
| 723 | op_amd_spec.num_controls = num_counters; | ||
| 724 | op_amd_spec.num_virt_counters = max(num_counters, NUM_VIRT_COUNTERS); | ||
| 725 | |||
| 706 | return 0; | 726 | return 0; |
| 707 | } | 727 | } |
| 708 | 728 | ||
| 709 | struct op_x86_model_spec op_amd_spec = { | 729 | struct op_x86_model_spec op_amd_spec = { |
| 710 | .num_counters = NUM_COUNTERS, | 730 | /* num_counters/num_controls filled in at runtime */ |
| 711 | .num_controls = NUM_COUNTERS, | ||
| 712 | .num_virt_counters = NUM_VIRT_COUNTERS, | ||
| 713 | .reserved = MSR_AMD_EVENTSEL_RESERVED, | 731 | .reserved = MSR_AMD_EVENTSEL_RESERVED, |
| 714 | .event_mask = OP_EVENT_MASK, | 732 | .event_mask = OP_EVENT_MASK, |
| 715 | .init = op_amd_init, | 733 | .init = op_amd_init, |
