Commit f1bbf5bb authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

cpufreq: intel_pstate: Rearrange freq QoS updates using __free()

Move the code from the for_each_possible_cpu() loop in update_qos_request()
to a separate function and use __free() for cpufreq policy reference
counting in it to avoid having to call cpufreq_cpu_put() repeatedly (or
using goto).

While at it, rename update_qos_request() to update_qos_requests()
because it updates multiple requests in one go.

No intentional functional impact.

Link: https://lore.kernel.org/linux-pm/CAJZ5v0gN1T5woSF0tO=TbAh+2-sWzxFjWyDbB7wG2TFCOU01iQ@mail.gmail.com/


Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: default avatarZihuan Zhang <zhangzihuan@kylinos.cn>
Link: https://patch.msgid.link/3026597.e9J7NaK4W3@rafael.j.wysocki


[ rjw: Rename "cpu" to "cpudata" and "cpunum" to "cpu" in new code ]
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 69e5d50f
Loading
Loading
Loading
Loading
+28 −29
Original line number Diff line number Diff line
@@ -1652,28 +1652,22 @@ static ssize_t store_no_turbo(struct kobject *a, struct kobj_attribute *b,
	return count;
}

static void update_qos_request(enum freq_qos_req_type type)
static void update_cpu_qos_request(int cpu, enum freq_qos_req_type type)
{
	struct cpudata *cpudata = all_cpu_data[cpu];
	struct freq_qos_request *req;
	struct cpufreq_policy *policy;
	int i;

	for_each_possible_cpu(i) {
		struct cpudata *cpu = all_cpu_data[i];
	unsigned int freq, perf_pct;

		policy = cpufreq_cpu_get(i);
	struct cpufreq_policy *policy __free(put_cpufreq_policy) = cpufreq_cpu_get(cpu);
	if (!policy)
			continue;
		return;

	req = policy->driver_data;
		if (!req) {
			cpufreq_cpu_put(policy);
			continue;
		}
	if (!req)
		return;

	if (hwp_active)
			intel_pstate_get_hwp_cap(cpu);
		intel_pstate_get_hwp_cap(cpudata);

	if (type == FREQ_QOS_MIN) {
		perf_pct = global.min_perf_pct;
@@ -1682,13 +1676,18 @@ static void update_qos_request(enum freq_qos_req_type type)
		perf_pct = global.max_perf_pct;
	}

		freq = DIV_ROUND_UP(cpu->pstate.turbo_freq * perf_pct, 100);
	freq = DIV_ROUND_UP(cpudata->pstate.turbo_freq * perf_pct, 100);

	if (freq_qos_update_request(req, freq) < 0)
			pr_warn("Failed to update freq constraint: CPU%d\n", i);

		cpufreq_cpu_put(policy);
		pr_warn("Failed to update freq constraint: CPU%d\n", cpu);
}

static void update_qos_requests(enum freq_qos_req_type type)
{
	int i;

	for_each_possible_cpu(i)
		update_cpu_qos_request(i, type);
}

static ssize_t store_max_perf_pct(struct kobject *a, struct kobj_attribute *b,
@@ -1717,7 +1716,7 @@ static ssize_t store_max_perf_pct(struct kobject *a, struct kobj_attribute *b,
	if (intel_pstate_driver == &intel_pstate)
		intel_pstate_update_policies();
	else
		update_qos_request(FREQ_QOS_MAX);
		update_qos_requests(FREQ_QOS_MAX);

	mutex_unlock(&intel_pstate_driver_lock);

@@ -1751,7 +1750,7 @@ static ssize_t store_min_perf_pct(struct kobject *a, struct kobj_attribute *b,
	if (intel_pstate_driver == &intel_pstate)
		intel_pstate_update_policies();
	else
		update_qos_request(FREQ_QOS_MIN);
		update_qos_requests(FREQ_QOS_MIN);

	mutex_unlock(&intel_pstate_driver_lock);