diff options
author | Dirk Brandewie <dirk.j.brandewie@intel.com> | 2014-01-16 13:32:25 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-01-16 20:00:44 -0500 |
commit | b69880f9ccf7e13b2e2cb38f49a2451d7aa548b3 (patch) | |
tree | 65f402f165b9b4f33ccac597202a82acfe845bdf | |
parent | 652ed95d5fa6074b3c4ea245deb0691f1acb6656 (diff) |
intel_pstate: Add trace point to report internal state.
Add perf trace event "power:pstate_sample" to report driver state to
aid in diagnosing issues reported against intel_pstate.
Signed-off-by: Dirk Brandewie <dirk.j.brandewie@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | drivers/cpufreq/intel_pstate.c | 24 | ||||
-rw-r--r-- | include/trace/events/power.h | 53 |
2 files changed, 77 insertions, 0 deletions
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index fe91dad8f5e2..7e257b233602 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
@@ -51,6 +51,8 @@ static inline int32_t div_fp(int32_t x, int32_t y) | |||
51 | return div_s64((int64_t)x << FRAC_BITS, (int64_t)y); | 51 | return div_s64((int64_t)x << FRAC_BITS, (int64_t)y); |
52 | } | 52 | } |
53 | 53 | ||
54 | static u64 energy_divisor; | ||
55 | |||
54 | struct sample { | 56 | struct sample { |
55 | int32_t core_pct_busy; | 57 | int32_t core_pct_busy; |
56 | u64 aperf; | 58 | u64 aperf; |
@@ -559,6 +561,7 @@ static inline void intel_pstate_sample(struct cpudata *cpu) | |||
559 | 561 | ||
560 | rdmsrl(MSR_IA32_APERF, aperf); | 562 | rdmsrl(MSR_IA32_APERF, aperf); |
561 | rdmsrl(MSR_IA32_MPERF, mperf); | 563 | rdmsrl(MSR_IA32_MPERF, mperf); |
564 | |||
562 | cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT; | 565 | cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT; |
563 | cpu->samples[cpu->sample_ptr].aperf = aperf; | 566 | cpu->samples[cpu->sample_ptr].aperf = aperf; |
564 | cpu->samples[cpu->sample_ptr].mperf = mperf; | 567 | cpu->samples[cpu->sample_ptr].mperf = mperf; |
@@ -603,6 +606,7 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu) | |||
603 | ctl = pid_calc(pid, busy_scaled); | 606 | ctl = pid_calc(pid, busy_scaled); |
604 | 607 | ||
605 | steps = abs(ctl); | 608 | steps = abs(ctl); |
609 | |||
606 | if (ctl < 0) | 610 | if (ctl < 0) |
607 | intel_pstate_pstate_increase(cpu, steps); | 611 | intel_pstate_pstate_increase(cpu, steps); |
608 | else | 612 | else |
@@ -612,9 +616,24 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu) | |||
612 | static void intel_pstate_timer_func(unsigned long __data) | 616 | static void intel_pstate_timer_func(unsigned long __data) |
613 | { | 617 | { |
614 | struct cpudata *cpu = (struct cpudata *) __data; | 618 | struct cpudata *cpu = (struct cpudata *) __data; |
619 | struct sample *sample; | ||
620 | u64 energy; | ||
615 | 621 | ||
616 | intel_pstate_sample(cpu); | 622 | intel_pstate_sample(cpu); |
623 | |||
624 | sample = &cpu->samples[cpu->sample_ptr]; | ||
625 | rdmsrl(MSR_PKG_ENERGY_STATUS, energy); | ||
626 | |||
617 | intel_pstate_adjust_busy_pstate(cpu); | 627 | intel_pstate_adjust_busy_pstate(cpu); |
628 | |||
629 | trace_pstate_sample(fp_toint(sample->core_pct_busy), | ||
630 | fp_toint(intel_pstate_get_scaled_busy(cpu)), | ||
631 | cpu->pstate.current_pstate, | ||
632 | sample->mperf, | ||
633 | sample->aperf, | ||
634 | div64_u64(energy, energy_divisor), | ||
635 | sample->freq); | ||
636 | |||
618 | intel_pstate_set_sample_time(cpu); | 637 | intel_pstate_set_sample_time(cpu); |
619 | } | 638 | } |
620 | 639 | ||
@@ -894,6 +913,7 @@ static int __init intel_pstate_init(void) | |||
894 | int cpu, rc = 0; | 913 | int cpu, rc = 0; |
895 | const struct x86_cpu_id *id; | 914 | const struct x86_cpu_id *id; |
896 | struct cpu_defaults *cpu_info; | 915 | struct cpu_defaults *cpu_info; |
916 | u64 units; | ||
897 | 917 | ||
898 | if (no_load) | 918 | if (no_load) |
899 | return -ENODEV; | 919 | return -ENODEV; |
@@ -927,8 +947,12 @@ static int __init intel_pstate_init(void) | |||
927 | if (rc) | 947 | if (rc) |
928 | goto out; | 948 | goto out; |
929 | 949 | ||
950 | rdmsrl(MSR_RAPL_POWER_UNIT, units); | ||
951 | energy_divisor = 1 << ((units >> 8) & 0x1f); /* bits{12:8} */ | ||
952 | |||
930 | intel_pstate_debug_expose_params(); | 953 | intel_pstate_debug_expose_params(); |
931 | intel_pstate_sysfs_expose_params(); | 954 | intel_pstate_sysfs_expose_params(); |
955 | |||
932 | return rc; | 956 | return rc; |
933 | out: | 957 | out: |
934 | get_online_cpus(); | 958 | get_online_cpus(); |
diff --git a/include/trace/events/power.h b/include/trace/events/power.h index cda100d6762d..9e9475c85de5 100644 --- a/include/trace/events/power.h +++ b/include/trace/events/power.h | |||
@@ -35,6 +35,59 @@ DEFINE_EVENT(cpu, cpu_idle, | |||
35 | TP_ARGS(state, cpu_id) | 35 | TP_ARGS(state, cpu_id) |
36 | ); | 36 | ); |
37 | 37 | ||
38 | TRACE_EVENT(pstate_sample, | ||
39 | |||
40 | TP_PROTO(u32 core_busy, | ||
41 | u32 scaled_busy, | ||
42 | u32 state, | ||
43 | u64 mperf, | ||
44 | u64 aperf, | ||
45 | u32 energy, | ||
46 | u32 freq | ||
47 | ), | ||
48 | |||
49 | TP_ARGS(core_busy, | ||
50 | scaled_busy, | ||
51 | state, | ||
52 | mperf, | ||
53 | aperf, | ||
54 | energy, | ||
55 | freq | ||
56 | ), | ||
57 | |||
58 | TP_STRUCT__entry( | ||
59 | __field(u32, core_busy) | ||
60 | __field(u32, scaled_busy) | ||
61 | __field(u32, state) | ||
62 | __field(u64, mperf) | ||
63 | __field(u64, aperf) | ||
64 | __field(u32, energy) | ||
65 | __field(u32, freq) | ||
66 | |||
67 | ), | ||
68 | |||
69 | TP_fast_assign( | ||
70 | __entry->core_busy = core_busy; | ||
71 | __entry->scaled_busy = scaled_busy; | ||
72 | __entry->state = state; | ||
73 | __entry->mperf = mperf; | ||
74 | __entry->aperf = aperf; | ||
75 | __entry->energy = energy; | ||
76 | __entry->freq = freq; | ||
77 | ), | ||
78 | |||
79 | TP_printk("core_busy=%lu scaled=%lu state=%lu mperf=%llu aperf=%llu energy=%lu freq=%lu ", | ||
80 | (unsigned long)__entry->core_busy, | ||
81 | (unsigned long)__entry->scaled_busy, | ||
82 | (unsigned long)__entry->state, | ||
83 | (unsigned long long)__entry->mperf, | ||
84 | (unsigned long long)__entry->aperf, | ||
85 | (unsigned long)__entry->energy, | ||
86 | (unsigned long)__entry->freq | ||
87 | ) | ||
88 | |||
89 | ); | ||
90 | |||
38 | /* This file can get included multiple times, TRACE_HEADER_MULTI_READ at top */ | 91 | /* This file can get included multiple times, TRACE_HEADER_MULTI_READ at top */ |
39 | #ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING | 92 | #ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING |
40 | #define _PWR_EVENT_AVOID_DOUBLE_DEFINING | 93 | #define _PWR_EVENT_AVOID_DOUBLE_DEFINING |