diff options
author | Len Brown <len.brown@intel.com> | 2011-01-12 18:06:06 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2011-01-12 18:06:06 -0500 |
commit | 56dbed129df3fdd4caf9018b6e7599ee258a5420 (patch) | |
tree | b902491aef3a99efe0d9d49edd0f6e414dba654f /arch/x86/oprofile | |
parent | 2a2d31c8dc6f1ebcf5eab1d93a0cb0fb4ed57c7c (diff) | |
parent | f878133bf022717b880d0e0995b8f91436fd605c (diff) |
Merge branch 'linus' into idle-test
Diffstat (limited to 'arch/x86/oprofile')
-rw-r--r-- | arch/x86/oprofile/backtrace.c | 2 | ||||
-rw-r--r-- | arch/x86/oprofile/nmi_int.c | 8 | ||||
-rw-r--r-- | arch/x86/oprofile/nmi_timer_int.c | 5 | ||||
-rw-r--r-- | arch/x86/oprofile/op_model_amd.c | 55 | ||||
-rw-r--r-- | arch/x86/oprofile/op_model_p4.c | 2 | ||||
-rw-r--r-- | arch/x86/oprofile/op_model_ppro.c | 8 |
6 files changed, 49 insertions, 31 deletions
diff --git a/arch/x86/oprofile/backtrace.c b/arch/x86/oprofile/backtrace.c index 2d49d4e19a36..72cbec14d783 100644 --- a/arch/x86/oprofile/backtrace.c +++ b/arch/x86/oprofile/backtrace.c | |||
@@ -126,7 +126,7 @@ x86_backtrace(struct pt_regs * const regs, unsigned int depth) | |||
126 | if (!user_mode_vm(regs)) { | 126 | if (!user_mode_vm(regs)) { |
127 | unsigned long stack = kernel_stack_pointer(regs); | 127 | unsigned long stack = kernel_stack_pointer(regs); |
128 | if (depth) | 128 | if (depth) |
129 | dump_trace(NULL, regs, (unsigned long *)stack, 0, | 129 | dump_trace(NULL, regs, (unsigned long *)stack, |
130 | &backtrace_ops, &depth); | 130 | &backtrace_ops, &depth); |
131 | return; | 131 | return; |
132 | } | 132 | } |
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index 4e8baad36d37..e2b7b0c06cdf 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c | |||
@@ -65,7 +65,6 @@ static int profile_exceptions_notify(struct notifier_block *self, | |||
65 | 65 | ||
66 | switch (val) { | 66 | switch (val) { |
67 | case DIE_NMI: | 67 | case DIE_NMI: |
68 | case DIE_NMI_IPI: | ||
69 | if (ctr_running) | 68 | if (ctr_running) |
70 | model->check_ctrs(args->regs, &__get_cpu_var(cpu_msrs)); | 69 | model->check_ctrs(args->regs, &__get_cpu_var(cpu_msrs)); |
71 | else if (!nmi_enabled) | 70 | else if (!nmi_enabled) |
@@ -143,7 +142,7 @@ static inline int has_mux(void) | |||
143 | 142 | ||
144 | inline int op_x86_phys_to_virt(int phys) | 143 | inline int op_x86_phys_to_virt(int phys) |
145 | { | 144 | { |
146 | return __get_cpu_var(switch_index) + phys; | 145 | return __this_cpu_read(switch_index) + phys; |
147 | } | 146 | } |
148 | 147 | ||
149 | inline int op_x86_virt_to_phys(int virt) | 148 | inline int op_x86_virt_to_phys(int virt) |
@@ -361,7 +360,7 @@ static void nmi_cpu_setup(void *dummy) | |||
361 | static struct notifier_block profile_exceptions_nb = { | 360 | static struct notifier_block profile_exceptions_nb = { |
362 | .notifier_call = profile_exceptions_notify, | 361 | .notifier_call = profile_exceptions_notify, |
363 | .next = NULL, | 362 | .next = NULL, |
364 | .priority = 2 | 363 | .priority = NMI_LOCAL_LOW_PRIOR, |
365 | }; | 364 | }; |
366 | 365 | ||
367 | static void nmi_cpu_restore_registers(struct op_msrs *msrs) | 366 | static void nmi_cpu_restore_registers(struct op_msrs *msrs) |
@@ -732,6 +731,9 @@ int __init op_nmi_init(struct oprofile_operations *ops) | |||
732 | case 0x14: | 731 | case 0x14: |
733 | cpu_type = "x86-64/family14h"; | 732 | cpu_type = "x86-64/family14h"; |
734 | break; | 733 | break; |
734 | case 0x15: | ||
735 | cpu_type = "x86-64/family15h"; | ||
736 | break; | ||
735 | default: | 737 | default: |
736 | return -ENODEV; | 738 | return -ENODEV; |
737 | } | 739 | } |
diff --git a/arch/x86/oprofile/nmi_timer_int.c b/arch/x86/oprofile/nmi_timer_int.c index e3ecb71b5790..720bf5a53c51 100644 --- a/arch/x86/oprofile/nmi_timer_int.c +++ b/arch/x86/oprofile/nmi_timer_int.c | |||
@@ -38,7 +38,7 @@ static int profile_timer_exceptions_notify(struct notifier_block *self, | |||
38 | static struct notifier_block profile_timer_exceptions_nb = { | 38 | static struct notifier_block profile_timer_exceptions_nb = { |
39 | .notifier_call = profile_timer_exceptions_notify, | 39 | .notifier_call = profile_timer_exceptions_notify, |
40 | .next = NULL, | 40 | .next = NULL, |
41 | .priority = 0 | 41 | .priority = NMI_LOW_PRIOR, |
42 | }; | 42 | }; |
43 | 43 | ||
44 | static int timer_start(void) | 44 | static int timer_start(void) |
@@ -58,9 +58,6 @@ static void timer_stop(void) | |||
58 | 58 | ||
59 | int __init op_nmi_timer_init(struct oprofile_operations *ops) | 59 | int __init op_nmi_timer_init(struct oprofile_operations *ops) |
60 | { | 60 | { |
61 | if ((nmi_watchdog != NMI_IO_APIC) || (atomic_read(&nmi_active) <= 0)) | ||
62 | return -ENODEV; | ||
63 | |||
64 | ops->start = timer_start; | 61 | ops->start = timer_start; |
65 | ops->stop = timer_stop; | 62 | ops->stop = timer_stop; |
66 | ops->cpu_type = "timer"; | 63 | ops->cpu_type = "timer"; |
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c index 7d90d47655ba..c3b8e24f2b16 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); |
@@ -603,6 +610,7 @@ static int force_ibs_eilvt_setup(void) | |||
603 | ret = setup_ibs_ctl(i); | 610 | ret = setup_ibs_ctl(i); |
604 | if (ret) | 611 | if (ret) |
605 | return ret; | 612 | return ret; |
613 | pr_err(FW_BUG "using offset %d for IBS interrupts\n", i); | ||
606 | return 0; | 614 | return 0; |
607 | } | 615 | } |
608 | 616 | ||
@@ -706,18 +714,29 @@ static int setup_ibs_files(struct super_block *sb, struct dentry *root) | |||
706 | return 0; | 714 | return 0; |
707 | } | 715 | } |
708 | 716 | ||
717 | struct op_x86_model_spec op_amd_spec; | ||
718 | |||
709 | static int op_amd_init(struct oprofile_operations *ops) | 719 | static int op_amd_init(struct oprofile_operations *ops) |
710 | { | 720 | { |
711 | init_ibs(); | 721 | init_ibs(); |
712 | create_arch_files = ops->create_files; | 722 | create_arch_files = ops->create_files; |
713 | ops->create_files = setup_ibs_files; | 723 | ops->create_files = setup_ibs_files; |
724 | |||
725 | if (boot_cpu_data.x86 == 0x15) { | ||
726 | num_counters = NUM_COUNTERS_F15H; | ||
727 | } else { | ||
728 | num_counters = NUM_COUNTERS; | ||
729 | } | ||
730 | |||
731 | op_amd_spec.num_counters = num_counters; | ||
732 | op_amd_spec.num_controls = num_counters; | ||
733 | op_amd_spec.num_virt_counters = max(num_counters, NUM_VIRT_COUNTERS); | ||
734 | |||
714 | return 0; | 735 | return 0; |
715 | } | 736 | } |
716 | 737 | ||
717 | struct op_x86_model_spec op_amd_spec = { | 738 | struct op_x86_model_spec op_amd_spec = { |
718 | .num_counters = NUM_COUNTERS, | 739 | /* num_counters/num_controls filled in at runtime */ |
719 | .num_controls = NUM_COUNTERS, | ||
720 | .num_virt_counters = NUM_VIRT_COUNTERS, | ||
721 | .reserved = MSR_AMD_EVENTSEL_RESERVED, | 740 | .reserved = MSR_AMD_EVENTSEL_RESERVED, |
722 | .event_mask = OP_EVENT_MASK, | 741 | .event_mask = OP_EVENT_MASK, |
723 | .init = op_amd_init, | 742 | .init = op_amd_init, |
diff --git a/arch/x86/oprofile/op_model_p4.c b/arch/x86/oprofile/op_model_p4.c index 182558dd5515..9fadec074142 100644 --- a/arch/x86/oprofile/op_model_p4.c +++ b/arch/x86/oprofile/op_model_p4.c | |||
@@ -11,7 +11,7 @@ | |||
11 | #include <linux/oprofile.h> | 11 | #include <linux/oprofile.h> |
12 | #include <linux/smp.h> | 12 | #include <linux/smp.h> |
13 | #include <linux/ptrace.h> | 13 | #include <linux/ptrace.h> |
14 | #include <linux/nmi.h> | 14 | #include <asm/nmi.h> |
15 | #include <asm/msr.h> | 15 | #include <asm/msr.h> |
16 | #include <asm/fixmap.h> | 16 | #include <asm/fixmap.h> |
17 | #include <asm/apic.h> | 17 | #include <asm/apic.h> |
diff --git a/arch/x86/oprofile/op_model_ppro.c b/arch/x86/oprofile/op_model_ppro.c index d769cda54082..94b745045e45 100644 --- a/arch/x86/oprofile/op_model_ppro.c +++ b/arch/x86/oprofile/op_model_ppro.c | |||
@@ -95,8 +95,8 @@ static void ppro_setup_ctrs(struct op_x86_model_spec const *model, | |||
95 | * counter width: | 95 | * counter width: |
96 | */ | 96 | */ |
97 | if (!(eax.split.version_id == 0 && | 97 | if (!(eax.split.version_id == 0 && |
98 | current_cpu_data.x86 == 6 && | 98 | __this_cpu_read(cpu_info.x86) == 6 && |
99 | current_cpu_data.x86_model == 15)) { | 99 | __this_cpu_read(cpu_info.x86_model) == 15)) { |
100 | 100 | ||
101 | if (counter_width < eax.split.bit_width) | 101 | if (counter_width < eax.split.bit_width) |
102 | counter_width = eax.split.bit_width; | 102 | counter_width = eax.split.bit_width; |
@@ -235,8 +235,8 @@ static void arch_perfmon_setup_counters(void) | |||
235 | eax.full = cpuid_eax(0xa); | 235 | eax.full = cpuid_eax(0xa); |
236 | 236 | ||
237 | /* Workaround for BIOS bugs in 6/15. Taken from perfmon2 */ | 237 | /* Workaround for BIOS bugs in 6/15. Taken from perfmon2 */ |
238 | if (eax.split.version_id == 0 && current_cpu_data.x86 == 6 && | 238 | if (eax.split.version_id == 0 && __this_cpu_read(cpu_info.x86) == 6 && |
239 | current_cpu_data.x86_model == 15) { | 239 | __this_cpu_read(cpu_info.x86_model) == 15) { |
240 | eax.split.version_id = 2; | 240 | eax.split.version_id = 2; |
241 | eax.split.num_counters = 2; | 241 | eax.split.num_counters = 2; |
242 | eax.split.bit_width = 40; | 242 | eax.split.bit_width = 40; |