* [RFC PATCH 1/2] pm_qos: Rename freq to interval constraint
@ 2023-12-01 19:07 Daniel Lezcano
2023-12-01 19:07 ` [RFC PATCH 2/2] PM: QoS: Add a performance QoS Daniel Lezcano
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Daniel Lezcano @ 2023-12-01 19:07 UTC (permalink / raw)
To: rjw; +Cc: caleb.connolly, lina.iyer, linux-pm, mani, linux-kernel,
lukasz.luba
The frequency pm_qos relies on a couple of values, the min and max
frequencies. However more pm_qos will be added with the same logic of
a couple of min and max. Instead of writing new set of constraints as
well as type, etc... let's rename freq_* to a more generic name
interval_*
That way, new qos interval based can be added easily.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
drivers/base/power/qos.c | 4 +--
drivers/powercap/dtpm_cpu.c | 2 +-
drivers/thermal/cpufreq_cooling.c | 2 +-
include/linux/cpufreq.h | 6 ++--
include/linux/pm_qos.h | 55 ++++++++++++++++---------------
kernel/power/qos.c | 53 +++++++++++++++--------------
6 files changed, 61 insertions(+), 61 deletions(-)
diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c
index 8e93167f1783..561d2a0e106c 100644
--- a/drivers/base/power/qos.c
+++ b/drivers/base/power/qos.c
@@ -285,14 +285,14 @@ void dev_pm_qos_constraints_destroy(struct device *dev)
memset(req, 0, sizeof(*req));
}
- c = &qos->freq.min_freq;
+ c = &qos->freq.min;
plist_for_each_entry_safe(req, tmp, &c->list, data.freq.pnode) {
apply_constraint(req, PM_QOS_REMOVE_REQ,
PM_QOS_MIN_FREQUENCY_DEFAULT_VALUE);
memset(req, 0, sizeof(*req));
}
- c = &qos->freq.max_freq;
+ c = &qos->freq.max;
plist_for_each_entry_safe(req, tmp, &c->list, data.freq.pnode) {
apply_constraint(req, PM_QOS_REMOVE_REQ,
PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE);
diff --git a/drivers/powercap/dtpm_cpu.c b/drivers/powercap/dtpm_cpu.c
index 2ff7717530bf..6587c94d0127 100644
--- a/drivers/powercap/dtpm_cpu.c
+++ b/drivers/powercap/dtpm_cpu.c
@@ -28,7 +28,7 @@
struct dtpm_cpu {
struct dtpm dtpm;
- struct freq_qos_request qos_req;
+ struct interval_qos_request qos_req;
int cpu;
};
diff --git a/drivers/thermal/cpufreq_cooling.c b/drivers/thermal/cpufreq_cooling.c
index e2cc7bd30862..72e9f0cde55c 100644
--- a/drivers/thermal/cpufreq_cooling.c
+++ b/drivers/thermal/cpufreq_cooling.c
@@ -77,7 +77,7 @@ struct cpufreq_cooling_device {
#ifndef CONFIG_SMP
struct time_in_idle *idle_time;
#endif
- struct freq_qos_request qos_req;
+ struct interval_qos_request qos_req;
};
#ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 71d186d6933a..7e2d66c37535 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -80,9 +80,9 @@ struct cpufreq_policy {
struct work_struct update; /* if update_policy() needs to be
* called, but you're in IRQ context */
- struct freq_constraints constraints;
- struct freq_qos_request *min_freq_req;
- struct freq_qos_request *max_freq_req;
+ struct interval_constraints constraints;
+ struct interval_qos_request *min_freq_req;
+ struct interval_qos_request *max_freq_req;
struct cpufreq_frequency_table *freq_table;
enum cpufreq_table_sorting freq_table_sorted;
diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h
index 4a69d4af3ff8..a662ac918e3e 100644
--- a/include/linux/pm_qos.h
+++ b/include/linux/pm_qos.h
@@ -77,25 +77,26 @@ struct pm_qos_flags {
#define FREQ_QOS_MIN_DEFAULT_VALUE 0
#define FREQ_QOS_MAX_DEFAULT_VALUE S32_MAX
-enum freq_qos_req_type {
- FREQ_QOS_MIN = 1,
+enum interval_qos_req_type {
+ INTERVAL_QOS_MIN = 1,
+ INTERVAL_QOS_MAX,
+ FREQ_QOS_MIN,
FREQ_QOS_MAX,
};
-struct freq_constraints {
- struct pm_qos_constraints min_freq;
- struct blocking_notifier_head min_freq_notifiers;
- struct pm_qos_constraints max_freq;
- struct blocking_notifier_head max_freq_notifiers;
+struct interval_constraints {
+ struct pm_qos_constraints min;
+ struct blocking_notifier_head min_notifiers;
+ struct pm_qos_constraints max;
+ struct blocking_notifier_head max_notifiers;
};
-struct freq_qos_request {
- enum freq_qos_req_type type;
+struct interval_qos_request {
+ enum interval_qos_req_type type;
struct plist_node pnode;
- struct freq_constraints *qos;
+ struct interval_constraints *qos;
};
-
enum dev_pm_qos_req_type {
DEV_PM_QOS_RESUME_LATENCY = 1,
DEV_PM_QOS_LATENCY_TOLERANCE,
@@ -109,7 +110,7 @@ struct dev_pm_qos_request {
union {
struct plist_node pnode;
struct pm_qos_flags_request flr;
- struct freq_qos_request freq;
+ struct interval_qos_request freq;
} data;
struct device *dev;
};
@@ -117,7 +118,7 @@ struct dev_pm_qos_request {
struct dev_pm_qos {
struct pm_qos_constraints resume_latency;
struct pm_qos_constraints latency_tolerance;
- struct freq_constraints freq;
+ struct interval_constraints freq;
struct pm_qos_flags flags;
struct dev_pm_qos_request *resume_latency_req;
struct dev_pm_qos_request *latency_tolerance_req;
@@ -291,29 +292,29 @@ static inline s32 dev_pm_qos_raw_resume_latency(struct device *dev)
}
#endif
-static inline int freq_qos_request_active(struct freq_qos_request *req)
+static inline int freq_qos_request_active(struct interval_qos_request *req)
{
return !IS_ERR_OR_NULL(req->qos);
}
-void freq_constraints_init(struct freq_constraints *qos);
+void freq_constraints_init(struct interval_constraints *qos);
-s32 freq_qos_read_value(struct freq_constraints *qos,
- enum freq_qos_req_type type);
+s32 freq_qos_read_value(struct interval_constraints *qos,
+ enum interval_qos_req_type type);
-int freq_qos_add_request(struct freq_constraints *qos,
- struct freq_qos_request *req,
- enum freq_qos_req_type type, s32 value);
-int freq_qos_update_request(struct freq_qos_request *req, s32 new_value);
-int freq_qos_remove_request(struct freq_qos_request *req);
-int freq_qos_apply(struct freq_qos_request *req,
+int freq_qos_add_request(struct interval_constraints *qos,
+ struct interval_qos_request *req,
+ enum interval_qos_req_type type, s32 value);
+int freq_qos_update_request(struct interval_qos_request *req, s32 new_value);
+int freq_qos_remove_request(struct interval_qos_request *req);
+int freq_qos_apply(struct interval_qos_request *req,
enum pm_qos_req_action action, s32 value);
-int freq_qos_add_notifier(struct freq_constraints *qos,
- enum freq_qos_req_type type,
+int freq_qos_add_notifier(struct interval_constraints *qos,
+ enum interval_qos_req_type type,
struct notifier_block *notifier);
-int freq_qos_remove_notifier(struct freq_constraints *qos,
- enum freq_qos_req_type type,
+int freq_qos_remove_notifier(struct interval_constraints *qos,
+ enum interval_qos_req_type type,
struct notifier_block *notifier);
#endif
diff --git a/kernel/power/qos.c b/kernel/power/qos.c
index 4244b069442e..6ff6c494f84d 100644
--- a/kernel/power/qos.c
+++ b/kernel/power/qos.c
@@ -440,26 +440,26 @@ static inline bool freq_qos_value_invalid(s32 value)
* freq_constraints_init - Initialize frequency QoS constraints.
* @qos: Frequency QoS constraints to initialize.
*/
-void freq_constraints_init(struct freq_constraints *qos)
+void freq_constraints_init(struct interval_constraints *qos)
{
struct pm_qos_constraints *c;
- c = &qos->min_freq;
+ c = &qos->min;
plist_head_init(&c->list);
c->target_value = FREQ_QOS_MIN_DEFAULT_VALUE;
c->default_value = FREQ_QOS_MIN_DEFAULT_VALUE;
c->no_constraint_value = FREQ_QOS_MIN_DEFAULT_VALUE;
c->type = PM_QOS_MAX;
- c->notifiers = &qos->min_freq_notifiers;
+ c->notifiers = &qos->min_notifiers;
BLOCKING_INIT_NOTIFIER_HEAD(c->notifiers);
- c = &qos->max_freq;
+ c = &qos->max;
plist_head_init(&c->list);
c->target_value = FREQ_QOS_MAX_DEFAULT_VALUE;
c->default_value = FREQ_QOS_MAX_DEFAULT_VALUE;
c->no_constraint_value = FREQ_QOS_MAX_DEFAULT_VALUE;
c->type = PM_QOS_MIN;
- c->notifiers = &qos->max_freq_notifiers;
+ c->notifiers = &qos->max_notifiers;
BLOCKING_INIT_NOTIFIER_HEAD(c->notifiers);
}
@@ -468,8 +468,8 @@ void freq_constraints_init(struct freq_constraints *qos)
* @qos: Constraints to evaluate.
* @type: QoS request type.
*/
-s32 freq_qos_read_value(struct freq_constraints *qos,
- enum freq_qos_req_type type)
+s32 freq_qos_read_value(struct interval_constraints *qos,
+ enum interval_qos_req_type type)
{
s32 ret;
@@ -477,15 +477,14 @@ s32 freq_qos_read_value(struct freq_constraints *qos,
case FREQ_QOS_MIN:
ret = IS_ERR_OR_NULL(qos) ?
FREQ_QOS_MIN_DEFAULT_VALUE :
- pm_qos_read_value(&qos->min_freq);
+ pm_qos_read_value(&qos->min);
break;
case FREQ_QOS_MAX:
ret = IS_ERR_OR_NULL(qos) ?
FREQ_QOS_MAX_DEFAULT_VALUE :
- pm_qos_read_value(&qos->max_freq);
+ pm_qos_read_value(&qos->max);
break;
default:
- WARN_ON(1);
ret = 0;
}
@@ -500,18 +499,18 @@ s32 freq_qos_read_value(struct freq_constraints *qos,
*
* This is only meant to be called from inside pm_qos, not drivers.
*/
-int freq_qos_apply(struct freq_qos_request *req,
- enum pm_qos_req_action action, s32 value)
+int freq_qos_apply(struct interval_qos_request *req,
+ enum pm_qos_req_action action, s32 value)
{
int ret;
switch(req->type) {
case FREQ_QOS_MIN:
- ret = pm_qos_update_target(&req->qos->min_freq, &req->pnode,
+ ret = pm_qos_update_target(&req->qos->min, &req->pnode,
action, value);
break;
case FREQ_QOS_MAX:
- ret = pm_qos_update_target(&req->qos->max_freq, &req->pnode,
+ ret = pm_qos_update_target(&req->qos->max, &req->pnode,
action, value);
break;
default:
@@ -535,9 +534,9 @@ int freq_qos_apply(struct freq_qos_request *req,
* Return 1 if the effective constraint value has changed, 0 if the effective
* constraint value has not changed, or a negative error code on failures.
*/
-int freq_qos_add_request(struct freq_constraints *qos,
- struct freq_qos_request *req,
- enum freq_qos_req_type type, s32 value)
+int freq_qos_add_request(struct interval_constraints *qos,
+ struct interval_qos_request *req,
+ enum interval_qos_req_type type, s32 value)
{
int ret;
@@ -571,7 +570,7 @@ EXPORT_SYMBOL_GPL(freq_qos_add_request);
* Return 1 if the effective constraint value has changed, 0 if the effective
* constraint value has not changed, or a negative error code on failures.
*/
-int freq_qos_update_request(struct freq_qos_request *req, s32 new_value)
+int freq_qos_update_request(struct interval_qos_request *req, s32 new_value)
{
if (!req || freq_qos_value_invalid(new_value))
return -EINVAL;
@@ -597,7 +596,7 @@ EXPORT_SYMBOL_GPL(freq_qos_update_request);
* Return 1 if the effective constraint value has changed, 0 if the effective
* constraint value has not changed, or a negative error code on failures.
*/
-int freq_qos_remove_request(struct freq_qos_request *req)
+int freq_qos_remove_request(struct interval_qos_request *req)
{
int ret;
@@ -622,8 +621,8 @@ EXPORT_SYMBOL_GPL(freq_qos_remove_request);
* @type: Request type.
* @notifier: Notifier block to add.
*/
-int freq_qos_add_notifier(struct freq_constraints *qos,
- enum freq_qos_req_type type,
+int freq_qos_add_notifier(struct interval_constraints *qos,
+ enum interval_qos_req_type type,
struct notifier_block *notifier)
{
int ret;
@@ -633,11 +632,11 @@ int freq_qos_add_notifier(struct freq_constraints *qos,
switch (type) {
case FREQ_QOS_MIN:
- ret = blocking_notifier_chain_register(qos->min_freq.notifiers,
+ ret = blocking_notifier_chain_register(qos->min.notifiers,
notifier);
break;
case FREQ_QOS_MAX:
- ret = blocking_notifier_chain_register(qos->max_freq.notifiers,
+ ret = blocking_notifier_chain_register(qos->max.notifiers,
notifier);
break;
default:
@@ -655,8 +654,8 @@ EXPORT_SYMBOL_GPL(freq_qos_add_notifier);
* @type: Request type.
* @notifier: Notifier block to remove.
*/
-int freq_qos_remove_notifier(struct freq_constraints *qos,
- enum freq_qos_req_type type,
+int freq_qos_remove_notifier(struct interval_constraints *qos,
+ enum interval_qos_req_type type,
struct notifier_block *notifier)
{
int ret;
@@ -666,11 +665,11 @@ int freq_qos_remove_notifier(struct freq_constraints *qos,
switch (type) {
case FREQ_QOS_MIN:
- ret = blocking_notifier_chain_unregister(qos->min_freq.notifiers,
+ ret = blocking_notifier_chain_unregister(qos->min.notifiers,
notifier);
break;
case FREQ_QOS_MAX:
- ret = blocking_notifier_chain_unregister(qos->max_freq.notifiers,
+ ret = blocking_notifier_chain_unregister(qos->max.notifiers,
notifier);
break;
default:
--
2.34.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [RFC PATCH 2/2] PM: QoS: Add a performance QoS
2023-12-01 19:07 [RFC PATCH 1/2] pm_qos: Rename freq to interval constraint Daniel Lezcano
@ 2023-12-01 19:07 ` Daniel Lezcano
2023-12-05 12:29 ` kernel test robot
2023-12-05 12:40 ` kernel test robot
2023-12-05 14:26 ` [RFC PATCH 1/2] pm_qos: Rename freq to interval constraint kernel test robot
2023-12-08 20:42 ` Rafael J. Wysocki
2 siblings, 2 replies; 6+ messages in thread
From: Daniel Lezcano @ 2023-12-01 19:07 UTC (permalink / raw)
To: rjw; +Cc: caleb.connolly, lina.iyer, linux-pm, mani, linux-kernel,
lukasz.luba
Currently cpufreq and devfreq are using the freq QoS to aggregate the
requests for frequency minimum and maximum limits.
However, there are new devices wanting to act not on a frequency limit
but on a performance index limit. Those need also to export to
userspace the knob to act on their performance limits.
This change provides a performance limiter QoS based on a minimum /
maximum performance values. At init time, the limits of the interval
are 0 / 1024. It is up to the backend to convert the 1024 to the
maximum performance state. So if the performance must be limited to
50%, it should set to maximum limit to 512 where the backend will end
up by converting (max performance index / 2). The same applies for the
minimum. Obviously, the min can not be greater than the max.
There are a couple of things making this change a RFC:
1. With the example above, if there is a odd number like 5 for the
number of performance indexes and we ask for 512 (so 50%), what would
be the performance index computed? (5/2=2 or 5/2=3)? (I would say the
minimum otherwise we end up with a performance limit greater than
what we actually asked for).
2. The conversion from 1024 to a performance index will inevatibly
end up to a state above or below the percentage given. Shall it be
reflected in the value set? eg. We want to apply a performance limit
to be 33% maximum. So it is, 1024 x 0.333333 = 314. If there are 20
performance indexes, that will be (20 x 314) / 1024 = 6.13, so index
6. Shall we convert this index back to the requested performance
limit to (6.13 x 1024) / 20 = 307 ? (So requested is 314 but it is
actually 307).
The end goal is to make the freq QoS and perf QoS to co-exist together
in the next changes in the different backends. A change of one of the
QoS impacts the other. For instance if there are 5 performance states
and we set a performance limit to 80%, then the maximum state will 4.
For the long term, when those can co-exist, then we can implement a
cooling device based on the performance Qos which will be generic for
all devices using this QoS. That will imply the CPUs, the GPUs and any
devfreq devices. So devfreq and cpufreq cooling devices can be merged
into a single performance cooling device which will be generic for all
devices with a performance limit QoS.
In a similar way, in the future, a power QoS could be added also and a
power based cooling device. So any device with the energy model can
become a cooling device and the power computation part in the cooling
devices will move to the back ends. We will end up with a generic
power cooling device compatible with all power capable devices.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
drivers/base/power/power.h | 2 +
drivers/base/power/qos.c | 158 +++++++++++++++++++++++++-
drivers/base/power/sysfs.c | 92 +++++++++++++++
include/linux/cpufreq.h | 2 +
include/linux/pm_qos.h | 42 +++++++
kernel/power/qos.c | 225 +++++++++++++++++++++++++++++++++++++
6 files changed, 517 insertions(+), 4 deletions(-)
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h
index 922ed457db19..eb1a77a7a0f4 100644
--- a/drivers/base/power/power.h
+++ b/drivers/base/power/power.h
@@ -78,6 +78,8 @@ extern int pm_qos_sysfs_add_flags(struct device *dev);
extern void pm_qos_sysfs_remove_flags(struct device *dev);
extern int pm_qos_sysfs_add_latency_tolerance(struct device *dev);
extern void pm_qos_sysfs_remove_latency_tolerance(struct device *dev);
+extern int pm_qos_sysfs_add_perf_limit(struct device *dev);
+extern void pm_qos_sysfs_remove_perf_limit(struct device *dev);
extern int dpm_sysfs_change_owner(struct device *dev, kuid_t kuid, kgid_t kgid);
#else /* CONFIG_PM */
diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c
index 561d2a0e106c..efc5b3d88d8d 100644
--- a/drivers/base/power/qos.c
+++ b/drivers/base/power/qos.c
@@ -128,6 +128,14 @@ s32 dev_pm_qos_read_value(struct device *dev, enum dev_pm_qos_req_type type)
ret = IS_ERR_OR_NULL(qos) ? PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE
: freq_qos_read_value(&qos->freq, FREQ_QOS_MAX);
break;
+ case DEV_PM_QOS_MIN_PERF:
+ ret = IS_ERR_OR_NULL(qos) ? PM_QOS_MIN_PERF_DEFAULT_VALUE
+ : perf_qos_read_value(&qos->perf, INTERVAL_QOS_MIN);
+ break;
+ case DEV_PM_QOS_MAX_PERF:
+ ret = IS_ERR_OR_NULL(qos) ? PM_QOS_MAX_PERF_DEFAULT_VALUE
+ : perf_qos_read_value(&qos->perf, INTERVAL_QOS_MAX);
+ break;
default:
WARN_ON(1);
ret = 0;
@@ -177,6 +185,10 @@ static int apply_constraint(struct dev_pm_qos_request *req,
ret = pm_qos_update_flags(&qos->flags, &req->data.flr,
action, value);
break;
+ case DEV_PM_QOS_MIN_PERF:
+ case DEV_PM_QOS_MAX_PERF:
+ ret = perf_qos_apply(&req->data.perf, action, value);
+ break;
default:
ret = -EINVAL;
}
@@ -223,6 +235,20 @@ static int dev_pm_qos_constraints_allocate(struct device *dev)
c->no_constraint_value = PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT;
c->type = PM_QOS_MIN;
+ c = &qos->perf.min;
+ plist_head_init(&c->list);
+ c->target_value = PM_QOS_MIN_PERF_DEFAULT_VALUE;
+ c->default_value = PM_QOS_MIN_PERF_DEFAULT_VALUE;
+ c->no_constraint_value = PM_QOS_MIN_PERF_DEFAULT_VALUE;
+ c->type = PM_QOS_MAX;
+
+ c = &qos->perf.max;
+ plist_head_init(&c->list);
+ c->target_value = PM_QOS_MAX_PERF_DEFAULT_VALUE;
+ c->default_value = PM_QOS_MAX_PERF_DEFAULT_VALUE;
+ c->no_constraint_value = PM_QOS_MAX_PERF_DEFAULT_VALUE;
+ c->type = PM_QOS_MIN;
+
freq_constraints_init(&qos->freq);
INIT_LIST_HEAD(&qos->flags.list);
@@ -299,6 +325,20 @@ void dev_pm_qos_constraints_destroy(struct device *dev)
memset(req, 0, sizeof(*req));
}
+ c = &qos->perf.min;
+ plist_for_each_entry_safe(req, tmp, &c->list, data.freq.pnode) {
+ apply_constraint(req, PM_QOS_REMOVE_REQ,
+ PM_QOS_MIN_PERF_DEFAULT_VALUE);
+ memset(req, 0, sizeof(*req));
+ }
+
+ c = &qos->perf.max;
+ plist_for_each_entry_safe(req, tmp, &c->list, data.freq.pnode) {
+ apply_constraint(req, PM_QOS_REMOVE_REQ,
+ PM_QOS_MAX_PERF_DEFAULT_VALUE);
+ memset(req, 0, sizeof(*req));
+ }
+
f = &qos->flags;
list_for_each_entry_safe(req, tmp, &f->list, data.flr.node) {
apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE);
@@ -349,17 +389,32 @@ static int __dev_pm_qos_add_request(struct device *dev,
req->dev = dev;
req->type = type;
- if (req->type == DEV_PM_QOS_MIN_FREQUENCY)
+
+ switch (type) {
+ case DEV_PM_QOS_MIN_FREQUENCY:
ret = freq_qos_add_request(&dev->power.qos->freq,
&req->data.freq,
FREQ_QOS_MIN, value);
- else if (req->type == DEV_PM_QOS_MAX_FREQUENCY)
+ break;
+ case DEV_PM_QOS_MAX_FREQUENCY:
ret = freq_qos_add_request(&dev->power.qos->freq,
&req->data.freq,
FREQ_QOS_MAX, value);
- else
+ break;
+ case DEV_PM_QOS_MIN_PERF:
+ ret = perf_qos_add_request(&dev->power.qos->perf,
+ &req->data.perf,
+ INTERVAL_QOS_MIN, value);
+ break;
+ case DEV_PM_QOS_MAX_PERF:
+ ret = perf_qos_add_request(&dev->power.qos->perf,
+ &req->data.perf,
+ INTERVAL_QOS_MAX, value);
+ break;
+ default:
ret = apply_constraint(req, PM_QOS_ADD_REQ, value);
-
+ break;
+ }
return ret;
}
@@ -427,6 +482,10 @@ static int __dev_pm_qos_update_request(struct dev_pm_qos_request *req,
case DEV_PM_QOS_MAX_FREQUENCY:
curr_value = req->data.freq.pnode.prio;
break;
+ case DEV_PM_QOS_MIN_PERF:
+ case DEV_PM_QOS_MAX_PERF:
+ curr_value = req->data.perf.pnode.prio;
+ break;
case DEV_PM_QOS_FLAGS:
curr_value = req->data.flr.flags;
break;
@@ -674,6 +733,14 @@ static void __dev_pm_qos_drop_user_request(struct device *dev,
req = dev->power.qos->flags_req;
dev->power.qos->flags_req = NULL;
break;
+ case DEV_PM_QOS_MIN_PERF:
+ req = dev->power.qos->perf_min_req;
+ dev->power.qos->perf_min_req = NULL;
+ break;
+ case DEV_PM_QOS_MAX_PERF:
+ req = dev->power.qos->perf_max_req;
+ dev->power.qos->perf_max_req = NULL;
+ break;
default:
WARN_ON(1);
return;
@@ -980,3 +1047,86 @@ void dev_pm_qos_hide_latency_tolerance(struct device *dev)
pm_runtime_put(dev);
}
EXPORT_SYMBOL_GPL(dev_pm_qos_hide_latency_tolerance);
+
+int dev_pm_qos_expose_perf_limit(struct device *dev)
+{
+ struct dev_pm_qos_request *req_min;
+ struct dev_pm_qos_request *req_max;
+ int ret;
+
+ if (!device_is_registered(dev))
+ return -EINVAL;
+
+ req_min = kzalloc(sizeof(*req_min), GFP_KERNEL);
+ if (!req_min)
+ return -ENOMEM;
+
+ req_max = kzalloc(sizeof(*req_max), GFP_KERNEL);
+ if (!req_max) {
+ kfree(req_min);
+ return -ENOMEM;
+ }
+
+ ret = dev_pm_qos_add_request(dev, req_min, DEV_PM_QOS_MIN_PERF,
+ PM_QOS_MIN_PERF_DEFAULT_VALUE);
+ if (ret < 0) {
+ kfree(req_min);
+ kfree(req_max);
+ return ret;
+ }
+
+ ret = dev_pm_qos_add_request(dev, req_max, DEV_PM_QOS_MAX_PERF,
+ PM_QOS_MAX_PERF_DEFAULT_VALUE);
+ if (ret < 0) {
+ dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_MIN_PERF);
+ return ret;
+ }
+
+ mutex_lock(&dev_pm_qos_sysfs_mtx);
+
+ mutex_lock(&dev_pm_qos_mtx);
+
+ if (IS_ERR_OR_NULL(dev->power.qos))
+ ret = -ENODEV;
+ else if (dev->power.qos->perf_min_req || dev->power.qos->perf_max_req)
+ ret = -EEXIST;
+
+ if (ret < 0) {
+ __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_MIN_PERF);
+ __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_MAX_PERF);
+ mutex_unlock(&dev_pm_qos_mtx);
+ goto out;
+ }
+
+ dev->power.qos->perf_min_req = req_min;
+ dev->power.qos->perf_max_req = req_max;
+
+ mutex_unlock(&dev_pm_qos_mtx);
+
+ ret = pm_qos_sysfs_add_perf_limit(dev);
+ if (ret) {
+ dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_MIN_PERF);
+ dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_MAX_PERF);
+ }
+out:
+ mutex_unlock(&dev_pm_qos_sysfs_mtx);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(dev_pm_qos_expose_perf_limit);
+
+void dev_pm_qos_hide_perf_limit(struct device *dev)
+{
+ mutex_lock(&dev_pm_qos_sysfs_mtx);
+
+ pm_qos_sysfs_remove_perf_limit(dev);
+
+ mutex_lock(&dev_pm_qos_mtx);
+
+ __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_MIN_PERF);
+ __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_MAX_PERF);
+
+ mutex_unlock(&dev_pm_qos_mtx);
+
+ mutex_unlock(&dev_pm_qos_sysfs_mtx);
+}
+EXPORT_SYMBOL_GPL(dev_pm_qos_hide_perf_limit);
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c
index a1474fb67db9..5a45191006c1 100644
--- a/drivers/base/power/sysfs.c
+++ b/drivers/base/power/sysfs.c
@@ -317,6 +317,76 @@ static ssize_t pm_qos_no_power_off_store(struct device *dev,
static DEVICE_ATTR_RW(pm_qos_no_power_off);
+
+static ssize_t pm_qos_perf_limit_min_max_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf, bool max)
+{
+ s32 value = dev_pm_qos_read_value(dev, max ? DEV_PM_QOS_MAX_PERF :
+ DEV_PM_QOS_MIN_PERF);
+
+ return sysfs_emit(buf, "%d\n", value);
+}
+
+static ssize_t pm_qos_perf_limit_min_max_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t n, bool max)
+{
+ int ret;
+ s32 min_value = dev_pm_qos_read_value(dev, DEV_PM_QOS_MIN_PERF);
+ s32 max_value = dev_pm_qos_read_value(dev, DEV_PM_QOS_MAX_PERF);
+ s32 new_value;
+
+ if (kstrtoint(buf, 0, &new_value))
+ return -EINVAL;
+
+ if (new_value < PM_QOS_MIN_PERF_DEFAULT_VALUE ||
+ new_value > PM_QOS_MAX_PERF_DEFAULT_VALUE)
+ return -EINVAL;
+
+ if (max && (new_value < min_value))
+ return -EINVAL;
+
+ if (!max && (new_value > max_value))
+ return -EINVAL;
+
+ ret = dev_pm_qos_update_request(max ? dev->power.qos->perf_max_req :
+ dev->power.qos->perf_min_req, new_value);
+
+ return ret < 0 ? ret : n;
+}
+
+static ssize_t pm_qos_perf_limit_min_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return pm_qos_perf_limit_min_max_show(dev, attr, buf, false);
+}
+
+static ssize_t pm_qos_perf_limit_min_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t n)
+{
+ return pm_qos_perf_limit_min_max_store(dev, attr, buf, n, false);
+}
+
+static ssize_t pm_qos_perf_limit_max_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return pm_qos_perf_limit_min_max_show(dev, attr, buf, true);
+}
+
+static ssize_t pm_qos_perf_limit_max_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t n)
+{
+ return pm_qos_perf_limit_min_max_store(dev, attr, buf, n, true);
+}
+
+static DEVICE_ATTR_RW(pm_qos_perf_limit_min);
+static DEVICE_ATTR_RW(pm_qos_perf_limit_max);
+
#ifdef CONFIG_PM_SLEEP
static const char _enabled[] = "enabled";
static const char _disabled[] = "disabled";
@@ -686,6 +756,17 @@ static struct attribute *pm_qos_flags_attrs[] = {
&dev_attr_pm_qos_no_power_off.attr,
NULL,
};
+
+static struct attribute *pm_qos_perf_limit_attrs[] = {
+ &dev_attr_pm_qos_perf_limit_min.attr,
+ &dev_attr_pm_qos_perf_limit_max.attr,
+ NULL,
+};
+static const struct attribute_group pm_qos_perf_limit_attr_group = {
+ .name = power_group_name,
+ .attrs = pm_qos_perf_limit_attrs,
+};
+
static const struct attribute_group pm_qos_flags_attr_group = {
.name = power_group_name,
.attrs = pm_qos_flags_attrs,
@@ -821,6 +902,17 @@ void pm_qos_sysfs_remove_latency_tolerance(struct device *dev)
sysfs_unmerge_group(&dev->kobj, &pm_qos_latency_tolerance_attr_group);
}
+int pm_qos_sysfs_add_perf_limit(struct device *dev)
+{
+ return sysfs_merge_group(&dev->kobj,
+ &pm_qos_perf_limit_attr_group);
+}
+
+void pm_qos_sysfs_remove_perf_limit(struct device *dev)
+{
+ sysfs_unmerge_group(&dev->kobj, &pm_qos_perf_limit_attr_group);
+}
+
void rpm_sysfs_remove(struct device *dev)
{
sysfs_unmerge_group(&dev->kobj, &pm_runtime_attr_group);
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 7e2d66c37535..21baf28d750c 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -83,6 +83,8 @@ struct cpufreq_policy {
struct interval_constraints constraints;
struct interval_qos_request *min_freq_req;
struct interval_qos_request *max_freq_req;
+ struct interval_qos_request *min_perf_req;
+ struct interval_qos_request *max_perf_req;
struct cpufreq_frequency_table *freq_table;
enum cpufreq_table_sorting freq_table_sorted;
diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h
index a662ac918e3e..8c5b84b640f5 100644
--- a/include/linux/pm_qos.h
+++ b/include/linux/pm_qos.h
@@ -34,6 +34,8 @@ enum pm_qos_flags_status {
#define PM_QOS_LATENCY_TOLERANCE_DEFAULT_VALUE 0
#define PM_QOS_MIN_FREQUENCY_DEFAULT_VALUE 0
#define PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE FREQ_QOS_MAX_DEFAULT_VALUE
+#define PM_QOS_MIN_PERF_DEFAULT_VALUE 0
+#define PM_QOS_MAX_PERF_DEFAULT_VALUE 1024
#define PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT (-1)
#define PM_QOS_FLAG_NO_POWER_OFF (1 << 0)
@@ -102,6 +104,8 @@ enum dev_pm_qos_req_type {
DEV_PM_QOS_LATENCY_TOLERANCE,
DEV_PM_QOS_MIN_FREQUENCY,
DEV_PM_QOS_MAX_FREQUENCY,
+ DEV_PM_QOS_MIN_PERF,
+ DEV_PM_QOS_MAX_PERF,
DEV_PM_QOS_FLAGS,
};
@@ -111,6 +115,7 @@ struct dev_pm_qos_request {
struct plist_node pnode;
struct pm_qos_flags_request flr;
struct interval_qos_request freq;
+ struct interval_qos_request perf;
} data;
struct device *dev;
};
@@ -119,10 +124,13 @@ struct dev_pm_qos {
struct pm_qos_constraints resume_latency;
struct pm_qos_constraints latency_tolerance;
struct interval_constraints freq;
+ struct interval_constraints perf;
struct pm_qos_flags flags;
struct dev_pm_qos_request *resume_latency_req;
struct dev_pm_qos_request *latency_tolerance_req;
struct dev_pm_qos_request *flags_req;
+ struct dev_pm_qos_request *perf_min_req;
+ struct dev_pm_qos_request *perf_max_req;
};
/* Action requested to pm_qos_update_target */
@@ -192,6 +200,8 @@ s32 dev_pm_qos_get_user_latency_tolerance(struct device *dev);
int dev_pm_qos_update_user_latency_tolerance(struct device *dev, s32 val);
int dev_pm_qos_expose_latency_tolerance(struct device *dev);
void dev_pm_qos_hide_latency_tolerance(struct device *dev);
+int dev_pm_qos_expose_perf_limit(struct device *dev);
+void dev_pm_qos_hide_perf_limit(struct device *dev);
static inline s32 dev_pm_qos_requested_resume_latency(struct device *dev)
{
@@ -228,6 +238,10 @@ static inline s32 dev_pm_qos_read_value(struct device *dev,
return PM_QOS_MIN_FREQUENCY_DEFAULT_VALUE;
case DEV_PM_QOS_MAX_FREQUENCY:
return PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE;
+ case DEV_PM_QOS_MIN_PERF:
+ return PM_QOS_MIN_PERF_DEFAULT_VALUE;
+ case DEV_PM_QOS_MAX_PERF:
+ return PM_QOS_MAX_PERF_DEFAULT_VALUE;
default:
WARN_ON(1);
return 0;
@@ -281,6 +295,10 @@ static inline int dev_pm_qos_expose_latency_tolerance(struct device *dev)
{ return 0; }
static inline void dev_pm_qos_hide_latency_tolerance(struct device *dev) {}
+static inline int dev_pm_qos_expose_perf_limit(struct device *dev)
+ { return 0; }
+void dev_pm_qos_hide_perf_limit(struct device *dev) {}
+
static inline s32 dev_pm_qos_requested_resume_latency(struct device *dev)
{
return PM_QOS_RESUME_LATENCY_NO_CONSTRAINT;
@@ -317,4 +335,28 @@ int freq_qos_remove_notifier(struct interval_constraints *qos,
enum interval_qos_req_type type,
struct notifier_block *notifier);
+static inline int perf_qos_request_active(struct interval_qos_request *req)
+{
+ return !IS_ERR_OR_NULL(req->qos);
+}
+
+s32 perf_qos_read_value(struct interval_constraints *qos,
+ enum interval_qos_req_type type);
+
+int perf_qos_apply(struct interval_qos_request *req,
+ enum pm_qos_req_action action, s32 value);
+
+int perf_qos_add_request(struct interval_constraints *qos,
+ struct interval_qos_request *req,
+ enum interval_qos_req_type type, s32 value);
+int perf_qos_update_request(struct interval_qos_request *req, s32 new_value);
+int perf_qos_remove_request(struct interval_qos_request *req);
+
+int perf_qos_add_notifier(struct interval_constraints *qos,
+ enum interval_qos_req_type type,
+ struct notifier_block *notifier);
+int perf_qos_remove_notifier(struct interval_constraints *qos,
+ enum interval_qos_req_type type,
+ struct notifier_block *notifier);
+
#endif
diff --git a/kernel/power/qos.c b/kernel/power/qos.c
index 6ff6c494f84d..736cd712839a 100644
--- a/kernel/power/qos.c
+++ b/kernel/power/qos.c
@@ -680,3 +680,228 @@ int freq_qos_remove_notifier(struct interval_constraints *qos,
return ret;
}
EXPORT_SYMBOL_GPL(freq_qos_remove_notifier);
+
+static inline bool perf_qos_value_invalid(s32 value)
+{
+ return value < 0 && value != PM_QOS_DEFAULT_VALUE;
+}
+
+/**
+ * perf_qos_apply - Add/modify/remove performance QoS request.
+ * @req: Constraint request to apply.
+ * @action: Action to perform (add/update/remove).
+ * @value: Value to assign to the QoS request.
+ *
+ * This is only meant to be called from inside pm_qos, not drivers.
+ */
+int perf_qos_apply(struct interval_qos_request *req,
+ enum pm_qos_req_action action, s32 value)
+{
+ int ret;
+
+ switch(req->type) {
+ case INTERVAL_QOS_MIN:
+ ret = pm_qos_update_target(&req->qos->min, &req->pnode,
+ action, value);
+ break;
+ case INTERVAL_QOS_MAX:
+ ret = pm_qos_update_target(&req->qos->max, &req->pnode,
+ action, value);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+/**
+ * perf_qos_read_value - Get performance QoS constraint for a given list.
+ * @qos: Constraints to evaluate.
+ * @type: QoS request type.
+ */
+s32 perf_qos_read_value(struct interval_constraints *qos,
+ enum interval_qos_req_type type)
+{
+ s32 ret;
+
+ switch (type) {
+ case INTERVAL_QOS_MIN:
+ ret = IS_ERR_OR_NULL(qos) ?
+ PM_QOS_MIN_PERF_DEFAULT_VALUE :
+ pm_qos_read_value(&qos->min);
+ break;
+ case INTERVAL_QOS_MAX:
+ ret = IS_ERR_OR_NULL(qos) ?
+ PM_QOS_MAX_PERF_DEFAULT_VALUE :
+ pm_qos_read_value(&qos->max);
+ break;
+ default:
+ ret = 0;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(perf_qos_read_value);
+
+/**
+ * perf_qos_add_request - Insert new performance QoS request into a given list.
+ * @qos: Constraints to update.
+ * @req: Preallocated request object.
+ * @type: Request type.
+ * @value: Request value.
+ *
+ * Insert a new entry into the @qos list of requests, recompute the effective
+ * QoS constraint value for that list and initialize the @req object. The
+ * caller needs to save that object for later use in updates and removal.
+ *
+ * Return 1 if the effective constraint value has changed, 0 if the effective
+ * constraint value has not changed, or a negative error code on failures.
+ */
+int perf_qos_add_request(struct interval_constraints *qos,
+ struct interval_qos_request *req,
+ enum interval_qos_req_type type, s32 value)
+{
+ int ret;
+
+ if (IS_ERR_OR_NULL(qos) || !req || perf_qos_value_invalid(value))
+ return -EINVAL;
+
+ if (WARN(perf_qos_request_active(req),
+ "%s() called for active request\n", __func__))
+ return -EINVAL;
+
+ req->qos = qos;
+ req->type = type;
+ ret = perf_qos_apply(req, PM_QOS_ADD_REQ, value);
+ if (ret < 0) {
+ req->qos = NULL;
+ req->type = 0;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(perf_qos_add_request);
+
+/**
+ * perf_qos_update_request - Modify existing performance QoS request.
+ * @req: Request to modify.
+ * @new_value: New request value.
+ *
+ * Update an existing performance QoS request along with the effective
+ * constraint value for the list of requests it belongs to.
+ *
+ * Return 1 if the effective constraint value has changed, 0 if the effective
+ * constraint value has not changed, or a negative error code on failures.
+ */
+int perf_qos_update_request(struct interval_qos_request *req, s32 new_value)
+{
+ if (!req || perf_qos_value_invalid(new_value))
+ return -EINVAL;
+
+ if (WARN(!perf_qos_request_active(req),
+ "%s() called for unknown object\n", __func__))
+ return -EINVAL;
+
+ if (req->pnode.prio == new_value)
+ return 0;
+
+ return perf_qos_apply(req, PM_QOS_UPDATE_REQ, new_value);
+}
+EXPORT_SYMBOL_GPL(perf_qos_update_request);
+
+/**
+ * perf_qos_remove_request - Remove performance QoS request from its list.
+ * @req: Request to remove.
+ *
+ * Remove the given performance QoS request from the list of
+ * constraints it belongs to and recompute the effective constraint
+ * value for that list.
+ *
+ * Return 1 if the effective constraint value has changed, 0 if the effective
+ * constraint value has not changed, or a negative error code on failures.
+ */
+int perf_qos_remove_request(struct interval_qos_request *req)
+{
+ int ret;
+
+ if (!req)
+ return -EINVAL;
+
+ if (WARN(!perf_qos_request_active(req),
+ "%s() called for unknown object\n", __func__))
+ return -EINVAL;
+
+ ret = perf_qos_apply(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE);
+ req->qos = NULL;
+ req->type = 0;
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(perf_qos_remove_request);
+
+/**
+ * perf_qos_add_notifier - Add performance QoS change notifier.
+ * @qos: List of requests to add the notifier to.
+ * @type: Request type.
+ * @notifier: Notifier block to add.
+ */
+int perf_qos_add_notifier(struct interval_constraints *qos,
+ enum interval_qos_req_type type,
+ struct notifier_block *notifier)
+{
+ int ret;
+
+ if (IS_ERR_OR_NULL(qos) || !notifier)
+ return -EINVAL;
+
+ switch (type) {
+ case INTERVAL_QOS_MIN:
+ ret = blocking_notifier_chain_register(qos->min.notifiers,
+ notifier);
+ break;
+ case INTERVAL_QOS_MAX:
+ ret = blocking_notifier_chain_register(qos->max.notifiers,
+ notifier);
+ break;
+ default:
+ WARN_ON(1);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(perf_qos_add_notifier);
+
+/**
+ * perf_qos_remove_notifier - Remove performance QoS change notifier.
+ * @qos: List of requests to remove the notifier from.
+ * @type: Request type.
+ * @notifier: Notifier block to remove.
+ */
+int perf_qos_remove_notifier(struct interval_constraints *qos,
+ enum interval_qos_req_type type,
+ struct notifier_block *notifier)
+{
+ int ret;
+
+ if (IS_ERR_OR_NULL(qos) || !notifier)
+ return -EINVAL;
+
+ switch (type) {
+ case INTERVAL_QOS_MIN:
+ ret = blocking_notifier_chain_unregister(qos->min.notifiers,
+ notifier);
+ break;
+ case INTERVAL_QOS_MAX:
+ ret = blocking_notifier_chain_unregister(qos->max.notifiers,
+ notifier);
+ break;
+ default:
+ WARN_ON(1);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(perf_qos_remove_notifier);
--
2.34.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [RFC PATCH 2/2] PM: QoS: Add a performance QoS
2023-12-01 19:07 ` [RFC PATCH 2/2] PM: QoS: Add a performance QoS Daniel Lezcano
@ 2023-12-05 12:29 ` kernel test robot
2023-12-05 12:40 ` kernel test robot
1 sibling, 0 replies; 6+ messages in thread
From: kernel test robot @ 2023-12-05 12:29 UTC (permalink / raw)
To: Daniel Lezcano; +Cc: oe-kbuild-all
Hi Daniel,
[This is a private test report for your RFC patch.]
kernel test robot noticed the following build errors:
[auto build test ERROR on rafael-pm/linux-next]
[also build test ERROR on rafael-pm/acpi-bus rafael-pm/thermal linus/master rafael-pm/devprop v6.7-rc4 next-20231205]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Daniel-Lezcano/PM-QoS-Add-a-performance-QoS/20231202-031119
base: https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git linux-next
patch link: https://lore.kernel.org/r/20231201190757.144741-2-daniel.lezcano%40linaro.org
patch subject: [RFC PATCH 2/2] PM: QoS: Add a performance QoS
config: parisc-randconfig-001-20231203 (https://download.01.org/0day-ci/archive/20231205/202312052019.Vy6Upt3W-lkp@intel.com/config)
compiler: hppa-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231205/202312052019.Vy6Upt3W-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202312052019.Vy6Upt3W-lkp@intel.com/
All errors (new ones prefixed by >>):
hppa-linux-ld: drivers/ufs/core/ufs-sysfs.o: in function `dev_pm_qos_hide_perf_limit':
>> (.text.dev_pm_qos_hide_perf_limit+0x0): multiple definition of `dev_pm_qos_hide_perf_limit'; drivers/ufs/core/ufshcd.o:(.text.dev_pm_qos_hide_perf_limit+0x0): first defined here
hppa-linux-ld: drivers/ufs/core/ufs-mcq.o: in function `dev_pm_qos_hide_perf_limit':
>> (.text.dev_pm_qos_hide_perf_limit+0x0): multiple definition of `dev_pm_qos_hide_perf_limit'; drivers/ufs/core/ufshcd.o:(.text.dev_pm_qos_hide_perf_limit+0x0): first defined here
hppa-linux-ld: drivers/ufs/core/ufs-debugfs.o: in function `dev_pm_qos_hide_perf_limit':
>> (.text.dev_pm_qos_hide_perf_limit+0x0): multiple definition of `dev_pm_qos_hide_perf_limit'; drivers/ufs/core/ufshcd.o:(.text.dev_pm_qos_hide_perf_limit+0x0): first defined here
hppa-linux-ld: drivers/ufs/core/ufs_bsg.o: in function `dev_pm_qos_hide_perf_limit':
>> (.text.dev_pm_qos_hide_perf_limit+0x0): multiple definition of `dev_pm_qos_hide_perf_limit'; drivers/ufs/core/ufshcd.o:(.text.dev_pm_qos_hide_perf_limit+0x0): first defined here
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RFC PATCH 2/2] PM: QoS: Add a performance QoS
2023-12-01 19:07 ` [RFC PATCH 2/2] PM: QoS: Add a performance QoS Daniel Lezcano
2023-12-05 12:29 ` kernel test robot
@ 2023-12-05 12:40 ` kernel test robot
1 sibling, 0 replies; 6+ messages in thread
From: kernel test robot @ 2023-12-05 12:40 UTC (permalink / raw)
To: Daniel Lezcano; +Cc: oe-kbuild-all
Hi Daniel,
[This is a private test report for your RFC patch.]
kernel test robot noticed the following build errors:
[auto build test ERROR on rafael-pm/linux-next]
[also build test ERROR on rafael-pm/acpi-bus rafael-pm/thermal linus/master rafael-pm/devprop v6.7-rc4 next-20231205]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Daniel-Lezcano/PM-QoS-Add-a-performance-QoS/20231202-031119
base: https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git linux-next
patch link: https://lore.kernel.org/r/20231201190757.144741-2-daniel.lezcano%40linaro.org
patch subject: [RFC PATCH 2/2] PM: QoS: Add a performance QoS
config: powerpc-randconfig-002-20231203 (https://download.01.org/0day-ci/archive/20231205/202312052053.GM9JEd1c-lkp@intel.com/config)
compiler: powerpc-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231205/202312052053.GM9JEd1c-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202312052053.GM9JEd1c-lkp@intel.com/
All errors (new ones prefixed by >>):
powerpc-linux-ld: sound/aoa/core/alsa.o: in function `dev_pm_qos_hide_perf_limit':
>> alsa.c:(.text+0x230): multiple definition of `dev_pm_qos_hide_perf_limit'; sound/aoa/core/core.o:core.c:(.text+0x690): first defined here
powerpc-linux-ld: sound/aoa/core/gpio-pmf.o: in function `dev_pm_qos_hide_perf_limit':
gpio-pmf.c:(.text+0xef4): multiple definition of `dev_pm_qos_hide_perf_limit'; sound/aoa/core/core.o:core.c:(.text+0x690): first defined here
powerpc-linux-ld: sound/aoa/core/gpio-feature.o: in function `dev_pm_qos_hide_perf_limit':
gpio-feature.c:(.text+0x1ad0): multiple definition of `dev_pm_qos_hide_perf_limit'; sound/aoa/core/core.o:core.c:(.text+0x690): first defined here
--
powerpc-linux-ld: sound/aoa/soundbus/sysfs.o: in function `dev_pm_qos_hide_perf_limit':
>> sysfs.c:(.text+0x170): multiple definition of `dev_pm_qos_hide_perf_limit'; sound/aoa/soundbus/core.o:core.c:(.text+0x6d0): first defined here
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RFC PATCH 1/2] pm_qos: Rename freq to interval constraint
2023-12-01 19:07 [RFC PATCH 1/2] pm_qos: Rename freq to interval constraint Daniel Lezcano
2023-12-01 19:07 ` [RFC PATCH 2/2] PM: QoS: Add a performance QoS Daniel Lezcano
@ 2023-12-05 14:26 ` kernel test robot
2023-12-08 20:42 ` Rafael J. Wysocki
2 siblings, 0 replies; 6+ messages in thread
From: kernel test robot @ 2023-12-05 14:26 UTC (permalink / raw)
To: Daniel Lezcano; +Cc: oe-kbuild-all
Hi Daniel,
[This is a private test report for your RFC patch.]
kernel test robot noticed the following build errors:
[auto build test ERROR on rafael-pm/linux-next]
[also build test ERROR on rafael-pm/acpi-bus rafael-pm/thermal linus/master rafael-pm/devprop v6.7-rc4 next-20231205]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Daniel-Lezcano/PM-QoS-Add-a-performance-QoS/20231202-031119
base: https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git linux-next
patch link: https://lore.kernel.org/r/20231201190757.144741-1-daniel.lezcano%40linaro.org
patch subject: [RFC PATCH 1/2] pm_qos: Rename freq to interval constraint
config: i386-buildonly-randconfig-001-20231203 (https://download.01.org/0day-ci/archive/20231205/202312052205.smINapGy-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231205/202312052205.smINapGy-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202312052205.smINapGy-lkp@intel.com/
All errors (new ones prefixed by >>):
In file included from drivers/cpufreq/intel_pstate.c:45:
include/acpi/processor.h:240:33: error: field 'perflib_req' has incomplete type
240 | struct freq_qos_request perflib_req;
| ^~~~~~~~~~~
include/acpi/processor.h:241:33: error: field 'thermal_req' has incomplete type
241 | struct freq_qos_request thermal_req;
| ^~~~~~~~~~~
drivers/cpufreq/intel_pstate.c:1323:37: warning: 'enum freq_qos_req_type' declared inside parameter list will not be visible outside of this definition or declaration
1323 | static void update_qos_request(enum freq_qos_req_type type)
| ^~~~~~~~~~~~~~~~~
drivers/cpufreq/intel_pstate.c:1323:55: error: parameter 1 ('type') has incomplete type
1323 | static void update_qos_request(enum freq_qos_req_type type)
| ~~~~~~~~~~~~~~~~~~~~~~~^~~~
drivers/cpufreq/intel_pstate.c:1323:13: error: function declaration isn't a prototype [-Werror=strict-prototypes]
1323 | static void update_qos_request(enum freq_qos_req_type type)
| ^~~~~~~~~~~~~~~~~~
drivers/cpufreq/intel_pstate.c: In function 'update_qos_request':
drivers/cpufreq/intel_pstate.c:1349:28: error: increment of pointer to an incomplete type 'struct freq_qos_request'
1349 | req++;
| ^~
drivers/cpufreq/intel_pstate.c:1355:45: error: passing argument 1 of 'freq_qos_update_request' from incompatible pointer type [-Werror=incompatible-pointer-types]
1355 | if (freq_qos_update_request(req, freq) < 0)
| ^~~
| |
| struct freq_qos_request *
In file included from include/linux/cpufreq.h:19,
from drivers/cpufreq/intel_pstate.c:21:
include/linux/pm_qos.h:308:58: note: expected 'struct interval_qos_request *' but argument is of type 'struct freq_qos_request *'
308 | int freq_qos_update_request(struct interval_qos_request *req, s32 new_value);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
drivers/cpufreq/intel_pstate.c: In function 'intel_cpufreq_cpu_init':
>> drivers/cpufreq/intel_pstate.c:3004:32: error: invalid application of 'sizeof' to incomplete type 'struct freq_qos_request'
3004 | req = kcalloc(2, sizeof(*req), GFP_KERNEL);
| ^
drivers/cpufreq/intel_pstate.c:3029:58: error: passing argument 2 of 'freq_qos_add_request' from incompatible pointer type [-Werror=incompatible-pointer-types]
3029 | ret = freq_qos_add_request(&policy->constraints, req, FREQ_QOS_MIN,
| ^~~
| |
| struct freq_qos_request *
include/linux/pm_qos.h:306:55: note: expected 'struct interval_qos_request *' but argument is of type 'struct freq_qos_request *'
306 | struct interval_qos_request *req,
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
drivers/cpufreq/intel_pstate.c:3038:62: error: invalid use of undefined type 'struct freq_qos_request'
3038 | ret = freq_qos_add_request(&policy->constraints, req + 1, FREQ_QOS_MAX,
| ^
drivers/cpufreq/intel_pstate.c:3038:62: error: passing argument 2 of 'freq_qos_add_request' from incompatible pointer type [-Werror=incompatible-pointer-types]
3038 | ret = freq_qos_add_request(&policy->constraints, req + 1, FREQ_QOS_MAX,
| ~~~~^~~
| |
| struct freq_qos_request *
include/linux/pm_qos.h:306:55: note: expected 'struct interval_qos_request *' but argument is of type 'struct freq_qos_request *'
306 | struct interval_qos_request *req,
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
drivers/cpufreq/intel_pstate.c:3050:33: error: passing argument 1 of 'freq_qos_remove_request' from incompatible pointer type [-Werror=incompatible-pointer-types]
3050 | freq_qos_remove_request(req);
| ^~~
| |
| struct freq_qos_request *
include/linux/pm_qos.h:309:58: note: expected 'struct interval_qos_request *' but argument is of type 'struct freq_qos_request *'
309 | int freq_qos_remove_request(struct interval_qos_request *req);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
drivers/cpufreq/intel_pstate.c: In function 'intel_cpufreq_cpu_exit':
drivers/cpufreq/intel_pstate.c:3065:37: error: invalid use of undefined type 'struct freq_qos_request'
3065 | freq_qos_remove_request(req + 1);
| ^
drivers/cpufreq/intel_pstate.c:3065:37: error: passing argument 1 of 'freq_qos_remove_request' from incompatible pointer type [-Werror=incompatible-pointer-types]
3065 | freq_qos_remove_request(req + 1);
| ~~~~^~~
| |
| struct freq_qos_request *
include/linux/pm_qos.h:309:58: note: expected 'struct interval_qos_request *' but argument is of type 'struct freq_qos_request *'
309 | int freq_qos_remove_request(struct interval_qos_request *req);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
drivers/cpufreq/intel_pstate.c:3066:33: error: passing argument 1 of 'freq_qos_remove_request' from incompatible pointer type [-Werror=incompatible-pointer-types]
3066 | freq_qos_remove_request(req);
| ^~~
| |
| struct freq_qos_request *
include/linux/pm_qos.h:309:58: note: expected 'struct interval_qos_request *' but argument is of type 'struct freq_qos_request *'
309 | int freq_qos_remove_request(struct interval_qos_request *req);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
cc1: some warnings being treated as errors
vim +3004 drivers/cpufreq/intel_pstate.c
a365ab6b9dfbaf8 Rafael J. Wysocki 2020-12-14 2984
001c76f05b01cc8 Rafael J. Wysocki 2016-11-17 2985 static int intel_cpufreq_cpu_init(struct cpufreq_policy *policy)
001c76f05b01cc8 Rafael J. Wysocki 2016-11-17 2986 {
3000ce3c52f8b8d Rafael J. Wysocki 2019-10-16 2987 struct freq_qos_request *req;
da5c504c7aae96d Viresh Kumar 2019-08-09 2988 struct cpudata *cpu;
da5c504c7aae96d Viresh Kumar 2019-08-09 2989 struct device *dev;
de5bcf404acee62 Rafael J. Wysocki 2021-03-16 2990 int ret, freq;
da5c504c7aae96d Viresh Kumar 2019-08-09 2991
da5c504c7aae96d Viresh Kumar 2019-08-09 2992 dev = get_cpu_device(policy->cpu);
da5c504c7aae96d Viresh Kumar 2019-08-09 2993 if (!dev)
da5c504c7aae96d Viresh Kumar 2019-08-09 2994 return -ENODEV;
001c76f05b01cc8 Rafael J. Wysocki 2016-11-17 2995
da5c504c7aae96d Viresh Kumar 2019-08-09 2996 ret = __intel_pstate_cpu_init(policy);
001c76f05b01cc8 Rafael J. Wysocki 2016-11-17 2997 if (ret)
001c76f05b01cc8 Rafael J. Wysocki 2016-11-17 2998 return ret;
001c76f05b01cc8 Rafael J. Wysocki 2016-11-17 2999
001c76f05b01cc8 Rafael J. Wysocki 2016-11-17 3000 policy->cpuinfo.transition_latency = INTEL_CPUFREQ_TRANSITION_LATENCY;
001c76f05b01cc8 Rafael J. Wysocki 2016-11-17 3001 /* This reflects the intel_pstate_get_cpu_pstates() setting. */
001c76f05b01cc8 Rafael J. Wysocki 2016-11-17 3002 policy->cur = policy->cpuinfo.min_freq;
001c76f05b01cc8 Rafael J. Wysocki 2016-11-17 3003
da5c504c7aae96d Viresh Kumar 2019-08-09 @3004 req = kcalloc(2, sizeof(*req), GFP_KERNEL);
da5c504c7aae96d Viresh Kumar 2019-08-09 3005 if (!req) {
da5c504c7aae96d Viresh Kumar 2019-08-09 3006 ret = -ENOMEM;
da5c504c7aae96d Viresh Kumar 2019-08-09 3007 goto pstate_exit;
da5c504c7aae96d Viresh Kumar 2019-08-09 3008 }
da5c504c7aae96d Viresh Kumar 2019-08-09 3009
da5c504c7aae96d Viresh Kumar 2019-08-09 3010 cpu = all_cpu_data[policy->cpu];
da5c504c7aae96d Viresh Kumar 2019-08-09 3011
f6ebbcf08f37b01 Rafael J. Wysocki 2020-08-06 3012 if (hwp_active) {
f6ebbcf08f37b01 Rafael J. Wysocki 2020-08-06 3013 u64 value;
f6ebbcf08f37b01 Rafael J. Wysocki 2020-08-06 3014
f6ebbcf08f37b01 Rafael J. Wysocki 2020-08-06 3015 policy->transition_delay_us = INTEL_CPUFREQ_TRANSITION_DELAY_HWP;
de5bcf404acee62 Rafael J. Wysocki 2021-03-16 3016
de5bcf404acee62 Rafael J. Wysocki 2021-03-16 3017 intel_pstate_get_hwp_cap(cpu);
de5bcf404acee62 Rafael J. Wysocki 2021-03-16 3018
f6ebbcf08f37b01 Rafael J. Wysocki 2020-08-06 3019 rdmsrl_on_cpu(cpu->cpu, MSR_HWP_REQUEST, &value);
f6ebbcf08f37b01 Rafael J. Wysocki 2020-08-06 3020 WRITE_ONCE(cpu->hwp_req_cached, value);
de5bcf404acee62 Rafael J. Wysocki 2021-03-16 3021
c27a0ccc3c715c5 Rafael J. Wysocki 2020-08-27 3022 cpu->epp_cached = intel_pstate_get_epp(cpu, value);
f6ebbcf08f37b01 Rafael J. Wysocki 2020-08-06 3023 } else {
f6ebbcf08f37b01 Rafael J. Wysocki 2020-08-06 3024 policy->transition_delay_us = INTEL_CPUFREQ_TRANSITION_DELAY;
f6ebbcf08f37b01 Rafael J. Wysocki 2020-08-06 3025 }
da5c504c7aae96d Viresh Kumar 2019-08-09 3026
de5bcf404acee62 Rafael J. Wysocki 2021-03-16 3027 freq = DIV_ROUND_UP(cpu->pstate.turbo_freq * global.min_perf_pct, 100);
da5c504c7aae96d Viresh Kumar 2019-08-09 3028
3000ce3c52f8b8d Rafael J. Wysocki 2019-10-16 3029 ret = freq_qos_add_request(&policy->constraints, req, FREQ_QOS_MIN,
de5bcf404acee62 Rafael J. Wysocki 2021-03-16 3030 freq);
da5c504c7aae96d Viresh Kumar 2019-08-09 3031 if (ret < 0) {
da5c504c7aae96d Viresh Kumar 2019-08-09 3032 dev_err(dev, "Failed to add min-freq constraint (%d)\n", ret);
da5c504c7aae96d Viresh Kumar 2019-08-09 3033 goto free_req;
da5c504c7aae96d Viresh Kumar 2019-08-09 3034 }
da5c504c7aae96d Viresh Kumar 2019-08-09 3035
de5bcf404acee62 Rafael J. Wysocki 2021-03-16 3036 freq = DIV_ROUND_UP(cpu->pstate.turbo_freq * global.max_perf_pct, 100);
de5bcf404acee62 Rafael J. Wysocki 2021-03-16 3037
3000ce3c52f8b8d Rafael J. Wysocki 2019-10-16 3038 ret = freq_qos_add_request(&policy->constraints, req + 1, FREQ_QOS_MAX,
de5bcf404acee62 Rafael J. Wysocki 2021-03-16 3039 freq);
da5c504c7aae96d Viresh Kumar 2019-08-09 3040 if (ret < 0) {
da5c504c7aae96d Viresh Kumar 2019-08-09 3041 dev_err(dev, "Failed to add max-freq constraint (%d)\n", ret);
da5c504c7aae96d Viresh Kumar 2019-08-09 3042 goto remove_min_req;
da5c504c7aae96d Viresh Kumar 2019-08-09 3043 }
da5c504c7aae96d Viresh Kumar 2019-08-09 3044
da5c504c7aae96d Viresh Kumar 2019-08-09 3045 policy->driver_data = req;
da5c504c7aae96d Viresh Kumar 2019-08-09 3046
001c76f05b01cc8 Rafael J. Wysocki 2016-11-17 3047 return 0;
da5c504c7aae96d Viresh Kumar 2019-08-09 3048
da5c504c7aae96d Viresh Kumar 2019-08-09 3049 remove_min_req:
3000ce3c52f8b8d Rafael J. Wysocki 2019-10-16 3050 freq_qos_remove_request(req);
da5c504c7aae96d Viresh Kumar 2019-08-09 3051 free_req:
da5c504c7aae96d Viresh Kumar 2019-08-09 3052 kfree(req);
da5c504c7aae96d Viresh Kumar 2019-08-09 3053 pstate_exit:
da5c504c7aae96d Viresh Kumar 2019-08-09 3054 intel_pstate_exit_perf_limits(policy);
da5c504c7aae96d Viresh Kumar 2019-08-09 3055
da5c504c7aae96d Viresh Kumar 2019-08-09 3056 return ret;
da5c504c7aae96d Viresh Kumar 2019-08-09 3057 }
da5c504c7aae96d Viresh Kumar 2019-08-09 3058
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RFC PATCH 1/2] pm_qos: Rename freq to interval constraint
2023-12-01 19:07 [RFC PATCH 1/2] pm_qos: Rename freq to interval constraint Daniel Lezcano
2023-12-01 19:07 ` [RFC PATCH 2/2] PM: QoS: Add a performance QoS Daniel Lezcano
2023-12-05 14:26 ` [RFC PATCH 1/2] pm_qos: Rename freq to interval constraint kernel test robot
@ 2023-12-08 20:42 ` Rafael J. Wysocki
2 siblings, 0 replies; 6+ messages in thread
From: Rafael J. Wysocki @ 2023-12-08 20:42 UTC (permalink / raw)
To: Daniel Lezcano
Cc: rjw, caleb.connolly, lina.iyer, linux-pm, mani, linux-kernel,
lukasz.luba
On Fri, Dec 1, 2023 at 8:08 PM Daniel Lezcano <daniel.lezcano@linaro.org> wrote:
>
> The frequency pm_qos relies on a couple of values, the min and max
> frequencies. However more pm_qos will be added with the same logic of
> a couple of min and max. Instead of writing new set of constraints as
> well as type, etc... let's rename freq_* to a more generic name
> interval_*
I'm fine with a rename if it helps, but I would rather call it range_*
than interval_*.
>
> That way, new qos interval based can be added easily.
>
> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> ---
> drivers/base/power/qos.c | 4 +--
> drivers/powercap/dtpm_cpu.c | 2 +-
> drivers/thermal/cpufreq_cooling.c | 2 +-
> include/linux/cpufreq.h | 6 ++--
> include/linux/pm_qos.h | 55 ++++++++++++++++---------------
> kernel/power/qos.c | 53 +++++++++++++++--------------
> 6 files changed, 61 insertions(+), 61 deletions(-)
>
> diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c
> index 8e93167f1783..561d2a0e106c 100644
> --- a/drivers/base/power/qos.c
> +++ b/drivers/base/power/qos.c
> @@ -285,14 +285,14 @@ void dev_pm_qos_constraints_destroy(struct device *dev)
> memset(req, 0, sizeof(*req));
> }
>
> - c = &qos->freq.min_freq;
> + c = &qos->freq.min;
> plist_for_each_entry_safe(req, tmp, &c->list, data.freq.pnode) {
> apply_constraint(req, PM_QOS_REMOVE_REQ,
> PM_QOS_MIN_FREQUENCY_DEFAULT_VALUE);
> memset(req, 0, sizeof(*req));
> }
>
> - c = &qos->freq.max_freq;
> + c = &qos->freq.max;
> plist_for_each_entry_safe(req, tmp, &c->list, data.freq.pnode) {
> apply_constraint(req, PM_QOS_REMOVE_REQ,
> PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE);
> diff --git a/drivers/powercap/dtpm_cpu.c b/drivers/powercap/dtpm_cpu.c
> index 2ff7717530bf..6587c94d0127 100644
> --- a/drivers/powercap/dtpm_cpu.c
> +++ b/drivers/powercap/dtpm_cpu.c
> @@ -28,7 +28,7 @@
>
> struct dtpm_cpu {
> struct dtpm dtpm;
> - struct freq_qos_request qos_req;
> + struct interval_qos_request qos_req;
> int cpu;
> };
>
> diff --git a/drivers/thermal/cpufreq_cooling.c b/drivers/thermal/cpufreq_cooling.c
> index e2cc7bd30862..72e9f0cde55c 100644
> --- a/drivers/thermal/cpufreq_cooling.c
> +++ b/drivers/thermal/cpufreq_cooling.c
> @@ -77,7 +77,7 @@ struct cpufreq_cooling_device {
> #ifndef CONFIG_SMP
> struct time_in_idle *idle_time;
> #endif
> - struct freq_qos_request qos_req;
> + struct interval_qos_request qos_req;
> };
>
> #ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
> diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
> index 71d186d6933a..7e2d66c37535 100644
> --- a/include/linux/cpufreq.h
> +++ b/include/linux/cpufreq.h
> @@ -80,9 +80,9 @@ struct cpufreq_policy {
> struct work_struct update; /* if update_policy() needs to be
> * called, but you're in IRQ context */
>
> - struct freq_constraints constraints;
> - struct freq_qos_request *min_freq_req;
> - struct freq_qos_request *max_freq_req;
> + struct interval_constraints constraints;
> + struct interval_qos_request *min_freq_req;
> + struct interval_qos_request *max_freq_req;
>
> struct cpufreq_frequency_table *freq_table;
> enum cpufreq_table_sorting freq_table_sorted;
> diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h
> index 4a69d4af3ff8..a662ac918e3e 100644
> --- a/include/linux/pm_qos.h
> +++ b/include/linux/pm_qos.h
> @@ -77,25 +77,26 @@ struct pm_qos_flags {
> #define FREQ_QOS_MIN_DEFAULT_VALUE 0
> #define FREQ_QOS_MAX_DEFAULT_VALUE S32_MAX
>
> -enum freq_qos_req_type {
> - FREQ_QOS_MIN = 1,
> +enum interval_qos_req_type {
> + INTERVAL_QOS_MIN = 1,
> + INTERVAL_QOS_MAX,
> + FREQ_QOS_MIN,
> FREQ_QOS_MAX,
> };
>
> -struct freq_constraints {
> - struct pm_qos_constraints min_freq;
> - struct blocking_notifier_head min_freq_notifiers;
> - struct pm_qos_constraints max_freq;
> - struct blocking_notifier_head max_freq_notifiers;
> +struct interval_constraints {
> + struct pm_qos_constraints min;
> + struct blocking_notifier_head min_notifiers;
> + struct pm_qos_constraints max;
> + struct blocking_notifier_head max_notifiers;
> };
Also I would rename min_freq and max_freq to lower_bound and
upper_bound, respectively, because this is less likely to get confused
with other things with the same name.
So the above would be
+struct range_constraints {
+ struct pm_qos_constraints lower_bound;
+ struct blocking_notifier_head lower_bound_notifiers;
+ struct pm_qos_constraints upper_bound;
+ struct blocking_notifier_head upper_bound_notifiers;
};
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2023-12-08 20:42 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-12-01 19:07 [RFC PATCH 1/2] pm_qos: Rename freq to interval constraint Daniel Lezcano
2023-12-01 19:07 ` [RFC PATCH 2/2] PM: QoS: Add a performance QoS Daniel Lezcano
2023-12-05 12:29 ` kernel test robot
2023-12-05 12:40 ` kernel test robot
2023-12-05 14:26 ` [RFC PATCH 1/2] pm_qos: Rename freq to interval constraint kernel test robot
2023-12-08 20:42 ` Rafael J. Wysocki
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.