Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8d940990 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull power management fixes from Rafael Wysocki:
 "These fix a few more intel_pstate issues and one small issue in the
  cpufreq core.

  Specifics:

   - Fix breakage in the intel_pstate's debugfs interface for PID
     controller tuning (Rafael Wysocki)

   - Fix computations related to P-state limits in intel_pstate to avoid
     excessive rounding errors leading to visible inaccuracies (Srinivas
     Pandruvada, Rafael Wysocki)

   - Add a missing newline to a message printed by one function in the
     cpufreq core and clean up that function (Rafael Wysocki)"

* tag 'pm-4.11-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  cpufreq: Fix and clean up show_cpuinfo_cur_freq()
  cpufreq: intel_pstate: Avoid percentages in limits-related computations
  cpufreq: intel_pstate: Correct frequency setting in the HWP mode
  cpufreq: intel_pstate: Update pid_params.sample_rate_ns in pid_param_set()
parents 8841b5f0 8b766e05
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -680,9 +680,11 @@ static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy,
					char *buf)
{
	unsigned int cur_freq = __cpufreq_get(policy);
	if (!cur_freq)
		return sprintf(buf, "<unknown>");

	if (cur_freq)
		return sprintf(buf, "%u\n", cur_freq);

	return sprintf(buf, "<unknown>\n");
}

/**
+31 −33
Original line number Diff line number Diff line
@@ -84,6 +84,11 @@ static inline u64 div_ext_fp(u64 x, u64 y)
	return div64_u64(x << EXT_FRAC_BITS, y);
}

static inline int32_t percent_ext_fp(int percent)
{
	return div_ext_fp(percent, 100);
}

/**
 * struct sample -	Store performance sample
 * @core_avg_perf:	Ratio of APERF/MPERF which is the actual average
@@ -845,12 +850,11 @@ static struct freq_attr *hwp_cpufreq_attrs[] = {

static void intel_pstate_hwp_set(struct cpufreq_policy *policy)
{
	int min, hw_min, max, hw_max, cpu, range, adj_range;
	int min, hw_min, max, hw_max, cpu;
	struct perf_limits *perf_limits = limits;
	u64 value, cap;

	for_each_cpu(cpu, policy->cpus) {
		int max_perf_pct, min_perf_pct;
		struct cpudata *cpu_data = all_cpu_data[cpu];
		s16 epp;

@@ -863,20 +867,15 @@ static void intel_pstate_hwp_set(struct cpufreq_policy *policy)
			hw_max = HWP_GUARANTEED_PERF(cap);
		else
			hw_max = HWP_HIGHEST_PERF(cap);
		range = hw_max - hw_min;

		max_perf_pct = perf_limits->max_perf_pct;
		min_perf_pct = perf_limits->min_perf_pct;
		min = fp_ext_toint(hw_max * perf_limits->min_perf);

		rdmsrl_on_cpu(cpu, MSR_HWP_REQUEST, &value);
		adj_range = min_perf_pct * range / 100;
		min = hw_min + adj_range;

		value &= ~HWP_MIN_PERF(~0L);
		value |= HWP_MIN_PERF(min);

		adj_range = max_perf_pct * range / 100;
		max = hw_min + adj_range;

		max = fp_ext_toint(hw_max * perf_limits->max_perf);
		value &= ~HWP_MAX_PERF(~0L);
		value |= HWP_MAX_PERF(max);

@@ -989,6 +988,7 @@ static void intel_pstate_update_policies(void)
static int pid_param_set(void *data, u64 val)
{
	*(u32 *)data = val;
	pid_params.sample_rate_ns = pid_params.sample_rate_ms * NSEC_PER_MSEC;
	intel_pstate_reset_all_pid();
	return 0;
}
@@ -1225,7 +1225,7 @@ static ssize_t store_max_perf_pct(struct kobject *a, struct attribute *b,
				   limits->max_perf_pct);
	limits->max_perf_pct = max(limits->min_perf_pct,
				   limits->max_perf_pct);
	limits->max_perf = div_ext_fp(limits->max_perf_pct, 100);
	limits->max_perf = percent_ext_fp(limits->max_perf_pct);

	intel_pstate_update_policies();

@@ -1262,7 +1262,7 @@ static ssize_t store_min_perf_pct(struct kobject *a, struct attribute *b,
				   limits->min_perf_pct);
	limits->min_perf_pct = min(limits->max_perf_pct,
				   limits->min_perf_pct);
	limits->min_perf = div_ext_fp(limits->min_perf_pct, 100);
	limits->min_perf = percent_ext_fp(limits->min_perf_pct);

	intel_pstate_update_policies();

@@ -2080,36 +2080,34 @@ static void intel_pstate_clear_update_util_hook(unsigned int cpu)
static void intel_pstate_update_perf_limits(struct cpufreq_policy *policy,
					    struct perf_limits *limits)
{
	int32_t max_policy_perf, min_policy_perf;

	limits->max_policy_pct = DIV_ROUND_UP(policy->max * 100,
					      policy->cpuinfo.max_freq);
	limits->max_policy_pct = clamp_t(int, limits->max_policy_pct, 0, 100);
	max_policy_perf = div_ext_fp(policy->max, policy->cpuinfo.max_freq);
	max_policy_perf = clamp_t(int32_t, max_policy_perf, 0, int_ext_tofp(1));
	if (policy->max == policy->min) {
		limits->min_policy_pct = limits->max_policy_pct;
		min_policy_perf = max_policy_perf;
	} else {
		limits->min_policy_pct = DIV_ROUND_UP(policy->min * 100,
		min_policy_perf = div_ext_fp(policy->min,
					     policy->cpuinfo.max_freq);
		limits->min_policy_pct = clamp_t(int, limits->min_policy_pct,
						 0, 100);
		min_policy_perf = clamp_t(int32_t, min_policy_perf,
					  0, max_policy_perf);
	}

	/* Normalize user input to [min_policy_pct, max_policy_pct] */
	limits->min_perf_pct = max(limits->min_policy_pct,
				   limits->min_sysfs_pct);
	limits->min_perf_pct = min(limits->max_policy_pct,
				   limits->min_perf_pct);
	limits->max_perf_pct = min(limits->max_policy_pct,
				   limits->max_sysfs_pct);
	limits->max_perf_pct = max(limits->min_policy_pct,
				   limits->max_perf_pct);
	/* Normalize user input to [min_perf, max_perf] */
	limits->min_perf = max(min_policy_perf,
			       percent_ext_fp(limits->min_sysfs_pct));
	limits->min_perf = min(limits->min_perf, max_policy_perf);
	limits->max_perf = min(max_policy_perf,
			       percent_ext_fp(limits->max_sysfs_pct));
	limits->max_perf = max(min_policy_perf, limits->max_perf);

	/* Make sure min_perf_pct <= max_perf_pct */
	limits->min_perf_pct = min(limits->max_perf_pct, limits->min_perf_pct);
	/* Make sure min_perf <= max_perf */
	limits->min_perf = min(limits->min_perf, limits->max_perf);

	limits->min_perf = div_ext_fp(limits->min_perf_pct, 100);
	limits->max_perf = div_ext_fp(limits->max_perf_pct, 100);
	limits->max_perf = round_up(limits->max_perf, EXT_FRAC_BITS);
	limits->min_perf = round_up(limits->min_perf, EXT_FRAC_BITS);
	limits->max_perf_pct = fp_ext_toint(limits->max_perf * 100);
	limits->min_perf_pct = fp_ext_toint(limits->min_perf * 100);

	pr_debug("cpu:%d max_perf_pct:%d min_perf_pct:%d\n", policy->cpu,
		 limits->max_perf_pct, limits->min_perf_pct);