All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 0/5] intel_pstate: Use the cpu load first on Atom only
@ 2015-11-23 13:06 Philippe Longepe
  2015-11-23 13:06 ` Philippe Longepe
                   ` (10 more replies)
  0 siblings, 11 replies; 15+ messages in thread
From: Philippe Longepe @ 2015-11-23 13:06 UTC (permalink / raw)
  To: linux-pm; +Cc: srinivas.pandruvada, Philippe Longepe

From: Philippe Longepe <philippe.longepe@intel.com>

This patch serie aims to use the load as the input of the PID.

The load is defined by cpu_load = 100 * (delta_mperf / delta_tsc)
since mperf is counting at HFM during C0 state and TSC is counting at 
the same frequency during all C-States.

The load gives very good power improvements on Android manly for gaming
use cases.
Also include the IOBoost improvement that converts time spent in iowait 
into mperf cycles to avoid performance degradation during IOs use cases.

Measured on a Cherrytrail with this algorithm:

			Power (in J)	Power with patch	Power Gain
Candycrush Saga (30sec) 46.7 		14.5 			221.6%
Circular ProgressBar 	10.4 		3.2 			226.12%
SmartBench 		76 		54.3 			40%
FishTank 		226		116			95%
AnTuTu5.6		315		311 			2.7%

Philippe Longepe (5):
  cpufreq: intel_pstate: change function name for calculation for busy
  cpufreq: intel_pstate: Rename current busy calculation function
  cpufreq: intel_pstate: account for non C0 time
  cpufreq: intel_pstate: configurable busy calculation
  cpufreq: intel_pstate: try load instead of busy_scaled

 drivers/cpufreq/intel_pstate.c | 56 ++++++++++++++++++++++++++++++++++++------
 1 file changed, 48 insertions(+), 8 deletions(-)

-- 
1.9.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v1 0/5] intel_pstate: Use the cpu load first on Atom only
  2015-11-23 13:06 [PATCH v1 0/5] intel_pstate: Use the cpu load first on Atom only Philippe Longepe
@ 2015-11-23 13:06 ` Philippe Longepe
  2015-11-23 13:06 ` [PATCH v1 1/5] cpufreq: intel_pstate: change function name for calculation for busy Philippe Longepe
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Philippe Longepe @ 2015-11-23 13:06 UTC (permalink / raw)
  To: linux-pm; +Cc: srinivas.pandruvada, Philippe Longepe

From: Philippe Longepe <philippe.longepe@intel.com>

This patch serie aims to use the load as the input of the PID.

The load is defined by cpu_load = 100 * (delta_mperf / delta_tsc)
since mperf is counting at HFM during C0 state and TSC is counting at 
the same frequency during all C-States.

The load gives very good power improvements on Android manly for gaming
use cases.
Also include the IOBoost improvement that converts time spent in iowait 
into mperf cycles to avoid performance degradation during IOs use cases.

Measured on a Cherrytrail with this algorithm:

			Power (in J)	Power with patch	Power Gain
Candycrush Saga (30sec) 46.7 		14.5 			221.6%
Circular ProgressBar 	10.4 		3.2 			226.12%
SmartBench 		76 		54.3 			40%
FishTank 		226		116			95%
AnTuTu5.6		315		311 			2.7%

Philippe Longepe (5):
  cpufreq: intel_pstate: change function name for calculation for busy
  cpufreq: intel_pstate: Rename current busy calculation function
  cpufreq: intel_pstate: account for non C0 time
  cpufreq: intel_pstate: configurable busy calculation
  cpufreq: intel_pstate: try load instead of busy_scaled

 drivers/cpufreq/intel_pstate.c | 56 ++++++++++++++++++++++++++++++++++++------
 1 file changed, 48 insertions(+), 8 deletions(-)

-- 
1.9.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v1 1/5] cpufreq: intel_pstate: change function name for calculation for busy
  2015-11-23 13:06 [PATCH v1 0/5] intel_pstate: Use the cpu load first on Atom only Philippe Longepe
  2015-11-23 13:06 ` Philippe Longepe
@ 2015-11-23 13:06 ` Philippe Longepe
  2015-11-23 13:06 ` [PATCH " Philippe Longepe
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Philippe Longepe @ 2015-11-23 13:06 UTC (permalink / raw)
  To: linux-pm; +Cc: srinivas.pandruvada, Philippe Longepe

From: Philippe Longepe <philippe.longepe@intel.com>

APERF/MPERF is not giving busy but average performance of frequency.
Also core_pct_busy is not busy but core percent for performance.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Philippe Longepe <philippe.longepe@intel.com>
---
 drivers/cpufreq/intel_pstate.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index d3b0e50..423a12a 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -65,7 +65,7 @@ static inline int ceiling_fp(int32_t x)
 }
 
 struct sample {
-	int32_t core_pct_busy;
+	int32_t core_pct_perf;
 	u64 aperf;
 	u64 mperf;
 	u64 tsc;
@@ -856,7 +856,7 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
 	intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate, false);
 }
 
-static inline void intel_pstate_calc_busy(struct cpudata *cpu)
+static inline void intel_pstate_calc_performance(struct cpudata *cpu)
 {
 	struct sample *sample = &cpu->sample;
 	int64_t core_pct;
@@ -870,7 +870,7 @@ static inline void intel_pstate_calc_busy(struct cpudata *cpu)
 			cpu->pstate.scaling / 100),
 			core_pct));
 
-	sample->core_pct_busy = (int32_t)core_pct;
+	sample->core_pct_perf = (int32_t)core_pct;
 }
 
 static inline void intel_pstate_sample(struct cpudata *cpu)
@@ -899,7 +899,7 @@ static inline void intel_pstate_sample(struct cpudata *cpu)
 	cpu->sample.mperf -= cpu->prev_mperf;
 	cpu->sample.tsc -= cpu->prev_tsc;
 
-	intel_pstate_calc_busy(cpu);
+	intel_pstate_calc_performance(cpu);
 
 	cpu->prev_aperf = aperf;
 	cpu->prev_mperf = mperf;
@@ -939,7 +939,7 @@ static inline int32_t intel_pstate_get_scaled_busy(struct cpudata *cpu)
 	 * period. The result will be a percentage of busy at a
 	 * specified pstate.
 	 */
-	core_busy = cpu->sample.core_pct_busy;
+	core_busy = cpu->sample.core_pct_perf;
 	max_pstate = int_tofp(cpu->pstate.max_pstate_physical);
 	current_pstate = int_tofp(cpu->pstate.current_pstate);
 	core_busy = mul_fp(core_busy, div_fp(max_pstate, current_pstate));
@@ -982,7 +982,7 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
 	intel_pstate_set_pstate(cpu, cpu->pstate.current_pstate - ctl, true);
 
 	sample = &cpu->sample;
-	trace_pstate_sample(fp_toint(sample->core_pct_busy),
+	trace_pstate_sample(fp_toint(sample->core_pct_perf),
 		fp_toint(busy_scaled),
 		from,
 		cpu->pstate.current_pstate,
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 1/5] cpufreq: intel_pstate: change function name for calculation for busy
  2015-11-23 13:06 [PATCH v1 0/5] intel_pstate: Use the cpu load first on Atom only Philippe Longepe
  2015-11-23 13:06 ` Philippe Longepe
  2015-11-23 13:06 ` [PATCH v1 1/5] cpufreq: intel_pstate: change function name for calculation for busy Philippe Longepe
@ 2015-11-23 13:06 ` Philippe Longepe
  2015-11-23 13:06 ` [PATCH v1 2/5] cpufreq: intel_pstate: Rename current busy calculation function Philippe Longepe
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Philippe Longepe @ 2015-11-23 13:06 UTC (permalink / raw)
  To: linux-pm; +Cc: srinivas.pandruvada, Philippe Longepe

From: Philippe Longepe <philippe.longepe@intel.com>

APERF/MPERF is not giving busy but average performance of frequency.
Also core_pct_busy is not busy but core percent for performance.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Philippe Longepe <philippe.longepe@intel.com>
---
 drivers/cpufreq/intel_pstate.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index d3b0e50..423a12a 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -65,7 +65,7 @@ static inline int ceiling_fp(int32_t x)
 }
 
 struct sample {
-	int32_t core_pct_busy;
+	int32_t core_pct_perf;
 	u64 aperf;
 	u64 mperf;
 	u64 tsc;
@@ -856,7 +856,7 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
 	intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate, false);
 }
 
-static inline void intel_pstate_calc_busy(struct cpudata *cpu)
+static inline void intel_pstate_calc_performance(struct cpudata *cpu)
 {
 	struct sample *sample = &cpu->sample;
 	int64_t core_pct;
@@ -870,7 +870,7 @@ static inline void intel_pstate_calc_busy(struct cpudata *cpu)
 			cpu->pstate.scaling / 100),
 			core_pct));
 
-	sample->core_pct_busy = (int32_t)core_pct;
+	sample->core_pct_perf = (int32_t)core_pct;
 }
 
 static inline void intel_pstate_sample(struct cpudata *cpu)
@@ -899,7 +899,7 @@ static inline void intel_pstate_sample(struct cpudata *cpu)
 	cpu->sample.mperf -= cpu->prev_mperf;
 	cpu->sample.tsc -= cpu->prev_tsc;
 
-	intel_pstate_calc_busy(cpu);
+	intel_pstate_calc_performance(cpu);
 
 	cpu->prev_aperf = aperf;
 	cpu->prev_mperf = mperf;
@@ -939,7 +939,7 @@ static inline int32_t intel_pstate_get_scaled_busy(struct cpudata *cpu)
 	 * period. The result will be a percentage of busy at a
 	 * specified pstate.
 	 */
-	core_busy = cpu->sample.core_pct_busy;
+	core_busy = cpu->sample.core_pct_perf;
 	max_pstate = int_tofp(cpu->pstate.max_pstate_physical);
 	current_pstate = int_tofp(cpu->pstate.current_pstate);
 	core_busy = mul_fp(core_busy, div_fp(max_pstate, current_pstate));
@@ -982,7 +982,7 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
 	intel_pstate_set_pstate(cpu, cpu->pstate.current_pstate - ctl, true);
 
 	sample = &cpu->sample;
-	trace_pstate_sample(fp_toint(sample->core_pct_busy),
+	trace_pstate_sample(fp_toint(sample->core_pct_perf),
 		fp_toint(busy_scaled),
 		from,
 		cpu->pstate.current_pstate,
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v1 2/5] cpufreq: intel_pstate: Rename current busy calculation function
  2015-11-23 13:06 [PATCH v1 0/5] intel_pstate: Use the cpu load first on Atom only Philippe Longepe
                   ` (2 preceding siblings ...)
  2015-11-23 13:06 ` [PATCH " Philippe Longepe
@ 2015-11-23 13:06 ` Philippe Longepe
  2015-11-23 13:06 ` Philippe Longepe
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Philippe Longepe @ 2015-11-23 13:06 UTC (permalink / raw)
  To: linux-pm; +Cc: srinivas.pandruvada, Philippe Longepe

From: Philippe Longepe <philippe.longepe@intel.com>

The current busy calculation estimate idle time using experimented
3X idle period, not using delta mperf/ delta tsc. So rename this
function.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Philippe Longepe <philippe.longepe@intel.com>
---
 drivers/cpufreq/intel_pstate.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 423a12a..fa27ec5 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -922,7 +922,7 @@ static inline void intel_pstate_set_sample_time(struct cpudata *cpu)
 	mod_timer_pinned(&cpu->timer, jiffies + delay);
 }
 
-static inline int32_t intel_pstate_get_scaled_busy(struct cpudata *cpu)
+static inline int32_t intel_pstate_get_scaled_busy_estimate(struct cpudata *cpu)
 {
 	int32_t core_busy, max_pstate, current_pstate, sample_ratio;
 	s64 duration_us;
@@ -974,7 +974,7 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
 	from = cpu->pstate.current_pstate;
 
 	pid = &cpu->pid;
-	busy_scaled = intel_pstate_get_scaled_busy(cpu);
+	busy_scaled = intel_pstate_get_scaled_busy_estimate(cpu);
 
 	ctl = pid_calc(pid, busy_scaled);
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v1 2/5] cpufreq: intel_pstate: Rename current busy calculation function
  2015-11-23 13:06 [PATCH v1 0/5] intel_pstate: Use the cpu load first on Atom only Philippe Longepe
                   ` (3 preceding siblings ...)
  2015-11-23 13:06 ` [PATCH v1 2/5] cpufreq: intel_pstate: Rename current busy calculation function Philippe Longepe
@ 2015-11-23 13:06 ` Philippe Longepe
  2015-11-23 13:06 ` [PATCH v1 3/5] cpufreq: intel_pstate: account for non C0 time Philippe Longepe
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Philippe Longepe @ 2015-11-23 13:06 UTC (permalink / raw)
  To: linux-pm; +Cc: srinivas.pandruvada, Philippe Longepe

From: Philippe Longepe <philippe.longepe@intel.com>

The current busy calculation estimate idle time using experimented
3X idle period, not using delta mperf/ delta tsc. So rename this
function.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Philippe Longepe <philippe.longepe@intel.com>
---
 drivers/cpufreq/intel_pstate.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 423a12a..fa27ec5 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -922,7 +922,7 @@ static inline void intel_pstate_set_sample_time(struct cpudata *cpu)
 	mod_timer_pinned(&cpu->timer, jiffies + delay);
 }
 
-static inline int32_t intel_pstate_get_scaled_busy(struct cpudata *cpu)
+static inline int32_t intel_pstate_get_scaled_busy_estimate(struct cpudata *cpu)
 {
 	int32_t core_busy, max_pstate, current_pstate, sample_ratio;
 	s64 duration_us;
@@ -974,7 +974,7 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
 	from = cpu->pstate.current_pstate;
 
 	pid = &cpu->pid;
-	busy_scaled = intel_pstate_get_scaled_busy(cpu);
+	busy_scaled = intel_pstate_get_scaled_busy_estimate(cpu);
 
 	ctl = pid_calc(pid, busy_scaled);
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v1 3/5] cpufreq: intel_pstate: account for non C0 time
  2015-11-23 13:06 [PATCH v1 0/5] intel_pstate: Use the cpu load first on Atom only Philippe Longepe
                   ` (4 preceding siblings ...)
  2015-11-23 13:06 ` Philippe Longepe
@ 2015-11-23 13:06 ` Philippe Longepe
  2015-11-23 13:06 ` Philippe Longepe
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Philippe Longepe @ 2015-11-23 13:06 UTC (permalink / raw)
  To: linux-pm; +Cc: srinivas.pandruvada, Philippe Longepe, Stephane Gasparini

From: Philippe Longepe <philippe.longepe@intel.com>

Aperf and Mperf counter are not enough to determine the Target P-state
because they measure performance only when the targeted processor is
in the C0 state (active state).
Because of that, we were computing the average P-state during the last
period which can be very different from the average frequency
(or percentage of performance).

As defined in the SDM (section 14.2), the PercentPerformance is defined by:

PercentPerformance = PercentBusy * (delta_aperf / delta_mperf);

The PercentBusy (or load) can be estimated as the ratio of the mperf
counter running at a constant frequency only during active periods (C0)
and the time stamp counter running at the same frequency but also
during idle.

So, PercentBusy = 100 * (delta_mperf / delta_tsc)

and, PercentPerformance = 100 * (delta_mperf / delta_tsc) *
                                (delta_aperf / delta_mperf)
That can be simplified with:
PercentPerformance = 100 * (delta_aperf / delta_tsc)

Signed-off-by: Philippe Longepe <philippe.longepe@intel.com>
Signed-off-by: Stephane Gasparini <stephane.gasparini@linux.intel.com>
---
 drivers/cpufreq/intel_pstate.c | 40 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 39 insertions(+), 1 deletion(-)

diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index fa27ec5..f9acfb0 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -66,6 +66,7 @@ static inline int ceiling_fp(int32_t x)
 
 struct sample {
 	int32_t core_pct_perf;
+	int32_t	cpu_load;
 	u64 aperf;
 	u64 mperf;
 	u64 tsc;
@@ -922,6 +923,43 @@ static inline void intel_pstate_set_sample_time(struct cpudata *cpu)
 	mod_timer_pinned(&cpu->timer, jiffies + delay);
 }
 
+
+static inline int32_t intel_pstate_calc_scaled_busy(struct cpudata *cpu)
+{
+	struct sample *sample = &cpu->sample;
+	struct pstate_data *pstate = &cpu->pstate;
+	int64_t core_busy_ratio;
+
+	/*
+	 * The load can be estimated as the ratio of the mperf counter
+	 * running at a constant frequency only during active periods
+	 * (C0) and the time stamp counter running at the same frequency
+	 * also during C-states.
+	 */
+	sample->cpu_load = div64_u64(100 * sample->mperf, sample->tsc);
+
+	/*
+	 * The target P-state can be estimated with the following formula:
+	 * PercentPerformance = PercentBusy * (delta_aperf/delta_mperf);
+	 * (see Section 14.2 from Intel Software Developer Manual)
+	 * with PercentBusy = 100 * (delta_mperf / delta_tsc) and
+	 * PercentPerformance can be simplified with:
+	 * (delta_mperf * delta_aperf) / (delta_tsc * delta_mperf) =
+	 * delta_aperf / delta_tsc. Finally, we normalize core_busy_ratio,
+	 * which was our actual percent performance to what we requested
+	 * during the last sample period. The result will be a percentage of
+	 * busy at a specified pstate.
+	 */
+	core_busy_ratio = div64_u64(int_tofp(100) * sample->aperf *
+		pstate->max_pstate, sample->tsc * pstate->current_pstate);
+
+	sample->freq = div64_u64(sample->aperf * pstate->max_pstate *
+		pstate->scaling, sample->mperf);
+
+	return core_busy_ratio;
+}
+
+
 static inline int32_t intel_pstate_get_scaled_busy_estimate(struct cpudata *cpu)
 {
 	int32_t core_busy, max_pstate, current_pstate, sample_ratio;
@@ -974,7 +1012,7 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
 	from = cpu->pstate.current_pstate;
 
 	pid = &cpu->pid;
-	busy_scaled = intel_pstate_get_scaled_busy_estimate(cpu);
+	busy_scaled = intel_pstate_calc_scaled_busy(cpu);
 
 	ctl = pid_calc(pid, busy_scaled);
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v1 3/5] cpufreq: intel_pstate: account for non C0 time
  2015-11-23 13:06 [PATCH v1 0/5] intel_pstate: Use the cpu load first on Atom only Philippe Longepe
                   ` (5 preceding siblings ...)
  2015-11-23 13:06 ` [PATCH v1 3/5] cpufreq: intel_pstate: account for non C0 time Philippe Longepe
@ 2015-11-23 13:06 ` Philippe Longepe
  2015-11-23 13:06 ` [PATCH v1 4/5] cpufreq: intel_pstate: configurable busy calculation Philippe Longepe
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Philippe Longepe @ 2015-11-23 13:06 UTC (permalink / raw)
  To: linux-pm; +Cc: srinivas.pandruvada, Philippe Longepe, Stephane Gasparini

From: Philippe Longepe <philippe.longepe@intel.com>

Aperf and Mperf counter are not enough to determine the Target P-state
because they measure performance only when the targeted processor is
in the C0 state (active state).
Because of that, we were computing the average P-state during the last
period which can be very different from the average frequency
(or percentage of performance).

As defined in the SDM (section 14.2), the PercentPerformance is defined by:

PercentPerformance = PercentBusy * (delta_aperf / delta_mperf);

The PercentBusy (or load) can be estimated as the ratio of the mperf
counter running at a constant frequency only during active periods (C0)
and the time stamp counter running at the same frequency but also
during idle.

So, PercentBusy = 100 * (delta_mperf / delta_tsc)

and, PercentPerformance = 100 * (delta_mperf / delta_tsc) *
                                (delta_aperf / delta_mperf)
That can be simplified with:
PercentPerformance = 100 * (delta_aperf / delta_tsc)

Signed-off-by: Philippe Longepe <philippe.longepe@intel.com>
Signed-off-by: Stephane Gasparini <stephane.gasparini@linux.intel.com>
---
 drivers/cpufreq/intel_pstate.c | 40 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 39 insertions(+), 1 deletion(-)

diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index fa27ec5..f9acfb0 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -66,6 +66,7 @@ static inline int ceiling_fp(int32_t x)
 
 struct sample {
 	int32_t core_pct_perf;
+	int32_t	cpu_load;
 	u64 aperf;
 	u64 mperf;
 	u64 tsc;
@@ -922,6 +923,43 @@ static inline void intel_pstate_set_sample_time(struct cpudata *cpu)
 	mod_timer_pinned(&cpu->timer, jiffies + delay);
 }
 
+
+static inline int32_t intel_pstate_calc_scaled_busy(struct cpudata *cpu)
+{
+	struct sample *sample = &cpu->sample;
+	struct pstate_data *pstate = &cpu->pstate;
+	int64_t core_busy_ratio;
+
+	/*
+	 * The load can be estimated as the ratio of the mperf counter
+	 * running at a constant frequency only during active periods
+	 * (C0) and the time stamp counter running at the same frequency
+	 * also during C-states.
+	 */
+	sample->cpu_load = div64_u64(100 * sample->mperf, sample->tsc);
+
+	/*
+	 * The target P-state can be estimated with the following formula:
+	 * PercentPerformance = PercentBusy * (delta_aperf/delta_mperf);
+	 * (see Section 14.2 from Intel Software Developer Manual)
+	 * with PercentBusy = 100 * (delta_mperf / delta_tsc) and
+	 * PercentPerformance can be simplified with:
+	 * (delta_mperf * delta_aperf) / (delta_tsc * delta_mperf) =
+	 * delta_aperf / delta_tsc. Finally, we normalize core_busy_ratio,
+	 * which was our actual percent performance to what we requested
+	 * during the last sample period. The result will be a percentage of
+	 * busy at a specified pstate.
+	 */
+	core_busy_ratio = div64_u64(int_tofp(100) * sample->aperf *
+		pstate->max_pstate, sample->tsc * pstate->current_pstate);
+
+	sample->freq = div64_u64(sample->aperf * pstate->max_pstate *
+		pstate->scaling, sample->mperf);
+
+	return core_busy_ratio;
+}
+
+
 static inline int32_t intel_pstate_get_scaled_busy_estimate(struct cpudata *cpu)
 {
 	int32_t core_busy, max_pstate, current_pstate, sample_ratio;
@@ -974,7 +1012,7 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
 	from = cpu->pstate.current_pstate;
 
 	pid = &cpu->pid;
-	busy_scaled = intel_pstate_get_scaled_busy_estimate(cpu);
+	busy_scaled = intel_pstate_calc_scaled_busy(cpu);
 
 	ctl = pid_calc(pid, busy_scaled);
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v1 4/5] cpufreq: intel_pstate: configurable busy calculation
  2015-11-23 13:06 [PATCH v1 0/5] intel_pstate: Use the cpu load first on Atom only Philippe Longepe
                   ` (6 preceding siblings ...)
  2015-11-23 13:06 ` Philippe Longepe
@ 2015-11-23 13:06 ` Philippe Longepe
  2015-11-23 13:06 ` Philippe Longepe
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Philippe Longepe @ 2015-11-23 13:06 UTC (permalink / raw)
  To: linux-pm; +Cc: srinivas.pandruvada, Philippe Longepe

From: Philippe Longepe <philippe.longepe@intel.com>

Allow a configurable busy calculation which account for non C0 time
based on APERF and TSC and one via estimates.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Philippe Longepe <philippe.longepe@intel.com>
---
 drivers/cpufreq/intel_pstate.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index f9acfb0..4f08fa7 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -134,6 +134,7 @@ struct pstate_funcs {
 	int (*get_scaling)(void);
 	void (*set)(struct cpudata*, int pstate);
 	void (*get_vid)(struct cpudata *);
+	int32_t (*get_busy_percent)(struct cpudata *);
 };
 
 struct cpu_defaults {
@@ -141,6 +142,9 @@ struct cpu_defaults {
 	struct pstate_funcs funcs;
 };
 
+static inline int32_t intel_pstate_calc_scaled_busy(struct cpudata *cpu);
+static inline int32_t intel_pstate_get_scaled_busy_estimate(struct cpudata *cpu);
+
 static struct pstate_adjust_policy pid_params;
 static struct pstate_funcs pstate_funcs;
 static int hwp_active;
@@ -739,6 +743,7 @@ static struct cpu_defaults core_params = {
 		.get_turbo = core_get_turbo_pstate,
 		.get_scaling = core_get_scaling,
 		.set = core_set_pstate,
+		.get_busy_percent = intel_pstate_get_scaled_busy_estimate,
 	},
 };
 
@@ -759,6 +764,7 @@ static struct cpu_defaults silvermont_params = {
 		.set = atom_set_pstate,
 		.get_scaling = silvermont_get_scaling,
 		.get_vid = atom_get_vid,
+		.get_busy_percent = intel_pstate_calc_scaled_busy,
 	},
 };
 
@@ -779,6 +785,7 @@ static struct cpu_defaults airmont_params = {
 		.set = atom_set_pstate,
 		.get_scaling = airmont_get_scaling,
 		.get_vid = atom_get_vid,
+		.get_busy_percent = intel_pstate_calc_scaled_busy,
 	},
 };
 
@@ -798,6 +805,7 @@ static struct cpu_defaults knl_params = {
 		.get_turbo = knl_get_turbo_pstate,
 		.get_scaling = core_get_scaling,
 		.set = core_set_pstate,
+		.get_busy_percent = intel_pstate_get_scaled_busy_estimate,
 	},
 };
 
@@ -1012,7 +1020,7 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
 	from = cpu->pstate.current_pstate;
 
 	pid = &cpu->pid;
-	busy_scaled = intel_pstate_calc_scaled_busy(cpu);
+	busy_scaled = pstate_funcs.get_busy_percent(cpu);
 
 	ctl = pid_calc(pid, busy_scaled);
 
@@ -1276,6 +1284,8 @@ static void copy_cpu_funcs(struct pstate_funcs *funcs)
 	pstate_funcs.get_scaling = funcs->get_scaling;
 	pstate_funcs.set       = funcs->set;
 	pstate_funcs.get_vid   = funcs->get_vid;
+	pstate_funcs.get_busy_percent = funcs->get_busy_percent;
+
 }
 
 #if IS_ENABLED(CONFIG_ACPI)
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v1 4/5] cpufreq: intel_pstate: configurable busy calculation
  2015-11-23 13:06 [PATCH v1 0/5] intel_pstate: Use the cpu load first on Atom only Philippe Longepe
                   ` (7 preceding siblings ...)
  2015-11-23 13:06 ` [PATCH v1 4/5] cpufreq: intel_pstate: configurable busy calculation Philippe Longepe
@ 2015-11-23 13:06 ` Philippe Longepe
  2015-11-23 13:06 ` [PATCH v1 5/5] cpufreq: intel_pstate: try load instead of busy_scaled Philippe Longepe
  2015-11-23 13:06 ` Philippe Longepe
  10 siblings, 0 replies; 15+ messages in thread
From: Philippe Longepe @ 2015-11-23 13:06 UTC (permalink / raw)
  To: linux-pm; +Cc: srinivas.pandruvada, Philippe Longepe

From: Philippe Longepe <philippe.longepe@intel.com>

Allow a configurable busy calculation which account for non C0 time
based on APERF and TSC and one via estimates.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Philippe Longepe <philippe.longepe@intel.com>
---
 drivers/cpufreq/intel_pstate.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index f9acfb0..4f08fa7 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -134,6 +134,7 @@ struct pstate_funcs {
 	int (*get_scaling)(void);
 	void (*set)(struct cpudata*, int pstate);
 	void (*get_vid)(struct cpudata *);
+	int32_t (*get_busy_percent)(struct cpudata *);
 };
 
 struct cpu_defaults {
@@ -141,6 +142,9 @@ struct cpu_defaults {
 	struct pstate_funcs funcs;
 };
 
+static inline int32_t intel_pstate_calc_scaled_busy(struct cpudata *cpu);
+static inline int32_t intel_pstate_get_scaled_busy_estimate(struct cpudata *cpu);
+
 static struct pstate_adjust_policy pid_params;
 static struct pstate_funcs pstate_funcs;
 static int hwp_active;
@@ -739,6 +743,7 @@ static struct cpu_defaults core_params = {
 		.get_turbo = core_get_turbo_pstate,
 		.get_scaling = core_get_scaling,
 		.set = core_set_pstate,
+		.get_busy_percent = intel_pstate_get_scaled_busy_estimate,
 	},
 };
 
@@ -759,6 +764,7 @@ static struct cpu_defaults silvermont_params = {
 		.set = atom_set_pstate,
 		.get_scaling = silvermont_get_scaling,
 		.get_vid = atom_get_vid,
+		.get_busy_percent = intel_pstate_calc_scaled_busy,
 	},
 };
 
@@ -779,6 +785,7 @@ static struct cpu_defaults airmont_params = {
 		.set = atom_set_pstate,
 		.get_scaling = airmont_get_scaling,
 		.get_vid = atom_get_vid,
+		.get_busy_percent = intel_pstate_calc_scaled_busy,
 	},
 };
 
@@ -798,6 +805,7 @@ static struct cpu_defaults knl_params = {
 		.get_turbo = knl_get_turbo_pstate,
 		.get_scaling = core_get_scaling,
 		.set = core_set_pstate,
+		.get_busy_percent = intel_pstate_get_scaled_busy_estimate,
 	},
 };
 
@@ -1012,7 +1020,7 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
 	from = cpu->pstate.current_pstate;
 
 	pid = &cpu->pid;
-	busy_scaled = intel_pstate_calc_scaled_busy(cpu);
+	busy_scaled = pstate_funcs.get_busy_percent(cpu);
 
 	ctl = pid_calc(pid, busy_scaled);
 
@@ -1276,6 +1284,8 @@ static void copy_cpu_funcs(struct pstate_funcs *funcs)
 	pstate_funcs.get_scaling = funcs->get_scaling;
 	pstate_funcs.set       = funcs->set;
 	pstate_funcs.get_vid   = funcs->get_vid;
+	pstate_funcs.get_busy_percent = funcs->get_busy_percent;
+
 }
 
 #if IS_ENABLED(CONFIG_ACPI)
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v1 5/5] cpufreq: intel_pstate: try load instead of busy_scaled
  2015-11-23 13:06 [PATCH v1 0/5] intel_pstate: Use the cpu load first on Atom only Philippe Longepe
                   ` (8 preceding siblings ...)
  2015-11-23 13:06 ` Philippe Longepe
@ 2015-11-23 13:06 ` Philippe Longepe
  2015-11-23 16:10   ` Doug Smythies
  2015-11-24  1:33   ` Doug Smythies
  2015-11-23 13:06 ` Philippe Longepe
  10 siblings, 2 replies; 15+ messages in thread
From: Philippe Longepe @ 2015-11-23 13:06 UTC (permalink / raw)
  To: linux-pm; +Cc: srinivas.pandruvada, Philippe Longepe, Stephane Gasparini

From: Philippe Longepe <philippe.longepe@intel.com>

- use the load instead of busy scales
- reactivate ioboost

The time spent in iowait is converted into cycles at max freq,
so it increases the load during IOs.

Signed-off-by: Philippe Longepe <philippe.longepe@intel.com>
Signed-off-by: Stephane Gasparini <stephane.gasparini@intel.com>
---
 drivers/cpufreq/intel_pstate.c | 38 +++++++++++++++-----------------------
 1 file changed, 15 insertions(+), 23 deletions(-)

diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 4f08fa7..61b31d4 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -114,6 +114,7 @@ struct cpudata {
 	u64	prev_mperf;
 	u64	prev_tsc;
 	struct sample sample;
+	u64 prev_cummulative_iowait;
 };
 
 static struct cpudata **all_cpu_data;
@@ -931,12 +932,22 @@ static inline void intel_pstate_set_sample_time(struct cpudata *cpu)
 	mod_timer_pinned(&cpu->timer, jiffies + delay);
 }
 
-
 static inline int32_t intel_pstate_calc_scaled_busy(struct cpudata *cpu)
 {
+	u64 cummulative_iowait, delta_iowait_us;
+	u64 delta_iowait_mperf;
+	u64 mperf, now;
 	struct sample *sample = &cpu->sample;
 	struct pstate_data *pstate = &cpu->pstate;
-	int64_t core_busy_ratio;
+
+	cummulative_iowait = get_cpu_iowait_time_us(cpu->cpu, &now);
+	/* Convert iowait time into number of IO cycles spent at max_freq */
+	delta_iowait_us = cummulative_iowait - cpu->prev_cummulative_iowait;
+	delta_iowait_mperf = div64_u64(delta_iowait_us * cpu->pstate.scaling *
+		cpu->pstate.max_pstate, 1000);
+
+	mperf = cpu->sample.mperf + delta_iowait_mperf;
+	cpu->prev_cummulative_iowait = cummulative_iowait;
 
 	/*
 	 * The load can be estimated as the ratio of the mperf counter
@@ -944,30 +955,11 @@ static inline int32_t intel_pstate_calc_scaled_busy(struct cpudata *cpu)
 	 * (C0) and the time stamp counter running at the same frequency
 	 * also during C-states.
 	 */
-	sample->cpu_load = div64_u64(100 * sample->mperf, sample->tsc);
-
-	/*
-	 * The target P-state can be estimated with the following formula:
-	 * PercentPerformance = PercentBusy * (delta_aperf/delta_mperf);
-	 * (see Section 14.2 from Intel Software Developer Manual)
-	 * with PercentBusy = 100 * (delta_mperf / delta_tsc) and
-	 * PercentPerformance can be simplified with:
-	 * (delta_mperf * delta_aperf) / (delta_tsc * delta_mperf) =
-	 * delta_aperf / delta_tsc. Finally, we normalize core_busy_ratio,
-	 * which was our actual percent performance to what we requested
-	 * during the last sample period. The result will be a percentage of
-	 * busy at a specified pstate.
-	 */
-	core_busy_ratio = div64_u64(int_tofp(100) * sample->aperf *
-		pstate->max_pstate, sample->tsc * pstate->current_pstate);
+	sample->cpu_load = div64_u64(100 * mperf, sample->tsc);
 
-	sample->freq = div64_u64(sample->aperf * pstate->max_pstate *
-		pstate->scaling, sample->mperf);
-
-	return core_busy_ratio;
+	return sample->cpu_load;
 }
 
-
 static inline int32_t intel_pstate_get_scaled_busy_estimate(struct cpudata *cpu)
 {
 	int32_t core_busy, max_pstate, current_pstate, sample_ratio;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v1 5/5] cpufreq: intel_pstate: try load instead of busy_scaled
  2015-11-23 13:06 [PATCH v1 0/5] intel_pstate: Use the cpu load first on Atom only Philippe Longepe
                   ` (9 preceding siblings ...)
  2015-11-23 13:06 ` [PATCH v1 5/5] cpufreq: intel_pstate: try load instead of busy_scaled Philippe Longepe
@ 2015-11-23 13:06 ` Philippe Longepe
  10 siblings, 0 replies; 15+ messages in thread
From: Philippe Longepe @ 2015-11-23 13:06 UTC (permalink / raw)
  To: linux-pm; +Cc: srinivas.pandruvada, Philippe Longepe, Stephane Gasparini

From: Philippe Longepe <philippe.longepe@intel.com>

- use the load instead of busy scales
- reactivate ioboost

The time spent in iowait is converted into cycles at max freq,
so it increases the load during IOs.

Signed-off-by: Philippe Longepe <philippe.longepe@intel.com>
Signed-off-by: Stephane Gasparini <stephane.gasparini@intel.com>
---
 drivers/cpufreq/intel_pstate.c | 38 +++++++++++++++-----------------------
 1 file changed, 15 insertions(+), 23 deletions(-)

diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 4f08fa7..61b31d4 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -114,6 +114,7 @@ struct cpudata {
 	u64	prev_mperf;
 	u64	prev_tsc;
 	struct sample sample;
+	u64 prev_cummulative_iowait;
 };
 
 static struct cpudata **all_cpu_data;
@@ -931,12 +932,22 @@ static inline void intel_pstate_set_sample_time(struct cpudata *cpu)
 	mod_timer_pinned(&cpu->timer, jiffies + delay);
 }
 
-
 static inline int32_t intel_pstate_calc_scaled_busy(struct cpudata *cpu)
 {
+	u64 cummulative_iowait, delta_iowait_us;
+	u64 delta_iowait_mperf;
+	u64 mperf, now;
 	struct sample *sample = &cpu->sample;
 	struct pstate_data *pstate = &cpu->pstate;
-	int64_t core_busy_ratio;
+
+	cummulative_iowait = get_cpu_iowait_time_us(cpu->cpu, &now);
+	/* Convert iowait time into number of IO cycles spent at max_freq */
+	delta_iowait_us = cummulative_iowait - cpu->prev_cummulative_iowait;
+	delta_iowait_mperf = div64_u64(delta_iowait_us * cpu->pstate.scaling *
+		cpu->pstate.max_pstate, 1000);
+
+	mperf = cpu->sample.mperf + delta_iowait_mperf;
+	cpu->prev_cummulative_iowait = cummulative_iowait;
 
 	/*
 	 * The load can be estimated as the ratio of the mperf counter
@@ -944,30 +955,11 @@ static inline int32_t intel_pstate_calc_scaled_busy(struct cpudata *cpu)
 	 * (C0) and the time stamp counter running at the same frequency
 	 * also during C-states.
 	 */
-	sample->cpu_load = div64_u64(100 * sample->mperf, sample->tsc);
-
-	/*
-	 * The target P-state can be estimated with the following formula:
-	 * PercentPerformance = PercentBusy * (delta_aperf/delta_mperf);
-	 * (see Section 14.2 from Intel Software Developer Manual)
-	 * with PercentBusy = 100 * (delta_mperf / delta_tsc) and
-	 * PercentPerformance can be simplified with:
-	 * (delta_mperf * delta_aperf) / (delta_tsc * delta_mperf) =
-	 * delta_aperf / delta_tsc. Finally, we normalize core_busy_ratio,
-	 * which was our actual percent performance to what we requested
-	 * during the last sample period. The result will be a percentage of
-	 * busy at a specified pstate.
-	 */
-	core_busy_ratio = div64_u64(int_tofp(100) * sample->aperf *
-		pstate->max_pstate, sample->tsc * pstate->current_pstate);
+	sample->cpu_load = div64_u64(100 * mperf, sample->tsc);
 
-	sample->freq = div64_u64(sample->aperf * pstate->max_pstate *
-		pstate->scaling, sample->mperf);
-
-	return core_busy_ratio;
+	return sample->cpu_load;
 }
 
-
 static inline int32_t intel_pstate_get_scaled_busy_estimate(struct cpudata *cpu)
 {
 	int32_t core_busy, max_pstate, current_pstate, sample_ratio;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* RE: [PATCH v1 5/5] cpufreq: intel_pstate: try load instead of busy_scaled
  2015-11-23 13:06 ` [PATCH v1 5/5] cpufreq: intel_pstate: try load instead of busy_scaled Philippe Longepe
@ 2015-11-23 16:10   ` Doug Smythies
  2015-11-23 16:26     ` Philippe Longepe
  2015-11-24  1:33   ` Doug Smythies
  1 sibling, 1 reply; 15+ messages in thread
From: Doug Smythies @ 2015-11-23 16:10 UTC (permalink / raw)
  To: 'Philippe Longepe'
  Cc: srinivas.pandruvada, 'Stephane Gasparini', linux-pm

On 2015.11.23 05:47 Philippe Longepe wrote:

> static inline int32_t intel_pstate_calc_scaled_busy(struct cpudata *cpu)
>  {
> +	u64 cummulative_iowait, delta_iowait_us;
> +	u64 delta_iowait_mperf;
> +	u64 mperf, now;
>  	struct sample *sample = &cpu->sample;
>  	struct pstate_data *pstate = &cpu->pstate;

To prevent a build "unused variable 'pstate'" warning, suggest deleting that last line.
As of this patch 5 of 5 it is no longer used. i.e.:

-  	struct pstate_data *pstate = &cpu->pstate;



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v1 5/5] cpufreq: intel_pstate: try load instead of busy_scaled
  2015-11-23 16:10   ` Doug Smythies
@ 2015-11-23 16:26     ` Philippe Longepe
  0 siblings, 0 replies; 15+ messages in thread
From: Philippe Longepe @ 2015-11-23 16:26 UTC (permalink / raw)
  To: Doug Smythies; +Cc: srinivas.pandruvada, 'Stephane Gasparini', linux-pm

Thank you Smythies,

I found another small error on patch 5/5.

Let me doing few test on a CherryTrail and I'll resubmit a version 2 for 
this patch.

Thx,
Philippe

On 23/11/2015 17:10, Doug Smythies wrote:
> On 2015.11.23 05:47 Philippe Longepe wrote:
>
>> static inline int32_t intel_pstate_calc_scaled_busy(struct cpudata *cpu)
>>   {
>> +	u64 cummulative_iowait, delta_iowait_us;
>> +	u64 delta_iowait_mperf;
>> +	u64 mperf, now;
>>   	struct sample *sample = &cpu->sample;
>>   	struct pstate_data *pstate = &cpu->pstate;
> To prevent a build "unused variable 'pstate'" warning, suggest deleting that last line.
> As of this patch 5 of 5 it is no longer used. i.e.:
>
> -  	struct pstate_data *pstate = &cpu->pstate;
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: [PATCH v1 5/5] cpufreq: intel_pstate: try load instead of busy_scaled
  2015-11-23 13:06 ` [PATCH v1 5/5] cpufreq: intel_pstate: try load instead of busy_scaled Philippe Longepe
  2015-11-23 16:10   ` Doug Smythies
@ 2015-11-24  1:33   ` Doug Smythies
  1 sibling, 0 replies; 15+ messages in thread
From: Doug Smythies @ 2015-11-24  1:33 UTC (permalink / raw)
  To: 'Philippe Longepe'
  Cc: srinivas.pandruvada, 'Philippe Longepe',
	'Stephane Gasparini',
	linux-pm

On 2015.11.23 05:07 Philippe Longepe wrote:

> The time spent in iowait is converted into cycles at max freq,
> so it increases the load during IOs.
...
> +	cummulative_iowait = get_cpu_iowait_time_us(cpu->cpu, &now);
...

Did you consider to use get_cpu_idle_time_us(cpu_num, NULL) instead?
Why? Because it doesn't include iowait time, and thus just subtract
it from the kernel time to get the load, including iowait.

Crudely, below is what I have been trying for a month now (which also
makes the is mpref / tsc allowed or not discussion moot, because it
isn't used). Note, it can include iowait or not, you can observe by the
commented out lines (I have been testing both methods):

@@ -726,21 +737,32 @@ static inline void intel_pstate_sample(struct cpudata *cpu)
 
 	tsc = rdtsc();
 	local_irq_restore(flags);
+	time = ktime_get();
+	idle_us = get_cpu_idle_time_us(cpu_num, NULL);
+//	io_wait_us = get_cpu_iowait_time_us(cpu_num, NULL);
+	if (idle_us == -1ULL) {
+		/* !NO_HZ so we can rely on cpustat.idle */
+		idle = kcpustat_cpu(cpu_num).cpustat[CPUTIME_IDLE];
+//		io_wait = kcpustat_cpu(cpu_num).cpustat[CPUTIME_IOWAIT];
+		idle_us = cputime_to_usecs(idle);
+//		io_wait_us = cputime_to_usecs(io_wait);
+	}
...
+	cpu->sample.duration_us = ktime_us_delta(time, cpu->prev_time);
+	cpu->sample.idle_us = idle_us - cpu->prev_idle_us;
+//	cpu->sample.io_wait_us = io_wait_us - cpu->prev_io_wait_us;

And then the load calculation becomes (I use units of tenths of a percent in my stuff):

-	core_pct = int_tofp(sample->mperf) * int_tofp(1000);
-	core_pct = div64_u64(core_pct, int_tofp(sample->tsc));
+//	core_pct = sample->duration_us - sample->idle_us - sample->io_wait_us;
+	core_pct = sample->duration_us - sample->idle_us;
+	if (core_pct < 0) core_pct = 0;
+	core_pct = int_tofp(core_pct) * int_tofp(1000);
+	core_pct = div64_u64(core_pct, int_tofp(sample->duration_us));

In the above notice the special NO_HZ case. I don't this area well,
but I was of the understanding that the NO_HZ case requires special code.
(see also: fs/proc/stat.c, which is where I stole this stuff.) Note
that I haven't actually tested NO_HZ mode yet.

... Doug



^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2015-11-24  1:33 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-23 13:06 [PATCH v1 0/5] intel_pstate: Use the cpu load first on Atom only Philippe Longepe
2015-11-23 13:06 ` Philippe Longepe
2015-11-23 13:06 ` [PATCH v1 1/5] cpufreq: intel_pstate: change function name for calculation for busy Philippe Longepe
2015-11-23 13:06 ` [PATCH " Philippe Longepe
2015-11-23 13:06 ` [PATCH v1 2/5] cpufreq: intel_pstate: Rename current busy calculation function Philippe Longepe
2015-11-23 13:06 ` Philippe Longepe
2015-11-23 13:06 ` [PATCH v1 3/5] cpufreq: intel_pstate: account for non C0 time Philippe Longepe
2015-11-23 13:06 ` Philippe Longepe
2015-11-23 13:06 ` [PATCH v1 4/5] cpufreq: intel_pstate: configurable busy calculation Philippe Longepe
2015-11-23 13:06 ` Philippe Longepe
2015-11-23 13:06 ` [PATCH v1 5/5] cpufreq: intel_pstate: try load instead of busy_scaled Philippe Longepe
2015-11-23 16:10   ` Doug Smythies
2015-11-23 16:26     ` Philippe Longepe
2015-11-24  1:33   ` Doug Smythies
2015-11-23 13:06 ` Philippe Longepe

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.