]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/3.19.4/powercap-rapl-handle-domains-with-different-energy-units.patch
5.1-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.19.4 / powercap-rapl-handle-domains-with-different-energy-units.patch
CommitLineData
35e5a9d9
GKH
1From d474a4d365aaa5c7aabcf11a74ea43aa23f6f2e9 Mon Sep 17 00:00:00 2001
2From: Jacob Pan <jacob.jun.pan@linux.intel.com>
3Date: Fri, 13 Mar 2015 03:48:56 -0700
4Subject: powercap / RAPL: handle domains with different energy units
5
6From: Jacob Pan <jacob.jun.pan@linux.intel.com>
7
8commit d474a4d365aaa5c7aabcf11a74ea43aa23f6f2e9 upstream.
9
10The current driver assumes all RAPL domains within a CPU package
11have the same energy unit. This is no longer true for HSW server
12CPUs since DRAM domain has is own fixed energy unit which can be
13different than the package energy unit enumerated by package
14power MSR. In fact, the default HSW EP package power unit is 61uJ
15whereas DRAM domain unit is 15.3uJ. The result is that DRAM power
16consumption is counted 4x more than real power reported by energy
17counters, similarly for max_energy_range_uj of DRAM domain.
18
19This patch adds domain specific energy unit per cpu type, it allows
20domain energy unit to override package energy unit if non zero.
21
22Please see this document for details.
23"Intel Xeon Processor E5-1600 and E5-2600 v3 Product Families, Volume 2 of 2.
24 Datasheet, September 2014, Reference Number: 330784-001 "
25
26Signed-off-by: Jacob Pan <jacob.jun.pan@linux.intel.com>
27Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
28Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
29
30---
31 drivers/powercap/intel_rapl.c | 54 ++++++++++++++++++++++++++++++------------
32 1 file changed, 39 insertions(+), 15 deletions(-)
33
34--- a/drivers/powercap/intel_rapl.c
35+++ b/drivers/powercap/intel_rapl.c
36@@ -73,7 +73,7 @@
37
38 #define TIME_WINDOW_MAX_MSEC 40000
39 #define TIME_WINDOW_MIN_MSEC 250
40-
41+#define ENERGY_UNIT_SCALE 1000 /* scale from driver unit to powercap unit */
42 enum unit_type {
43 ARBITRARY_UNIT, /* no translation */
44 POWER_UNIT,
45@@ -158,6 +158,7 @@ struct rapl_domain {
46 struct rapl_power_limit rpl[NR_POWER_LIMITS];
47 u64 attr_map; /* track capabilities */
48 unsigned int state;
49+ unsigned int domain_energy_unit;
50 int package_id;
51 };
52 #define power_zone_to_rapl_domain(_zone) \
53@@ -190,6 +191,7 @@ struct rapl_defaults {
54 void (*set_floor_freq)(struct rapl_domain *rd, bool mode);
55 u64 (*compute_time_window)(struct rapl_package *rp, u64 val,
56 bool to_raw);
57+ unsigned int dram_domain_energy_unit;
58 };
59 static struct rapl_defaults *rapl_defaults;
60
61@@ -227,7 +229,8 @@ static int rapl_read_data_raw(struct rap
62 static int rapl_write_data_raw(struct rapl_domain *rd,
63 enum rapl_primitives prim,
64 unsigned long long value);
65-static u64 rapl_unit_xlate(int package, enum unit_type type, u64 value,
66+static u64 rapl_unit_xlate(struct rapl_domain *rd, int package,
67+ enum unit_type type, u64 value,
68 int to_raw);
69 static void package_power_limit_irq_save(int package_id);
70
71@@ -305,7 +308,9 @@ static int get_energy_counter(struct pow
72
73 static int get_max_energy_counter(struct powercap_zone *pcd_dev, u64 *energy)
74 {
75- *energy = rapl_unit_xlate(0, ENERGY_UNIT, ENERGY_STATUS_MASK, 0);
76+ struct rapl_domain *rd = power_zone_to_rapl_domain(pcd_dev);
77+
78+ *energy = rapl_unit_xlate(rd, 0, ENERGY_UNIT, ENERGY_STATUS_MASK, 0);
79 return 0;
80 }
81
82@@ -639,6 +644,11 @@ static void rapl_init_domains(struct rap
83 rd->msrs[4] = MSR_DRAM_POWER_INFO;
84 rd->rpl[0].prim_id = PL1_ENABLE;
85 rd->rpl[0].name = pl1_name;
86+ rd->domain_energy_unit =
87+ rapl_defaults->dram_domain_energy_unit;
88+ if (rd->domain_energy_unit)
89+ pr_info("DRAM domain energy unit %dpj\n",
90+ rd->domain_energy_unit);
91 break;
92 }
93 if (mask) {
94@@ -648,11 +658,13 @@ static void rapl_init_domains(struct rap
95 }
96 }
97
98-static u64 rapl_unit_xlate(int package, enum unit_type type, u64 value,
99+static u64 rapl_unit_xlate(struct rapl_domain *rd, int package,
100+ enum unit_type type, u64 value,
101 int to_raw)
102 {
103 u64 units = 1;
104 struct rapl_package *rp;
105+ u64 scale = 1;
106
107 rp = find_package_by_id(package);
108 if (!rp)
109@@ -663,7 +675,12 @@ static u64 rapl_unit_xlate(int package,
110 units = rp->power_unit;
111 break;
112 case ENERGY_UNIT:
113- units = rp->energy_unit;
114+ scale = ENERGY_UNIT_SCALE;
115+ /* per domain unit takes precedence */
116+ if (rd && rd->domain_energy_unit)
117+ units = rd->domain_energy_unit;
118+ else
119+ units = rp->energy_unit;
120 break;
121 case TIME_UNIT:
122 return rapl_defaults->compute_time_window(rp, value, to_raw);
123@@ -673,11 +690,11 @@ static u64 rapl_unit_xlate(int package,
124 };
125
126 if (to_raw)
127- return div64_u64(value, units);
128+ return div64_u64(value, units) * scale;
129
130 value *= units;
131
132- return value;
133+ return div64_u64(value, scale);
134 }
135
136 /* in the order of enum rapl_primitives */
137@@ -773,7 +790,7 @@ static int rapl_read_data_raw(struct rap
138 final = value & rp->mask;
139 final = final >> rp->shift;
140 if (xlate)
141- *data = rapl_unit_xlate(rd->package_id, rp->unit, final, 0);
142+ *data = rapl_unit_xlate(rd, rd->package_id, rp->unit, final, 0);
143 else
144 *data = final;
145
146@@ -799,7 +816,7 @@ static int rapl_write_data_raw(struct ra
147 "failed to read msr 0x%x on cpu %d\n", msr, cpu);
148 return -EIO;
149 }
150- value = rapl_unit_xlate(rd->package_id, rp->unit, value, 1);
151+ value = rapl_unit_xlate(rd, rd->package_id, rp->unit, value, 1);
152 msr_val &= ~rp->mask;
153 msr_val |= value << rp->shift;
154 if (wrmsrl_safe_on_cpu(cpu, msr, msr_val)) {
155@@ -818,7 +835,7 @@ static int rapl_write_data_raw(struct ra
156 * calculate units differ on different CPUs.
157 * We convert the units to below format based on CPUs.
158 * i.e.
159- * energy unit: microJoules : Represented in microJoules by default
160+ * energy unit: picoJoules : Represented in picoJoules by default
161 * power unit : microWatts : Represented in milliWatts by default
162 * time unit : microseconds: Represented in seconds by default
163 */
164@@ -834,7 +851,7 @@ static int rapl_check_unit_core(struct r
165 }
166
167 value = (msr_val & ENERGY_UNIT_MASK) >> ENERGY_UNIT_OFFSET;
168- rp->energy_unit = 1000000 / (1 << value);
169+ rp->energy_unit = ENERGY_UNIT_SCALE * 1000000 / (1 << value);
170
171 value = (msr_val & POWER_UNIT_MASK) >> POWER_UNIT_OFFSET;
172 rp->power_unit = 1000000 / (1 << value);
173@@ -842,7 +859,7 @@ static int rapl_check_unit_core(struct r
174 value = (msr_val & TIME_UNIT_MASK) >> TIME_UNIT_OFFSET;
175 rp->time_unit = 1000000 / (1 << value);
176
177- pr_debug("Core CPU package %d energy=%duJ, time=%dus, power=%duW\n",
178+ pr_debug("Core CPU package %d energy=%dpJ, time=%dus, power=%duW\n",
179 rp->id, rp->energy_unit, rp->time_unit, rp->power_unit);
180
181 return 0;
182@@ -859,7 +876,7 @@ static int rapl_check_unit_atom(struct r
183 return -ENODEV;
184 }
185 value = (msr_val & ENERGY_UNIT_MASK) >> ENERGY_UNIT_OFFSET;
186- rp->energy_unit = 1 << value;
187+ rp->energy_unit = ENERGY_UNIT_SCALE * 1 << value;
188
189 value = (msr_val & POWER_UNIT_MASK) >> POWER_UNIT_OFFSET;
190 rp->power_unit = (1 << value) * 1000;
191@@ -867,7 +884,7 @@ static int rapl_check_unit_atom(struct r
192 value = (msr_val & TIME_UNIT_MASK) >> TIME_UNIT_OFFSET;
193 rp->time_unit = 1000000 / (1 << value);
194
195- pr_debug("Atom package %d energy=%duJ, time=%dus, power=%duW\n",
196+ pr_debug("Atom package %d energy=%dpJ, time=%dus, power=%duW\n",
197 rp->id, rp->energy_unit, rp->time_unit, rp->power_unit);
198
199 return 0;
200@@ -1017,6 +1034,13 @@ static const struct rapl_defaults rapl_d
201 .compute_time_window = rapl_compute_time_window_core,
202 };
203
204+static const struct rapl_defaults rapl_defaults_hsw_server = {
205+ .check_unit = rapl_check_unit_core,
206+ .set_floor_freq = set_floor_freq_default,
207+ .compute_time_window = rapl_compute_time_window_core,
208+ .dram_domain_energy_unit = 15300,
209+};
210+
211 static const struct rapl_defaults rapl_defaults_atom = {
212 .check_unit = rapl_check_unit_atom,
213 .set_floor_freq = set_floor_freq_atom,
214@@ -1037,7 +1061,7 @@ static const struct x86_cpu_id rapl_ids[
215 RAPL_CPU(0x3a, rapl_defaults_core),/* Ivy Bridge */
216 RAPL_CPU(0x3c, rapl_defaults_core),/* Haswell */
217 RAPL_CPU(0x3d, rapl_defaults_core),/* Broadwell */
218- RAPL_CPU(0x3f, rapl_defaults_core),/* Haswell */
219+ RAPL_CPU(0x3f, rapl_defaults_hsw_server),/* Haswell servers */
220 RAPL_CPU(0x45, rapl_defaults_core),/* Haswell ULT */
221 RAPL_CPU(0x4C, rapl_defaults_atom),/* Braswell */
222 RAPL_CPU(0x4A, rapl_defaults_atom),/* Tangier */