Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

thermal/powerclamp: fix missing newer package c-states

Package C8 to C10 was introduced in newer Intel CPUs, we need to
include them in the package c-state residency calculation.
Otherwise, idle injection target is not accurately maintained by
the closed control loop.

Also cleaned up the code to make it scale better with large number
of c-states.

Reported-by: Kristen Carlson Accardi <kristen@linux.intel.com>
Signed-off-by: Jacob Pan <jacob.jun.pan@linux.intel.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>

authored by

Jacob Pan and committed by
Zhang Rui
d8186113 f09bfdb6

+42 -36
+42 -36
drivers/thermal/intel_powerclamp.c
··· 206 206 207 207 } 208 208 209 + struct pkg_cstate_info { 210 + bool skip; 211 + int msr_index; 212 + int cstate_id; 213 + }; 214 + 215 + #define PKG_CSTATE_INIT(id) { \ 216 + .msr_index = MSR_PKG_C##id##_RESIDENCY, \ 217 + .cstate_id = id \ 218 + } 219 + 220 + static struct pkg_cstate_info pkg_cstates[] = { 221 + PKG_CSTATE_INIT(2), 222 + PKG_CSTATE_INIT(3), 223 + PKG_CSTATE_INIT(6), 224 + PKG_CSTATE_INIT(7), 225 + PKG_CSTATE_INIT(8), 226 + PKG_CSTATE_INIT(9), 227 + PKG_CSTATE_INIT(10), 228 + {NULL}, 229 + }; 230 + 209 231 static bool has_pkg_state_counter(void) 210 232 { 211 - u64 tmp; 212 - return !rdmsrl_safe(MSR_PKG_C2_RESIDENCY, &tmp) || 213 - !rdmsrl_safe(MSR_PKG_C3_RESIDENCY, &tmp) || 214 - !rdmsrl_safe(MSR_PKG_C6_RESIDENCY, &tmp) || 215 - !rdmsrl_safe(MSR_PKG_C7_RESIDENCY, &tmp); 233 + u64 val; 234 + struct pkg_cstate_info *info = pkg_cstates; 235 + 236 + /* check if any one of the counter msrs exists */ 237 + while (info->msr_index) { 238 + if (!rdmsrl_safe(info->msr_index, &val)) 239 + return true; 240 + info++; 241 + } 242 + 243 + return false; 216 244 } 217 245 218 246 static u64 pkg_state_counter(void) 219 247 { 220 248 u64 val; 221 249 u64 count = 0; 250 + struct pkg_cstate_info *info = pkg_cstates; 222 251 223 - static bool skip_c2; 224 - static bool skip_c3; 225 - static bool skip_c6; 226 - static bool skip_c7; 227 - 228 - if (!skip_c2) { 229 - if (!rdmsrl_safe(MSR_PKG_C2_RESIDENCY, &val)) 230 - count += val; 231 - else 232 - skip_c2 = true; 233 - } 234 - 235 - if (!skip_c3) { 236 - if (!rdmsrl_safe(MSR_PKG_C3_RESIDENCY, &val)) 237 - count += val; 238 - else 239 - skip_c3 = true; 240 - } 241 - 242 - if (!skip_c6) { 243 - if (!rdmsrl_safe(MSR_PKG_C6_RESIDENCY, &val)) 244 - count += val; 245 - else 246 - skip_c6 = true; 247 - } 248 - 249 - if (!skip_c7) { 250 - if (!rdmsrl_safe(MSR_PKG_C7_RESIDENCY, &val)) 251 - count += val; 252 - else 253 - skip_c7 = true; 252 + while (info->msr_index) { 253 + if (!info->skip) { 254 + if (!rdmsrl_safe(info->msr_index, &val)) 255 + count += val; 256 + else 257 + info->skip = true; 258 + } 259 + info++; 254 260 } 255 261 256 262 return count;