aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq
diff options
context:
space:
mode:
authorDirk Brandewie <dirk.j.brandewie@intel.com>2013-05-07 11:20:25 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-05-12 08:04:16 -0400
commit1abc4b20b85b42e8573957e54b193385cf48b0d6 (patch)
treefae8b7b36dd913c05ee2e2c7fadb4308f7b4295f /drivers/cpufreq
parent559f56c70fc90bd9da8c9c9c36d86c5e582ac5b3 (diff)
cpufreq / intel_pstate: remove idle time and duration from sample and calculations
Idle time is taken into account in the APERF/MPERF ratio calculation there is no reason for the driver to track it seperately. This reduces the work in the driver and makes the code more readable. Removal of the tracking of sample duration removes the possibility of the divide by zero exception when the duration is sub 1us References: https://bugzilla.kernel.org/show_bug.cgi?id=56691 Reported-by: Mike Lothian <mike@fireburn.co.uk> Cc: 3.9+ <stable@vger.kernel.org> Signed-off-by: Dirk Brandewie <dirk.j.brandewie@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r--drivers/cpufreq/intel_pstate.c45
1 files changed, 8 insertions, 37 deletions
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index cc3a8e6c92be..c6e10d02b795 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -48,12 +48,7 @@ static inline int32_t div_fp(int32_t x, int32_t y)
48} 48}
49 49
50struct sample { 50struct sample {
51 ktime_t start_time;
52 ktime_t end_time;
53 int core_pct_busy; 51 int core_pct_busy;
54 int pstate_pct_busy;
55 u64 duration_us;
56 u64 idletime_us;
57 u64 aperf; 52 u64 aperf;
58 u64 mperf; 53 u64 mperf;
59 int freq; 54 int freq;
@@ -91,8 +86,6 @@ struct cpudata {
91 int min_pstate_count; 86 int min_pstate_count;
92 int idle_mode; 87 int idle_mode;
93 88
94 ktime_t prev_sample;
95 u64 prev_idle_time_us;
96 u64 prev_aperf; 89 u64 prev_aperf;
97 u64 prev_mperf; 90 u64 prev_mperf;
98 int sample_ptr; 91 int sample_ptr;
@@ -450,48 +443,26 @@ static inline void intel_pstate_calc_busy(struct cpudata *cpu,
450 struct sample *sample) 443 struct sample *sample)
451{ 444{
452 u64 core_pct; 445 u64 core_pct;
453 sample->pstate_pct_busy = 100 - div64_u64(
454 sample->idletime_us * 100,
455 sample->duration_us);
456 core_pct = div64_u64(sample->aperf * 100, sample->mperf); 446 core_pct = div64_u64(sample->aperf * 100, sample->mperf);
457 sample->freq = cpu->pstate.max_pstate * core_pct * 1000; 447 sample->freq = cpu->pstate.max_pstate * core_pct * 1000;
458 448
459 sample->core_pct_busy = div_s64((sample->pstate_pct_busy * core_pct), 449 sample->core_pct_busy = core_pct;
460 100);
461} 450}
462 451
463static inline void intel_pstate_sample(struct cpudata *cpu) 452static inline void intel_pstate_sample(struct cpudata *cpu)
464{ 453{
465 ktime_t now;
466 u64 idle_time_us;
467 u64 aperf, mperf; 454 u64 aperf, mperf;
468 455
469 now = ktime_get();
470 idle_time_us = get_cpu_idle_time_us(cpu->cpu, NULL);
471
472 rdmsrl(MSR_IA32_APERF, aperf); 456 rdmsrl(MSR_IA32_APERF, aperf);
473 rdmsrl(MSR_IA32_MPERF, mperf); 457 rdmsrl(MSR_IA32_MPERF, mperf);
474 /* for the first sample, don't actually record a sample, just 458 cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT;
475 * set the baseline */ 459 cpu->samples[cpu->sample_ptr].aperf = aperf;
476 if (cpu->prev_idle_time_us > 0) { 460 cpu->samples[cpu->sample_ptr].mperf = mperf;
477 cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT; 461 cpu->samples[cpu->sample_ptr].aperf -= cpu->prev_aperf;
478 cpu->samples[cpu->sample_ptr].start_time = cpu->prev_sample; 462 cpu->samples[cpu->sample_ptr].mperf -= cpu->prev_mperf;
479 cpu->samples[cpu->sample_ptr].end_time = now; 463
480 cpu->samples[cpu->sample_ptr].duration_us = 464 intel_pstate_calc_busy(cpu, &cpu->samples[cpu->sample_ptr]);
481 ktime_us_delta(now, cpu->prev_sample);
482 cpu->samples[cpu->sample_ptr].idletime_us =
483 idle_time_us - cpu->prev_idle_time_us;
484
485 cpu->samples[cpu->sample_ptr].aperf = aperf;
486 cpu->samples[cpu->sample_ptr].mperf = mperf;
487 cpu->samples[cpu->sample_ptr].aperf -= cpu->prev_aperf;
488 cpu->samples[cpu->sample_ptr].mperf -= cpu->prev_mperf;
489
490 intel_pstate_calc_busy(cpu, &cpu->samples[cpu->sample_ptr]);
491 }
492 465
493 cpu->prev_sample = now;
494 cpu->prev_idle_time_us = idle_time_us;
495 cpu->prev_aperf = aperf; 466 cpu->prev_aperf = aperf;
496 cpu->prev_mperf = mperf; 467 cpu->prev_mperf = mperf;
497} 468}