summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcperciva <cperciva@FreeBSD.org>2014-05-11 10:32:58 +0000
committercperciva <cperciva@FreeBSD.org>2014-05-11 10:32:58 +0000
commite9e7ccdea56a38ab5bee2efec955f8b14b05fd15 (patch)
treebcfd8cf3d829cbadc13037ed06e74fc1df88ff3d
parent8e56ee9c85ef48c55f77dfa3b6603ea9737a9033 (diff)
downloadFreeBSD-src-e9e7ccdea56a38ab5bee2efec955f8b14b05fd15.zip
FreeBSD-src-e9e7ccdea56a38ab5bee2efec955f8b14b05fd15.tar.gz
In cf_get_method, when we don't already know what clock speed the CPU is
running at, guess the nearest value instead of looking for a value within 25 MHz of the observed frequency. Prior to this change, if a system booted with Intel Turbo Boost enabled, the dev.cpu.0.freq sysctl is nonfunctional, since the ACPI-reported frequency for Turbo Boost states does not match the actual clock frequency (and thus no levels are within 25 MHz of the observed frequency) and the current performance level is read before a new level is set. MFC after: 3 days Relnotes: Bug fix in power management on CPUs with Intel Turbo Boost
-rw-r--r--sys/kern/kern_cpu.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/sys/kern/kern_cpu.c b/sys/kern/kern_cpu.c
index b4ba635..7206c38 100644
--- a/sys/kern/kern_cpu.c
+++ b/sys/kern/kern_cpu.c
@@ -418,7 +418,7 @@ cf_get_method(device_t dev, struct cf_level *level)
struct cf_setting *curr_set, set;
struct pcpu *pc;
device_t *devs;
- int count, error, i, n, numdevs;
+ int bdiff, count, diff, error, i, n, numdevs;
uint64_t rate;
sc = device_get_softc(dev);
@@ -494,14 +494,15 @@ cf_get_method(device_t dev, struct cf_level *level)
}
cpu_est_clockrate(pc->pc_cpuid, &rate);
rate /= 1000000;
+ bdiff = 1 << 30;
for (i = 0; i < count; i++) {
- if (CPUFREQ_CMP(rate, levels[i].total_set.freq)) {
+ diff = abs(levels[i].total_set.freq - rate);
+ if (diff < bdiff) {
+ bdiff = diff;
sc->curr_level = levels[i];
- CF_DEBUG("get estimated freq %d\n", curr_set->freq);
- goto out;
}
}
- error = ENXIO;
+ CF_DEBUG("get estimated freq %d\n", curr_set->freq);
out:
if (error == 0)
OpenPOWER on IntegriCloud