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>
This commit is contained in:
Jacob Pan 2015-05-07 09:03:59 -07:00 committed by Zhang Rui
parent f09bfdb667
commit d818611388

View File

@ -206,51 +206,57 @@ static void find_target_mwait(void)
} }
struct pkg_cstate_info {
bool skip;
int msr_index;
int cstate_id;
};
#define PKG_CSTATE_INIT(id) { \
.msr_index = MSR_PKG_C##id##_RESIDENCY, \
.cstate_id = id \
}
static struct pkg_cstate_info pkg_cstates[] = {
PKG_CSTATE_INIT(2),
PKG_CSTATE_INIT(3),
PKG_CSTATE_INIT(6),
PKG_CSTATE_INIT(7),
PKG_CSTATE_INIT(8),
PKG_CSTATE_INIT(9),
PKG_CSTATE_INIT(10),
{NULL},
};
static bool has_pkg_state_counter(void) static bool has_pkg_state_counter(void)
{ {
u64 tmp; u64 val;
return !rdmsrl_safe(MSR_PKG_C2_RESIDENCY, &tmp) || struct pkg_cstate_info *info = pkg_cstates;
!rdmsrl_safe(MSR_PKG_C3_RESIDENCY, &tmp) ||
!rdmsrl_safe(MSR_PKG_C6_RESIDENCY, &tmp) || /* check if any one of the counter msrs exists */
!rdmsrl_safe(MSR_PKG_C7_RESIDENCY, &tmp); while (info->msr_index) {
if (!rdmsrl_safe(info->msr_index, &val))
return true;
info++;
}
return false;
} }
static u64 pkg_state_counter(void) static u64 pkg_state_counter(void)
{ {
u64 val; u64 val;
u64 count = 0; u64 count = 0;
struct pkg_cstate_info *info = pkg_cstates;
static bool skip_c2; while (info->msr_index) {
static bool skip_c3; if (!info->skip) {
static bool skip_c6; if (!rdmsrl_safe(info->msr_index, &val))
static bool skip_c7; count += val;
else
if (!skip_c2) { info->skip = true;
if (!rdmsrl_safe(MSR_PKG_C2_RESIDENCY, &val)) }
count += val; info++;
else
skip_c2 = true;
}
if (!skip_c3) {
if (!rdmsrl_safe(MSR_PKG_C3_RESIDENCY, &val))
count += val;
else
skip_c3 = true;
}
if (!skip_c6) {
if (!rdmsrl_safe(MSR_PKG_C6_RESIDENCY, &val))
count += val;
else
skip_c6 = true;
}
if (!skip_c7) {
if (!rdmsrl_safe(MSR_PKG_C7_RESIDENCY, &val))
count += val;
else
skip_c7 = true;
} }
return count; return count;