* [PATCH v2 6/8] input: CPU frequency booster
From: Antti P Miettinen @ 2012-01-16 6:59 UTC (permalink / raw)
To: linux-pm
In-Reply-To: <1326697201-32406-1-git-send-email-amiettinen@nvidia.com>
Inspired by cpufreq ondemand governor changes at
git://codeaurora.org/kernel/msm.git tree in commits:
2a6181bc76c6ce46ca0fa8e547be42acd534cf0e
1cca8861d8fda4e05f6b0c59c60003345c15454d
96a9aeb02bf5b3fbbef47e44460750eb275e9f1b
b600449501cf15928440f87eff86b1f32d14214e
88a65c7ae04632ffee11f9fc628d7ab017c06b83
Signed-off-by: Antti P Miettinen <amiettinen@nvidia.com>
---
drivers/input/Kconfig | 9 ++
drivers/input/Makefile | 1 +
drivers/input/input-cfboost.c | 174 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 184 insertions(+), 0 deletions(-)
create mode 100644 drivers/input/input-cfboost.c
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
index 001b147..3859f78 100644
--- a/drivers/input/Kconfig
+++ b/drivers/input/Kconfig
@@ -161,6 +161,15 @@ config INPUT_APMPOWER
To compile this driver as a module, choose M here: the
module will be called apm-power.
+config INPUT_CFBOOST
+ tristate "CPU frequency booster"
+ depends on INPUT && CPU_FREQ
+ help
+ Say Y here if you want to boost frequency upon input events;
+
+ To compile this driver as a module, choose M here: the
+ module will be called input-cfboost.
+
comment "Input Device Drivers"
source "drivers/input/keyboard/Kconfig"
diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index 0c78949..6cad177 100644
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -24,3 +24,4 @@ obj-$(CONFIG_INPUT_TOUCHSCREEN) += touchscreen/
obj-$(CONFIG_INPUT_MISC) += misc/
obj-$(CONFIG_INPUT_APMPOWER) += apm-power.o
+obj-$(CONFIG_INPUT_CFBOOST) += input-cfboost.o
diff --git a/drivers/input/input-cfboost.c b/drivers/input/input-cfboost.c
new file mode 100644
index 0000000..bef3ec5
--- /dev/null
+++ b/drivers/input/input-cfboost.c
@@ -0,0 +1,174 @@
+/*
+ * drivers/input/input-cfboost.c
+ *
+ * Copyright (C) 2012 NVIDIA Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/printk.h>
+#include <linux/workqueue.h>
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/pm_qos.h>
+
+/* This module listens to input events and sets a temporary frequency
+ * floor upon input event detection. This is based on changes to
+ * cpufreq ondemand governor by:
+ *
+ * Tero Kristo <tero.kristo@nokia.com>
+ * Brian Steuer <bsteuer@codeaurora.org>
+ * David Ng <dave@codeaurora.org>
+ *
+ * at git://codeaurora.org/kernel/msm.git tree, commits:
+ *
+ * 2a6181bc76c6ce46ca0fa8e547be42acd534cf0e
+ * 1cca8861d8fda4e05f6b0c59c60003345c15454d
+ * 96a9aeb02bf5b3fbbef47e44460750eb275e9f1b
+ * b600449501cf15928440f87eff86b1f32d14214e
+ * 88a65c7ae04632ffee11f9fc628d7ab017c06b83
+ */
+
+MODULE_AUTHOR("Antti P Miettinen <amiettinen@nvidia.com>");
+MODULE_DESCRIPTION("Input event CPU frequency booster");
+MODULE_LICENSE("GPL v2");
+
+
+static struct pm_qos_request qos_req;
+static struct work_struct boost;
+static struct delayed_work unboost;
+static unsigned int boost_freq; /* kHz */
+module_param(boost_freq, uint, 0644);
+static unsigned long boost_time = 500; /* ms */
+module_param(boost_time, ulong, 0644);
+static struct workqueue_struct *cfb_wq;
+
+static void cfb_boost(struct work_struct *w)
+{
+ cancel_delayed_work_sync(&unboost);
+ pm_qos_update_request(&qos_req, boost_freq);
+ queue_delayed_work(cfb_wq, &unboost, msecs_to_jiffies(boost_time));
+}
+
+static void cfb_unboost(struct work_struct *w)
+{
+ pm_qos_update_request(&qos_req, PM_QOS_DEFAULT_VALUE);
+}
+
+static void cfb_input_event(struct input_handle *handle, unsigned int type,
+ unsigned int code, int value)
+{
+ if (!work_pending(&boost))
+ queue_work(cfb_wq, &boost);
+}
+
+static int cfb_input_connect(struct input_handler *handler,
+ struct input_dev *dev,
+ const struct input_device_id *id)
+{
+ struct input_handle *handle;
+ int error;
+
+ handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
+ if (!handle)
+ return -ENOMEM;
+
+ handle->dev = dev;
+ handle->handler = handler;
+ handle->name = "icfboost";
+
+ error = input_register_handle(handle);
+ if (error)
+ goto err2;
+
+ error = input_open_device(handle);
+ if (error)
+ goto err1;
+
+ return 0;
+err1:
+ input_unregister_handle(handle);
+err2:
+ kfree(handle);
+ return error;
+}
+
+static void cfb_input_disconnect(struct input_handle *handle)
+{
+ input_close_device(handle);
+ input_unregister_handle(handle);
+ kfree(handle);
+}
+
+/* XXX make configurable */
+static const struct input_device_id cfb_ids[] = {
+ { /* touch screen */
+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
+ INPUT_DEVICE_ID_MATCH_KEYBIT,
+ .evbit = { BIT_MASK(EV_ABS) },
+ .keybit = {[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
+ },
+ { /* mouse */
+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
+ INPUT_DEVICE_ID_MATCH_KEYBIT,
+ .evbit = { BIT_MASK(EV_REL) },
+ .keybit = {[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_MOUSE) },
+ },
+ { },
+};
+
+static struct input_handler cfb_input_handler = {
+ .event = cfb_input_event,
+ .connect = cfb_input_connect,
+ .disconnect = cfb_input_disconnect,
+ .name = "icfboost",
+ .id_table = cfb_ids,
+};
+
+static int __init cfboost_init(void)
+{
+ int ret;
+
+ cfb_wq = create_workqueue("icfb-wq");
+ if (!cfb_wq)
+ return -ENOMEM;
+ INIT_WORK(&boost, cfb_boost);
+ INIT_DELAYED_WORK(&unboost, cfb_unboost);
+ ret = input_register_handler(&cfb_input_handler);
+ if (ret) {
+ destroy_workqueue(cfb_wq);
+ return ret;
+ }
+ pm_qos_add_request(&qos_req, PM_QOS_CPU_FREQ_MIN,
+ PM_QOS_DEFAULT_VALUE);
+ return 0;
+}
+
+static void __exit cfboost_exit(void)
+{
+ /* stop input events */
+ input_unregister_handler(&cfb_input_handler);
+ /* cancel pending work requests */
+ cancel_work_sync(&boost);
+ cancel_delayed_work_sync(&unboost);
+ /* clean up */
+ destroy_workqueue(cfb_wq);
+ pm_qos_remove_request(&qos_req);
+}
+
+module_init(cfboost_init);
+module_exit(cfboost_exit);
--
1.7.4.1
^ permalink raw reply related
* [PATCH v2 5/8] cpufreq: Enforce PM QoS minimum limit
From: Antti P Miettinen @ 2012-01-16 6:59 UTC (permalink / raw)
To: linux-pm
In-Reply-To: <1326697201-32406-1-git-send-email-amiettinen@nvidia.com>
Observe PM QoS CPU frequency minimum in addition
to policy settings.
Signed-off-by: Antti P Miettinen <amiettinen@nvidia.com>
---
drivers/cpufreq/cpufreq.c | 41 +++++++++++++++++++++++++++++++++++++++--
1 files changed, 39 insertions(+), 2 deletions(-)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 127e37a..c2c1c62 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -29,6 +29,7 @@
#include <linux/completion.h>
#include <linux/mutex.h>
#include <linux/syscore_ops.h>
+#include <linux/pm_qos.h>
#include <trace/events/power.h>
@@ -1633,9 +1634,16 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data,
struct cpufreq_policy *policy)
{
int ret = 0;
+ unsigned int pmin = policy->min;
+ unsigned int pmax = policy->max;
+ unsigned int qmin = min(pm_qos_request(PM_QOS_CPU_FREQ_MIN),
+ data->max);
- pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
- policy->min, policy->max);
+ pr_debug("setting new policy for CPU %u: %u/%u - %u kHz\n",
+ policy->cpu, pmin, qmin, pmax);
+
+ /* clamp the new policy to PM QoS limits */
+ policy->min = max(pmin, qmin);
memcpy(&policy->cpuinfo, &data->cpuinfo,
sizeof(struct cpufreq_cpuinfo));
@@ -1710,6 +1718,9 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data,
}
error_out:
+ /* restore the limits that the policy requested */
+ policy->min = pmin;
+ policy->max = pmax;
return ret;
}
@@ -1903,9 +1914,32 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver)
}
EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
+static int cpu_freq_notify(struct notifier_block *b,
+ unsigned long l, void *v);
+
+static struct notifier_block min_freq_notifier = {
+ .notifier_call = cpu_freq_notify,
+};
+
+static int cpu_freq_notify(struct notifier_block *b,
+ unsigned long l, void *v)
+{
+ int cpu;
+ pr_debug("PM QoS min %lu\n", l);
+ for_each_online_cpu(cpu) {
+ struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
+ if (policy) {
+ cpufreq_update_policy(policy->cpu);
+ cpufreq_cpu_put(policy);
+ }
+ }
+ return NOTIFY_OK;
+}
+
static int __init cpufreq_core_init(void)
{
int cpu;
+ int rc;
for_each_possible_cpu(cpu) {
per_cpu(cpufreq_policy_cpu, cpu) = -1;
@@ -1915,6 +1949,9 @@ static int __init cpufreq_core_init(void)
cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj);
BUG_ON(!cpufreq_global_kobject);
register_syscore_ops(&cpufreq_syscore_ops);
+ rc = pm_qos_add_notifier(PM_QOS_CPU_FREQ_MIN,
+ &min_freq_notifier);
+ BUG_ON(rc);
return 0;
}
--
1.7.4.1
^ permalink raw reply related
* [PATCH v2 4/8] cpufreq: Preserve sysfs min/max request
From: Antti P Miettinen @ 2012-01-16 6:59 UTC (permalink / raw)
To: linux-pm
In-Reply-To: <1326697201-32406-1-git-send-email-amiettinen@nvidia.com>
Store the value received via sysfs as the user_policy
min/max value instead of the currently enforced min/max.
This allows restoring the user min/max values when
constraints on enforced min/max change.
Signed-off-by: Antti P Miettinen <amiettinen@nvidia.com>
---
drivers/cpufreq/cpufreq.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index f115888..127e37a 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -388,7 +388,7 @@ static ssize_t store_##file_name \
return -EINVAL; \
\
ret = __cpufreq_set_policy(policy, &new_policy); \
- policy->user_policy.object = policy->object; \
+ policy->user_policy.object = new_policy.object; \
\
return ret ? ret : count; \
}
--
1.7.4.1
^ permalink raw reply related
* [PATCH v2 3/8] cpufreq: Export user_policy min/max
From: Antti P Miettinen @ 2012-01-16 6:59 UTC (permalink / raw)
To: linux-pm
In-Reply-To: <1326697201-32406-1-git-send-email-amiettinen@nvidia.com>
Add sysfs nodes for user_policy min and max settings.
Signed-off-by: Antti P Miettinen <amiettinen@nvidia.com>
---
drivers/cpufreq/cpufreq.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 622013f..f115888 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -363,6 +363,8 @@ show_one(cpuinfo_transition_latency, cpuinfo.transition_latency);
show_one(scaling_min_freq, min);
show_one(scaling_max_freq, max);
show_one(scaling_cur_freq, cur);
+show_one(policy_min_freq, user_policy.min);
+show_one(policy_max_freq, user_policy.max);
static int __cpufreq_set_policy(struct cpufreq_policy *data,
struct cpufreq_policy *policy);
@@ -581,6 +583,8 @@ cpufreq_freq_attr_rw(scaling_min_freq);
cpufreq_freq_attr_rw(scaling_max_freq);
cpufreq_freq_attr_rw(scaling_governor);
cpufreq_freq_attr_rw(scaling_setspeed);
+cpufreq_freq_attr_ro(policy_min_freq);
+cpufreq_freq_attr_ro(policy_max_freq);
static struct attribute *default_attrs[] = {
&cpuinfo_min_freq.attr,
@@ -594,6 +598,8 @@ static struct attribute *default_attrs[] = {
&scaling_driver.attr,
&scaling_available_governors.attr,
&scaling_setspeed.attr,
+ &policy_min_freq.attr,
+ &policy_max_freq.attr,
NULL
};
--
1.7.4.1
^ permalink raw reply related
* [PATCH v2 2/8] PM QoS: Add CPU frequency minimum as PM QoS param
From: Antti P Miettinen @ 2012-01-16 6:59 UTC (permalink / raw)
To: linux-pm
In-Reply-To: <1326697201-32406-1-git-send-email-amiettinen@nvidia.com>
Add minimum CPU frequency as PM QoS parameter.
Signed-off-by: Antti P Miettinen <amiettinen@nvidia.com>
---
include/linux/pm_qos.h | 3 +++
kernel/power/qos.c | 17 ++++++++++++++++-
2 files changed, 19 insertions(+), 1 deletions(-)
diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h
index 5ac91d8..54a0d00 100644
--- a/include/linux/pm_qos.h
+++ b/include/linux/pm_qos.h
@@ -14,8 +14,10 @@ enum {
PM_QOS_CPU_DMA_LATENCY,
PM_QOS_NETWORK_LATENCY,
PM_QOS_NETWORK_THROUGHPUT,
+ PM_QOS_CPU_FREQ_MIN,
/* insert new class ID */
+
PM_QOS_NUM_CLASSES,
};
@@ -25,6 +27,7 @@ enum {
#define PM_QOS_NETWORK_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC)
#define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE 0
#define PM_QOS_DEV_LAT_DEFAULT_VALUE 0
+#define PM_QOS_CPU_FREQ_MIN_DEFAULT_VALUE 0
struct pm_qos_request {
struct plist_node node;
diff --git a/kernel/power/qos.c b/kernel/power/qos.c
index d6d6dbd..07d761a 100644
--- a/kernel/power/qos.c
+++ b/kernel/power/qos.c
@@ -101,11 +101,26 @@ static struct pm_qos_object network_throughput_pm_qos = {
};
+static BLOCKING_NOTIFIER_HEAD(cpu_freq_min_notifier);
+static struct pm_qos_constraints cpu_freq_min_constraints = {
+ .list = PLIST_HEAD_INIT(cpu_freq_min_constraints.list),
+ .target_value = PM_QOS_CPU_FREQ_MIN_DEFAULT_VALUE,
+ .default_value = PM_QOS_CPU_FREQ_MIN_DEFAULT_VALUE,
+ .type = PM_QOS_MAX,
+ .notifiers = &cpu_freq_min_notifier,
+};
+static struct pm_qos_object cpu_freq_min_pm_qos = {
+ .constraints = &cpu_freq_min_constraints,
+ .name = "cpu_freq_min",
+};
+
+
static struct pm_qos_object *pm_qos_array[] = {
&null_pm_qos,
&cpu_dma_pm_qos,
&network_lat_pm_qos,
- &network_throughput_pm_qos
+ &network_throughput_pm_qos,
+ &cpu_freq_min_pm_qos,
};
static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf,
--
1.7.4.1
^ permalink raw reply related
* [PATCH v2 1/8] PM QoS: Simplify PM QoS expansion/merge
From: Antti P Miettinen @ 2012-01-16 6:59 UTC (permalink / raw)
To: linux-pm
In-Reply-To: <1326697201-32406-1-git-send-email-amiettinen@nvidia.com>
From: Alex Frid <afrid@nvidia.com>
- Replace class ID #define with enumeration
- Loop through PM QoS objects during initialization (rather than
initializing them one-by-one)
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-by: Antti Miettinen <amiettinen@nvidia.com>
Reviewed-by: Diwakar Tundlam <dtundlam@nvidia.com>
Reviewed-by: Scott Williams <scwilliams@nvidia.com>
Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>
---
include/linux/pm_qos.h | 14 +++++++++-----
kernel/power/qos.c | 23 ++++++++++-------------
2 files changed, 19 insertions(+), 18 deletions(-)
diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h
index e5bbcba..5ac91d8 100644
--- a/include/linux/pm_qos.h
+++ b/include/linux/pm_qos.h
@@ -9,12 +9,16 @@
#include <linux/miscdevice.h>
#include <linux/device.h>
-#define PM_QOS_RESERVED 0
-#define PM_QOS_CPU_DMA_LATENCY 1
-#define PM_QOS_NETWORK_LATENCY 2
-#define PM_QOS_NETWORK_THROUGHPUT 3
+enum {
+ PM_QOS_RESERVED = 0,
+ PM_QOS_CPU_DMA_LATENCY,
+ PM_QOS_NETWORK_LATENCY,
+ PM_QOS_NETWORK_THROUGHPUT,
+
+ /* insert new class ID */
+ PM_QOS_NUM_CLASSES,
+};
-#define PM_QOS_NUM_CLASSES 4
#define PM_QOS_DEFAULT_VALUE -1
#define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC)
diff --git a/kernel/power/qos.c b/kernel/power/qos.c
index 995e3bd..d6d6dbd 100644
--- a/kernel/power/qos.c
+++ b/kernel/power/qos.c
@@ -469,21 +469,18 @@ static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf,
static int __init pm_qos_power_init(void)
{
int ret = 0;
+ int i;
- ret = register_pm_qos_misc(&cpu_dma_pm_qos);
- if (ret < 0) {
- printk(KERN_ERR "pm_qos_param: cpu_dma_latency setup failed\n");
- return ret;
- }
- ret = register_pm_qos_misc(&network_lat_pm_qos);
- if (ret < 0) {
- printk(KERN_ERR "pm_qos_param: network_latency setup failed\n");
- return ret;
+ BUILD_BUG_ON(ARRAY_SIZE(pm_qos_array) != PM_QOS_NUM_CLASSES);
+
+ for (i = 1; i < PM_QOS_NUM_CLASSES; i++) {
+ ret = register_pm_qos_misc(pm_qos_array[i]);
+ if (ret < 0) {
+ printk(KERN_ERR "pm_qos_param: %s setup failed\n",
+ pm_qos_array[i]->name);
+ return ret;
+ }
}
- ret = register_pm_qos_misc(&network_throughput_pm_qos);
- if (ret < 0)
- printk(KERN_ERR
- "pm_qos_param: network_throughput setup failed\n");
return ret;
}
--
1.7.4.1
^ permalink raw reply related
* [PATCH v2 0/8] RFC: CPU frequency min/max as PM QoS params
From: Antti P Miettinen @ 2012-01-16 6:59 UTC (permalink / raw)
To: linux-pm
[did not reach linux-pm as I sent to wrong address, sorry for
duplicates]
The inspiration for this patch series is the N9 CPU frequency boost
upon input events:
http://www.spinics.net/lists/cpufreq/msg00667.html
and the related changes in git://codeaurora.org/kernel/msm.git tree.
Those patches modify the ondemand cpufreq governor. This patch series
adds minimum and maximum CPU frequency as PM QoS parameters and
modifies the cpufreq core to enforce the PM QoS limits. There is also
an example module for boosting the frequency upon input events.
I've been testing these changes against Ubuntu 3.2 kernel on a Dell
E6420 with the ACPI cpufreq driver. The patches are against
linux-next/master, compile tested against it.
V2:
* split min and max to separate commits
* handle PM QoS min above max as max
* handle PM QoS max below min as min
--Antti
Alex Frid (1):
PM QoS: Simplify PM QoS expansion/merge
Antti P Miettinen (7):
PM QoS: Add CPU frequency minimum as PM QoS param
cpufreq: Export user_policy min/max
cpufreq: Preserve sysfs min/max request
cpufreq: Enforce PM QoS minimum limit
input: CPU frequency booster
PM QoS: Add CPU frequency maximum as PM QoS param
cpufreq: Enforce PM QoS maximum frequency
drivers/cpufreq/cpufreq.c | 59 +++++++++++++-
drivers/input/Kconfig | 9 ++
drivers/input/Makefile | 1 +
drivers/input/input-cfboost.c | 174 +++++++++++++++++++++++++++++++++++++++++
include/linux/pm_qos.h | 19 ++++-
kernel/power/qos.c | 55 ++++++++++----
6 files changed, 295 insertions(+), 22 deletions(-)
create mode 100644 drivers/input/input-cfboost.c
--
1.7.4.1
^ permalink raw reply
* [PATCH] Documentation/power/basic-pm-debugging: Fix spelling mistake
From: Viresh Kumar @ 2012-01-16 3:45 UTC (permalink / raw)
To: rjw
Cc: len.brown, rdunlap, linux-pm, armando.visconti, shiraz.hashim,
vipin.kumar, rajeev-dlh.kumar, deepak.sikri, vipulkumar.samar,
amit.virdi, viresh.kumar, pratyush.anand, bhupesh.sharma,
viresh.linux, bhavna.yadav, vincenzo.frascino, mirko.gardi,
linux-doc
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
Documentation/power/basic-pm-debugging.txt | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/Documentation/power/basic-pm-debugging.txt b/Documentation/power/basic-pm-debugging.txt
index 40a4c65..262acf5 100644
--- a/Documentation/power/basic-pm-debugging.txt
+++ b/Documentation/power/basic-pm-debugging.txt
@@ -15,7 +15,7 @@ test at least a couple of times in a row for confidence. [This is necessary,
because some problems only show up on a second attempt at suspending and
resuming the system.] Moreover, hibernating in the "reboot" and "shutdown"
modes causes the PM core to skip some platform-related callbacks which on ACPI
-systems might be necessary to make hibernation work. Thus, if you machine fails
+systems might be necessary to make hibernation work. Thus, if your machine fails
to hibernate or resume in the "reboot" mode, you should try the "platform" mode:
# echo platform > /sys/power/disk
--
1.7.8.110.g4cb5d
^ permalink raw reply related
* Re: [PATCH v2 0/8] RFC: CPU frequency min/max as PM QoS params
From: Antti P Miettinen @ 2012-01-13 16:17 UTC (permalink / raw)
To: cpufreq; +Cc: linux-pm
In-Reply-To: <20120113152445.GA3005@mgross-G62>
mark gross <markgross@thegnar.org> writes:
> just a quick note: ever since I lost my mgross@linux.intel.com email
> I've started using markgross@thegnar.org
Sorry - I picked the @linux.intel.com address from git blame. Hmm.. is
the mark.gross@intelc.om in MAINTAINERS still valid?
> FWIW if this works the way I hope it does then, its a feature we need
> for different reasons than interactivity. So thanks for working on
> this!
Thanks - I appreciate the feedback!
>> V2:
>> * split min and max to separate commits
>> * handle PM QoS min above max as max
>> * handle PM QoS max below min as min
>
> A qos to constrain how slow the cpu goes is ok.
> A qos to constrain how fast it is allowed to go is not a PM_QOS thing.
Thanks - I appreciate the feedback :-)
As I said earlier, I think the maximum frequency can act as a level of
energy efficiency request. If a workload knows that a certain level of
performance is adequate, the maximum frequency request can prevent
e.g. ondemand unnecessarily raising the frequency.
--Antti
^ permalink raw reply
* Re: [PATCH] Documentation/power/freezing-of-tasks: Fix minor issue
From: Pavel Machek @ 2012-01-13 10:21 UTC (permalink / raw)
To: Viresh Kumar
Cc: rjw, len.brown, rdunlap, linux-pm, linux-doc, armando.visconti,
shiraz.hashim, vipin.kumar, rajeev-dlh.kumar, deepak.sikri,
vipulkumar.samar, amit.virdi, pratyush.anand, bhupesh.sharma,
viresh.linux, bhavna.yadav, vincenzo.frascino, mirko.gardi
In-Reply-To: <1e6f2ab3f62123a550ca52ce68d9d7e0573c5084.1326372545.git.viresh.kumar@st.com>
> In a paragraph, "kernel thread" is mistakenly written as "kernel". Fix this by
> adding thread after word "kernel".
>
> Changes are shown in multiple lines, as they are realigned to 80 col width.
>
> Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
ACK.
^ permalink raw reply
* [PATCH] Documentation/power/freezing-of-tasks: Fix minor issue
From: Viresh Kumar @ 2012-01-13 4:39 UTC (permalink / raw)
To: rjw
Cc: pavel, len.brown, rdunlap, linux-pm, linux-doc, armando.visconti,
shiraz.hashim, vipin.kumar, rajeev-dlh.kumar, deepak.sikri,
vipulkumar.samar, amit.virdi, viresh.kumar, pratyush.anand,
bhupesh.sharma, viresh.linux, bhavna.yadav, vincenzo.frascino,
mirko.gardi
In a paragraph, "kernel thread" is mistakenly written as "kernel". Fix this by
adding thread after word "kernel".
Changes are shown in multiple lines, as they are realigned to 80 col width.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
Documentation/power/freezing-of-tasks.txt | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/Documentation/power/freezing-of-tasks.txt b/Documentation/power/freezing-of-tasks.txt
index 6ccb68f..ebd7490 100644
--- a/Documentation/power/freezing-of-tasks.txt
+++ b/Documentation/power/freezing-of-tasks.txt
@@ -120,10 +120,10 @@ So in practice, the 'at all' may become a 'why freeze kernel threads?' and
freezing user threads I don't find really objectionable."
Still, there are kernel threads that may want to be freezable. For example, if
-a kernel that belongs to a device driver accesses the device directly, it in
-principle needs to know when the device is suspended, so that it doesn't try to
-access it at that time. However, if the kernel thread is freezable, it will be
-frozen before the driver's .suspend() callback is executed and it will be
+a kernel thread that belongs to a device driver accesses the device directly, it
+in principle needs to know when the device is suspended, so that it doesn't try
+to access it at that time. However, if the kernel thread is freezable, it will
+be frozen before the driver's .suspend() callback is executed and it will be
thawed after the driver's .resume() callback has run, so it won't be accessing
the device while it's suspended.
--
1.7.8.110.g4cb5d
^ permalink raw reply related
* Re: [PATCH 0/6] RFC: CPU frequency min/max as PM QoS params
From: mark gross @ 2012-01-13 4:37 UTC (permalink / raw)
To: Antti P Miettinen; +Cc: linux-pm
In-Reply-To: <87ehv5cnui.fsf@amiettinen-lnx.nvidia.com>
On Thu, Jan 12, 2012 at 10:43:49AM +0200, Antti P Miettinen wrote:
> "Rafael J. Wysocki" <rjw@sisk.pl> writes:
> > On Wednesday, January 11, 2012, Antti P Miettinen wrote:
> >> I think for CPU performance, it's probably simplest just to use
> >> frequency. Mapping from GOPS/MIPS/FLOPS/FPS is probably more sensily
> >> done by PM QoS client side.
> >
> > Well, unfortunately, frequency is kind of system-specific. I mean,
> > you need to know what frequencies are supported/available to use that,
> > so it would require the potential users to know the CPU internals.
> >
> > Thanks,
> > Rafael
>
> I would expect clients requesting for computing performance to require
> system specific knowledge anyway. Computing performance is often
> affected by target specific details (CPU, memory, interconnects). So
> something like board specific configuration parameters would probably be
> required for the PM QoS clients doing computing performance requests.
>
Also, one doesn't have to know the exact number to use the throughput
parameter. If one value was not enough (i.e. you are missing
deadlines) the increase it until things stabilize.
In practice I doubt any of these qos parameter can be portable. I
once thought of using units of bogomips for cpu throughput but, thats
just as un-portable as frequency. Things will end up having to be
tuned or use some training algorithm.
--mark
^ permalink raw reply
* Re: [linux-pm] [RFC PATCH 1/2] thermal: Add a new trip type to use cooling device instance number
From: Amit Kachhap @ 2012-01-13 4:02 UTC (permalink / raw)
To: Rob Lee
Cc: Vincent Guittot, linux-pm, linaro-dev, patches, linux-kernel,
linux-acpi
In-Reply-To: <CAMXH7KG9JdxSxPERr4gG=nHFLdgUzqYBO=sUiDOp-G2bPcoVQw@mail.gmail.com>
Hi Rob,
I got your point. The main idea of doing like this is to keep the
cooling implementation independent from thermal zone
algorithms(thermal_sys.c). But binding freq_tab index to the trip
numbers may be not be bad idea. I will give more thought into it in
the next patchset.
Regards,
Amit D
On 11 January 2012 13:42, Rob Lee <rob.lee@linaro.org> wrote:
> Hey Amit/Vincent,
>
> It appears that with this implementation the STATE_ACTIVE trip number
> used will also be the index of the cool_freq_tab used. If that is
> true, then perhaps a common structure would be beneficial that links
> each STATE_ACTIVE trip point with its corresponding cooling data.
>
> BR,
> Rob
>
> On Tue, Dec 20, 2011 at 11:11 PM, Amit Kachhap <amit.kachhap@linaro.org> wrote:
>> Hi Vincent,
>>
>> Thanks for the review.
>> Well actually your are correct that current temperature and last
>> temperature can be used to increase or decrease the cpu frequency. But
>> this has to be done again in cooling devices so to make the cooling
>> devices generic and to avoid the temperature comparison again this new
>> trip type passes the cooling device instance id.
>> Also about your queries that this may add dependency between trip
>> index and cooling state. This is actually needed and this dependency
>> is created when the cooling device is binded with trip points(For
>> cpufreq type cooling device just the instance of cooling device is
>> associated with trip points). More over the existing PASSIVE cooling
>> trip type does the same thing and iterates across all the cooling
>> state.
>>
>> Thanks,
>> Amit Daniel
>>>
>>> On 20 December 2011 18:07, Vincent Guittot <vincent.guittot@linaro.org> wrote:
>>>>
>>>> Hi Amit,
>>>>
>>>> I'm not sure that using the trip index for setting the state of a
>>>> cooling device is a generic solution because you are adding a
>>>> dependency between the trip index and the cooling device state that
>>>> might be difficult to handle. This dependency implies that a cooling
>>>> device like cpufreq_cooling_device must be registered in the 1st trips
>>>> of a thermal_zone which is not possible when we want to register 2
>>>> cpufreq_cooling_devices in the same thermal_zone.
>>>> You should only rely on the current and last temperatures to detect if
>>>> a trip_temp has been crossed and you should increase or decrease the
>>>> current state of the cooling device accordingly.
>>>>
>>>> something like below should work with cpufreq_cooling_device and will
>>>> not add any constraint on the trip index. The state of a cooling
>>>> device is increased/decreased once for each trip
>>>>
>>>> + case THERMAL_TRIP_STATE_ACTIVE:
>>>> + list_for_each_entry(instance, &tz->cooling_devices,
>>>> + node) {
>>>> + if (instance->trip != count)
>>>> + continue;
>>>> +
>>>> + cdev = instance->cdev;
>>>> +
>>>> + if ((temp >= trip_temp)
>>>> + && (trip_temp > tz->last_temperature)) {
>>>> + cdev->ops->get_max_state(cdev,
>>>> + &max_state);
>>>> + cdev->ops->get_cur_state(cdev,
>>>> + ¤t_state);
>>>> + if (++current_state <= max_state)
>>>> + cdev->ops->set_cur_state(cdev,
>>>> + current_state);
>>>> + }
>>>> + else if ((temp < trip_temp)
>>>> + && (trip_temp <= tz->last_temperature)) {
>>>> + cdev->ops->get_cur_state(cdev,
>>>> + ¤t_state);
>>>> + if (current_state > 0)
>>>> + cdev->ops->set_cur_state(cdev,
>>>> + --current_state);
>>>> + }
>>>> + break;
>>>>
>>>> Regards,
>>>> Vincent
>>>>
>>>> On 13 December 2011 16:13, Amit Daniel Kachhap <amit.kachhap@linaro.org> wrote:
>>>> > This patch adds a new trip type THERMAL_TRIP_STATE_ACTIVE. This
>>>> > trip behaves same as THERMAL_TRIP_ACTIVE but also passes the cooling
>>>> > device instance number. This helps the cooling device registered as
>>>> > different instances to perform appropriate cooling action decision in
>>>> > the set_cur_state call back function.
>>>> >
>>>> > Also since the trip temperature's are in ascending order so some logic
>>>> > is put in place to skip the un-necessary checks.
>>>> >
>>>> > Signed-off-by: Amit Daniel Kachhap <amit.kachhap@linaro.org>
>>>> > ---
>>>> > Documentation/thermal/sysfs-api.txt | 4 ++--
>>>> > drivers/thermal/thermal_sys.c | 27 ++++++++++++++++++++++++++-
>>>> > include/linux/thermal.h | 1 +
>>>> > 3 files changed, 29 insertions(+), 3 deletions(-)
>>>> >
>>>> > diff --git a/Documentation/thermal/sysfs-api.txt b/Documentation/thermal/sysfs-api.txt
>>>> > index b61e46f..5c1d44e 100644
>>>> > --- a/Documentation/thermal/sysfs-api.txt
>>>> > +++ b/Documentation/thermal/sysfs-api.txt
>>>> > @@ -184,8 +184,8 @@ trip_point_[0-*]_temp
>>>> >
>>>> > trip_point_[0-*]_type
>>>> > Strings which indicate the type of the trip point.
>>>> > - E.g. it can be one of critical, hot, passive, active[0-*] for ACPI
>>>> > - thermal zone.
>>>> > + E.g. it can be one of critical, hot, passive, active[0-1],
>>>> > + state-active[0-*] for ACPI thermal zone.
>>>> > RO, Optional
>>>> >
>>>> > cdev[0-*]
>>>> > diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
>>>> > index dd9a574..72b1ab3 100644
>>>> > --- a/drivers/thermal/thermal_sys.c
>>>> > +++ b/drivers/thermal/thermal_sys.c
>>>> > @@ -192,6 +192,8 @@ trip_point_type_show(struct device *dev, struct device_attribute *attr,
>>>> > return sprintf(buf, "passive\n");
>>>> > case THERMAL_TRIP_ACTIVE:
>>>> > return sprintf(buf, "active\n");
>>>> > + case THERMAL_TRIP_STATE_ACTIVE:
>>>> > + return sprintf(buf, "state-active\n");
>>>> > default:
>>>> > return sprintf(buf, "unknown\n");
>>>> > }
>>>> > @@ -1035,7 +1037,7 @@ EXPORT_SYMBOL(thermal_cooling_device_unregister);
>>>> > void thermal_zone_device_update(struct thermal_zone_device *tz)
>>>> > {
>>>> > int count, ret = 0;
>>>> > - long temp, trip_temp;
>>>> > + long temp, trip_temp, max_state, last_trip_change = 0;
>>>> > enum thermal_trip_type trip_type;
>>>> > struct thermal_cooling_device_instance *instance;
>>>> > struct thermal_cooling_device *cdev;
>>>> > @@ -1086,6 +1088,29 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
>>>> > cdev->ops->set_cur_state(cdev, 0);
>>>> > }
>>>> > break;
>>>> > + case THERMAL_TRIP_STATE_ACTIVE:
>>>> > + list_for_each_entry(instance, &tz->cooling_devices,
>>>> > + node) {
>>>> > + if (instance->trip != count)
>>>> > + continue;
>>>> > +
>>>> > + if (temp <= last_trip_change)
>>>> > + continue;
>>>> > +
>>>> > + cdev = instance->cdev;
>>>> > + cdev->ops->get_max_state(cdev, &max_state);
>>>> > +
>>>> > + if ((temp >= trip_temp) &&
>>>> > + ((count + 1) <= max_state))
>>>> > + cdev->ops->set_cur_state(cdev,
>>>> > + count + 1);
>>>> > + else if ((temp < trip_temp) &&
>>>> > + (count <= max_state))
>>>> > + cdev->ops->set_cur_state(cdev, count);
>>>> > +
>>>> > + last_trip_change = trip_temp;
>>>> > + }
>>>> > + break;
>>>> > case THERMAL_TRIP_PASSIVE:
>>>> > if (temp >= trip_temp || tz->passive)
>>>> > thermal_zone_device_passive(tz, temp,
>>>> > diff --git a/include/linux/thermal.h b/include/linux/thermal.h
>>>> > index 47b4a27..d7d0a27 100644
>>>> > --- a/include/linux/thermal.h
>>>> > +++ b/include/linux/thermal.h
>>>> > @@ -42,6 +42,7 @@ enum thermal_trip_type {
>>>> > THERMAL_TRIP_PASSIVE,
>>>> > THERMAL_TRIP_HOT,
>>>> > THERMAL_TRIP_CRITICAL,
>>>> > + THERMAL_TRIP_STATE_ACTIVE,
>>>> > };
>>>> >
>>>> > struct thermal_zone_device_ops {
>>>> > --
>>>> > 1.7.1
>>>> >
>>>> > _______________________________________________
>>>> > linux-pm mailing list
>>>> > linux-pm@lists.linux-foundation.org
>>>> > https://lists.linuxfoundation.org/mailman/listinfo/linux-pm
>>>
>>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>> Please read the FAQ at http://www.tux.org/lkml/
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" 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
* Re: [RFC PATCH 2/2] thermal: Add generic cpu cooling implementation
From: Amit Kachhap @ 2012-01-13 3:50 UTC (permalink / raw)
To: Rob Lee; +Cc: linaro-dev, patches, linux-kernel, linux-acpi, linux-pm
In-Reply-To: <CAMXH7KEBCTWDsSFn+ZUsbetvbWXO3N9ZMpLBvLm0n0r2RH1wuQ@mail.gmail.com>
On 11 January 2012 13:32, Rob Lee <rob.lee@linaro.org> wrote:
> Hey Amit, I was able to use your code on an i.MX6Q thermal
> implementation and it seemed to work pretty well. Thanks for adding
> this. A couple of comments below.
Thanks for testing and reviewing the code.
>
> On Tue, Dec 13, 2011 at 9:13 AM, Amit Daniel Kachhap
> <amit.kachhap@linaro.org> wrote:
>> This patch adds support for generic cpu thermal cooling low level
>> implementations using frequency scaling and cpuhotplugg currently.
>> Different cpu related cooling devices can be registered by the
>> user and the binding of these cooling devices to the corresponding
>> trip points can be easily done as the registration API's return the
>> cooling device pointer.
>>
>> Signed-off-by: Amit Daniel Kachhap <amit.kachhap@linaro.org>
>> ---
>> Documentation/thermal/cpu-cooling-api.txt | 52 +++++
>> drivers/thermal/Kconfig | 11 +
>> drivers/thermal/Makefile | 1 +
>> drivers/thermal/cpu_cooling.c | 302 +++++++++++++++++++++++++++++
>> include/linux/cpu_cooling.h | 45 +++++
>> 5 files changed, 411 insertions(+), 0 deletions(-)
>> create mode 100644 Documentation/thermal/cpu-cooling-api.txt
>> create mode 100644 drivers/thermal/cpu_cooling.c
>> create mode 100644 include/linux/cpu_cooling.h
>>
>> diff --git a/Documentation/thermal/cpu-cooling-api.txt b/Documentation/thermal/cpu-cooling-api.txt
>> new file mode 100644
>> index 0000000..d30b4f2
>> --- /dev/null
>> +++ b/Documentation/thermal/cpu-cooling-api.txt
>> @@ -0,0 +1,52 @@
>> +CPU cooling api's How To
>> +===================================
>> +
>> +Written by Amit Daniel Kachhap <amit.kachhap@linaro.org>
>> +
>> +Updated: 13 Dec 2011
>> +
>> +Copyright (c) 2011 Samsung Electronics Co., Ltd(http://www.samsung.com)
>> +
>> +0. Introduction
>> +
>> +The generic cpu cooling(freq clipping, cpuhotplug) provides
>> +registration/unregistration api's to the user. The binding of the cooling
>> +devices to the trip types is left for the user. The registration api's returns
>> +the cooling device pointer.
>> +
>> +1. cpufreq cooling api's
>> +
>> +1.1 cpufreq registration api's
>> +1.1.1 struct thermal_cooling_device *cpufreq_cooling_register(
>> + struct freq_pctg_table *tab_ptr, unsigned int tab_size,
>> + const struct cpumask *mask_val)
>> +
>> + This interface function registers the cpufreq cooling device with the name
>> + "thermal-cpufreq".
>> +
>> + tab_ptr: The table containing the percentage of frequency to be clipped for
>> + each cooling state.
>> + .freq_clip_pctg[NR_CPUS]:Percentage of frequency to be clipped for each
>> + cpu.
>> + .polling_interval: polling interval for this cooling state.
>> + tab_size: the total number of cooling state.
>> + mask_val: all the allowed cpu's where frequency clipping can happen.
>> +
>> +1.1.2 void cpufreq_cooling_unregister(void)
>> +
>> + This interface function unregisters the "thermal-cpufreq" cooling device.
>> +
>> +
>> +1.2 cpuhotplug registration api's
>> +
>> +1.2.1 struct thermal_cooling_device *cpuhotplug_cooling_register(
>> + const struct cpumask *mask_val)
>> +
>> + This interface function registers the cpuhotplug cooling device with the name
>> + "thermal-cpuhotplug".
>> +
>> + mask_val: all the allowed cpu's which can be hotplugged out.
>> +
>> +1.1.2 void cpuhotplug_cooling_unregister(void)
>> +
>> + This interface function unregisters the "thermal-cpuhotplug" cooling device.
>> diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
>> index f7f71b2..298c1cd 100644
>> --- a/drivers/thermal/Kconfig
>> +++ b/drivers/thermal/Kconfig
>> @@ -18,3 +18,14 @@ config THERMAL_HWMON
>> depends on THERMAL
>> depends on HWMON=y || HWMON=THERMAL
>> default y
>> +
>> +config CPU_THERMAL
>> + bool "generic cpu cooling support"
>> + depends on THERMAL
>> + help
>> + This implements the generic cpu cooling mechanism through frequency
>> + reduction, cpu hotplug and any other ways of reducing temperature. An
>> + ACPI version of this already exists(drivers/acpi/processor_thermal.c).
>> + This will be useful for platforms using the generic thermal interface
>> + and not the ACPI interface.
>> + If you want this support, you should say Y or M here.
>> diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
>> index 31108a0..655cbc4 100644
>> --- a/drivers/thermal/Makefile
>> +++ b/drivers/thermal/Makefile
>> @@ -3,3 +3,4 @@
>> #
>>
>> obj-$(CONFIG_THERMAL) += thermal_sys.o
>> +obj-$(CONFIG_CPU_THERMAL) += cpu_cooling.o
>> diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
>> new file mode 100644
>> index 0000000..cdd148c
>> --- /dev/null
>> +++ b/drivers/thermal/cpu_cooling.c
>> @@ -0,0 +1,302 @@
>> +/*
>> + * linux/drivers/thermal/cpu_cooling.c
>> + *
>> + * Copyright (C) 2011 Samsung Electronics Co., Ltd(http://www.samsung.com)
>> + * Copyright (C) 2011 Amit Daniel <amit.kachhap@linaro.org>
>> + *
>> + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; version 2 of the License.
>> + *
>> + * This program is distributed in the hope that it will be useful, but
>> + * WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
>> + * General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License along
>> + * with this program; if not, write to the Free Software Foundation, Inc.,
>> + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
>> + *
>> + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> + */
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +#include <linux/thermal.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/cpufreq.h>
>> +#include <linux/err.h>
>> +#include <linux/slab.h>
>> +#include <linux/cpu.h>
>> +#include <linux/cpu_cooling.h>
>> +
>> +#ifdef CONFIG_CPU_FREQ
>> +struct cpufreq_cooling_device {
>> + struct thermal_cooling_device *cool_dev;
>> + struct freq_pctg_table *tab_ptr;
>> + unsigned int tab_size;
>> + unsigned int cpufreq_state;
>> + const struct cpumask *allowed_cpus;
>> +};
>> +
>> +static struct cpufreq_cooling_device *cpufreq_device;
>> +
>> +/*Below codes defines functions to be used for cpufreq as cooling device*/
>> +static bool is_cpufreq_valid(int cpu)
>> +{
>> + struct cpufreq_policy policy;
>> + if (!cpufreq_get_policy(&policy, cpu))
>> + return true;
>> + return false;
>> +}
>> +
>> +static int cpufreq_apply_cooling(int cooling_state)
>> +{
>> + int cpuid, this_cpu = smp_processor_id();
>> +
>> + if (!is_cpufreq_valid(this_cpu))
>> + return 0;
>> +
>> + if (cooling_state > cpufreq_device->tab_size)
>> + return -EINVAL;
>> +
>> + /*Check if last cooling level is same as current cooling level*/
>> + if (cpufreq_device->cpufreq_state == cooling_state)
>> + return 0;
>> +
>> + cpufreq_device->cpufreq_state = cooling_state;
>> +
>> + for_each_cpu(cpuid, cpufreq_device->allowed_cpus) {
>> + if (is_cpufreq_valid(cpuid))
>> + cpufreq_update_policy(cpuid);
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static int thermal_cpufreq_notifier(struct notifier_block *nb,
>> + unsigned long event, void *data)
>> +{
>> + struct cpufreq_policy *policy = data;
>> + struct freq_pctg_table *th_table;
>> + unsigned long max_freq = 0;
>> + unsigned int cpu = policy->cpu, th_pctg = 0, level;
>> +
>> + if (event != CPUFREQ_ADJUST)
>> + return 0;
>> +
>> + level = cpufreq_device->cpufreq_state;
>> +
>> + if (level > 0) {
>> + th_table =
>> + &(cpufreq_device->tab_ptr[level - 1]);
>> + th_pctg = th_table->freq_clip_pctg[cpu];
>> + }
>> +
>> + max_freq =
>> + (policy->cpuinfo.max_freq * (100 - th_pctg)) / 100;
>> +
>> + cpufreq_verify_within_limits(policy, 0, max_freq);
>> +
>> + return 0;
>> +}
>> +
>> +/*
>> + * cpufreq cooling device callback functions
>> + */
>> +static int cpufreq_get_max_state(struct thermal_cooling_device *cdev,
>> + unsigned long *state)
>> +{
>> + *state = cpufreq_device->tab_size;
>> + return 0;
>> +}
>> +
>> +static int cpufreq_get_cur_state(struct thermal_cooling_device *cdev,
>> + unsigned long *state)
>> +{
>> + *state = cpufreq_device->cpufreq_state;
>> + return 0;
>> +}
>> +
>> +/*This cooling may be as PASSIVE/STATE_ACTIVE type*/
>> +static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev,
>> + unsigned long state)
>> +{
>> + cpufreq_apply_cooling(state);
>> + return 0;
>> +}
>> +
>> +/* bind cpufreq callbacks to cpufreq cooling device */
>> +static struct thermal_cooling_device_ops cpufreq_cooling_ops = {
>> + .get_max_state = cpufreq_get_max_state,
>> + .get_cur_state = cpufreq_get_cur_state,
>> + .set_cur_state = cpufreq_set_cur_state,
>> +};
>> +
>> +static struct notifier_block thermal_cpufreq_notifier_block = {
>> + .notifier_call = thermal_cpufreq_notifier,
>> +};
>> +
>> +struct thermal_cooling_device *cpufreq_cooling_register(
>> + struct freq_pctg_table *tab_ptr, unsigned int tab_size,
>> + const struct cpumask *mask_val)
>> +{
>> + struct thermal_cooling_device *cool_dev;
>> +
>> + if (tab_ptr == NULL || tab_size == 0)
>> + return ERR_PTR(-EINVAL);
>> +
>> + cpufreq_device =
>> + kzalloc(sizeof(struct cpufreq_cooling_device), GFP_KERNEL);
>> +
>> + if (!cpufreq_device)
>> + return ERR_PTR(-ENOMEM);
>> +
>> + cool_dev = thermal_cooling_device_register("thermal-cpufreq", NULL,
>> + &cpufreq_cooling_ops);
>> + if (!cool_dev) {
>> + kfree(cpufreq_device);
>> + return ERR_PTR(-EINVAL);
>> + }
>> +
>> + cpufreq_device->tab_ptr = tab_ptr;
>> + cpufreq_device->tab_size = tab_size;
>> + cpufreq_device->cool_dev = cool_dev;
>> + cpufreq_device->allowed_cpus = mask_val;
>> +
>> + cpufreq_register_notifier(&thermal_cpufreq_notifier_block,
>> + CPUFREQ_POLICY_NOTIFIER);
>> + return cool_dev;
>> +}
>> +EXPORT_SYMBOL(cpufreq_cooling_register);
>> +
>> +void cpufreq_cooling_unregister(void)
>> +{
>> + cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block,
>> + CPUFREQ_POLICY_NOTIFIER);
>> + thermal_cooling_device_unregister(cpufreq_device->cool_dev);
>> + kfree(cpufreq_device);
>> +}
>> +EXPORT_SYMBOL(cpufreq_cooling_unregister);
>> +#else /*!CONFIG_CPU_FREQ*/
>> +struct thermal_cooling_device *cpufreq_cooling_register(
>> + struct freq_pctg_table *tab_ptr, unsigned int tab_size)
>
> Need to add the "const struct cpumask *mask_val" parameter
> to this function like it's used above and prototyped in the heard
> or else it causes a build error when building
> without CONFIG_CPU_FREQ defined.
Yes sure somehow missed adding this. Thanks for pointing this out.
>
>> +{
>> + return NULL;
>> +}
>> +EXPORT_SYMBOL(cpufreq_cooling_register);
>> +void cpufreq_cooling_unregister(void)
>> +{
>> + return;
>> +}
>> +EXPORT_SYMBOL(cpufreq_cooling_unregister);
>> +#endif /*CONFIG_CPU_FREQ*/
>> +
>> +#ifdef CONFIG_HOTPLUG_CPU
>> +
>> +struct hotplug_cooling_device {
>> + struct thermal_cooling_device *cool_dev;
>> + unsigned int hotplug_state;
>> + const struct cpumask *allowed_cpus;
>> +};
>> +static struct hotplug_cooling_device *hotplug_device;
>> +
>> +/*
>> + * cpu hotplug cooling device callback functions
>> + */
>> +static int cpuhotplug_get_max_state(struct thermal_cooling_device *cdev,
>> + unsigned long *state)
>> +{
>> + *state = 1;
>> + return 0;
>> +}
>> +
>> +static int cpuhotplug_get_cur_state(struct thermal_cooling_device *cdev,
>> + unsigned long *state)
>> +{
>> + /*This cooling device may be of type ACTIVE, so state field
>> + can be 0 or 1*/
>> + *state = hotplug_device->hotplug_state;
>> + return 0;
>> +}
>> +
>> +/*This cooling may be as PASSIVE/STATE_ACTIVE type*/
>> +static int cpuhotplug_set_cur_state(struct thermal_cooling_device *cdev,
>> + unsigned long state)
>> +{
>> + int cpuid, this_cpu = smp_processor_id();
>> +
>> + if (hotplug_device->hotplug_state == state)
>> + return 0;
>> +
>> + /*This cooling device may be of type ACTIVE, so state field
>> + can be 0 or 1*/
>> + if (state == 1) {
>> + for_each_cpu(cpuid, hotplug_device->allowed_cpus) {
>> + if (cpu_online(cpuid) && (cpuid != this_cpu))
>> + cpu_down(cpuid);
>> + }
>> + } else if (state == 0) {
>> + for_each_cpu(cpuid, hotplug_device->allowed_cpus) {
>> + if (!cpu_online(cpuid) && (cpuid != this_cpu))
>> + cpu_up(cpuid);
>> + }
>> + } else
>> + return -EINVAL;
>> +
>
> I don't like how ACTIVE does not have available notification callbacks
> like HOT and CRITICAL do. Perhaps I fail to grasp why they aren't there
> but besides just applying a cooling device, one might want to do something
> else as well upon hitting these trip points. So that said, it might be nice
> to add a notification to STATE_ACTIVE as well.
Well I added ACTIVE_STATE trip type as just some additional features
over trip type ACTIVE. Also each thermal zone can have more then one
trip types so HOT notifications can still be used. But I like your
suggestion of putting notfications in all the trip types. Lets see if
the maintainers agree to this idea.
>
>> + hotplug_device->hotplug_state = state;
>> +
>> + return 0;
>> +}
>> +/* bind hotplug callbacks to cpu hotplug cooling device */
>> +static struct thermal_cooling_device_ops cpuhotplug_cooling_ops = {
>> + .get_max_state = cpuhotplug_get_max_state,
>> + .get_cur_state = cpuhotplug_get_cur_state,
>> + .set_cur_state = cpuhotplug_set_cur_state,
>> +};
>> +
>> +struct thermal_cooling_device *cpuhotplug_cooling_register(
>> + const struct cpumask *mask_val)
>> +{
>> + struct thermal_cooling_device *cool_dev;
>> +
>> + hotplug_device =
>> + kzalloc(sizeof(struct hotplug_cooling_device), GFP_KERNEL);
>> +
>> + if (!hotplug_device)
>> + return ERR_PTR(-ENOMEM);
>> +
>> + cool_dev = thermal_cooling_device_register("thermal-cpuhotplug", NULL,
>> + &cpuhotplug_cooling_ops);
>> + if (!cool_dev) {
>> + kfree(hotplug_device);
>> + return ERR_PTR(-EINVAL);
>> + }
>> +
>> + hotplug_device->cool_dev = cool_dev;
>> + hotplug_device->hotplug_state = 0;
>> + hotplug_device->allowed_cpus = mask_val;
>> +
>> + return cool_dev;
>> +}
>> +EXPORT_SYMBOL(cpuhotplug_cooling_register);
>> +
>> +void cpuhotplug_cooling_unregister(void)
>> +{
>> + thermal_cooling_device_unregister(hotplug_device->cool_dev);
>> + kfree(hotplug_device);
>> +}
>> +EXPORT_SYMBOL(cpuhotplug_cooling_unregister);
>> +#else /*!CONFIG_HOTPLUG_CPU*/
>> +struct thermal_cooling_device *cpuhotplug_cooling_register(
>> + const struct cpumask *mask_val)
>> +{
>> + return NULL;
>> +}
>> +EXPORT_SYMBOL(cpuhotplug_cooling_register);
>> +void cpuhotplug_cooling_unregister(void)
>> +{
>> + return;
>> +}
>> +EXPORT_SYMBOL(cpuhotplug_cooling_unregister);
>> +#endif /*CONFIG_HOTPLUG_CPU*/
>> diff --git a/include/linux/cpu_cooling.h b/include/linux/cpu_cooling.h
>> new file mode 100644
>> index 0000000..0c57375
>> --- /dev/null
>> +++ b/include/linux/cpu_cooling.h
>> @@ -0,0 +1,45 @@
>> +/*
>> + * linux/include/linux/cpu_cooling.h
>> + *
>> + * Copyright (C) 2011 Samsung Electronics Co., Ltd(http://www.samsung.com)
>> + * Copyright (C) 2011 Amit Daniel <amit.kachhap@linaro.org>
>> + *
>> + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; version 2 of the License.
>> + *
>> + * This program is distributed in the hope that it will be useful, but
>> + * WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
>> + * General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License along
>> + * with this program; if not, write to the Free Software Foundation, Inc.,
>> + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
>> + *
>> + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> + */
>> +
>> +#ifndef __CPU_COOLING_H__
>> +#define __CPU_COOLING_H__
>> +
>> +#include <linux/thermal.h>
>> +
>> +struct freq_pctg_table {
>> + unsigned int freq_clip_pctg[NR_CPUS];
>> + unsigned int polling_interval;
>> +};
>> +
>> +extern struct thermal_cooling_device *cpufreq_cooling_register(
>> + struct freq_pctg_table *tab_ptr, unsigned int tab_size,
>> + const struct cpumask *mask_val);
>> +
>> +extern void cpufreq_cooling_unregister(void);
>> +
>> +extern struct thermal_cooling_device *cpuhotplug_cooling_register(
>> + const struct cpumask *mask_val);
>> +
>> +extern void cpuhotplug_cooling_unregister(void);
>> +
>> +#endif /* __CPU_COOLING_H__ */
>> --
>> 1.7.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>> Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply
* Re: [PATCH 0/6] RFC: CPU frequency min/max as PM QoS params
From: Rafael J. Wysocki @ 2012-01-12 23:55 UTC (permalink / raw)
To: Antti P Miettinen; +Cc: linux-pm
In-Reply-To: <87ipkhco4h.fsf@amiettinen-lnx.nvidia.com>
On Thursday, January 12, 2012, Antti P Miettinen wrote:
> "Rafael J. Wysocki" <rjw@sisk.pl> writes:
> >> By blocking sleep states we can address "system level latency" or "best case
> >> latency" but as far as I can see PM QoS does not address "worst case
> >> latency".
> >
> > I'm not sure what you mean by "worst case latency".
>
> Umm.. the usual concept. If latency is the time from stimulus to
> response, this time can vary based on context. One part of the context
> is the hardware state but there is also the system load. So for example
> the time from interrupt to display being updated is affected by hardware
> state but also system load. As far as I understand, current PM QoS
> latency requests addresses hardware state but do not account for
> possible resource contention, e.g. several latency sensitive clients
> (device drivers, tasks) competing for CPU. In this sense minimum CPU
> frequency requests would be similar.
That's correct, we don't take possible contention into account in PM QoS,
because such conditions may happen idependently of power management anyway.
Thanks,
Rafael
^ permalink raw reply
* Re: [PATCH 0/6] RFC: CPU frequency min/max as PM QoS params
From: Rafael J. Wysocki @ 2012-01-12 23:52 UTC (permalink / raw)
To: markgross; +Cc: linux-pm, Antti P Miettinen
In-Reply-To: <20120112030642.GD14968@mgross-G62>
On Thursday, January 12, 2012, mark gross wrote:
> On Tue, Jan 10, 2012 at 10:02:49PM +0100, Jean Pihet wrote:
> > Hi Mark, Rafael,
> >
> > On Tue, Jan 10, 2012 at 9:46 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > > On Tuesday, January 10, 2012, mark gross wrote:
> > >> On Mon, Jan 09, 2012 at 10:27:29PM +0100, Rafael J. Wysocki wrote:
> > >> > On Monday, January 09, 2012, mark gross wrote:
> > >> > > On Sun, Jan 08, 2012 at 11:59:24PM +0100, Rafael J. Wysocki wrote:
> > >> > > > On Friday, January 06, 2012, mark gross wrote:
> > >> > > > > On Fri, Jan 06, 2012 at 02:36:20AM +0200, Antti P Miettinen wrote:
> > >> > > > > > The inspiration for this patch series is the N9 CPU frequency boost
> > >> > > > > > upon input events:
> > >> > > > > >
> > >> > > > > > http://www.spinics.net/lists/cpufreq/msg00667.html
> > >> > > > > >
> > >> > > > > > and the related changes in git://codeaurora.org/kernel/msm.git tree.
> > >> > > > > > Those patches modify the ondemand cpufreq governor. This patch series
> > >> > > > > > adds minimum and maximum CPU frequency as PM QoS parameters and
> > >> > > > > > modifies the cpufreq core to enforce the PM QoS limits. There is also
> > >> > > > > > an example module for boosting the frequency upon input events.
> > >> > > > > >
> > >> > > > > > I've been testing these changes against Ubuntu 3.2 kernel on a Dell
> > >> > > > > > E6420 with the ACPI cpufreq driver. The patches are against
> > >> > > > > > linux-next/master, compile tested against it.
> > >> > > > > >
> > >> > > > > > --Antti
> > >> > > > > >
> > >> > > > > > Alex Frid (1):
> > >> > > > > > PM QoS: Simplify PM QoS expansion/merge
> > >> > > > > >
> > >> > > > > > Antti P Miettinen (5):
> > >> > > > > > PM QoS: Add CPU frequency min/max as PM QoS params
> > >> > > > > > cpufreq: Export user_policy min/max
> > >> > > > > > cpufreq: Preserve sysfs min/max request
> > >> > > > > > cpufreq: Enforce PM QoS min/max limits
> > >> > > > > > input: CPU frequency booster
> > >> > > > > >
> > >> > > > > > drivers/cpufreq/cpufreq.c | 57 +++++++++++++-
> > >> > > > > > drivers/input/Kconfig | 9 ++
> > >> > > > > > drivers/input/Makefile | 1 +
> > >> > > > > > drivers/input/input-cfboost.c | 174 +++++++++++++++++++++++++++++++++++++++++
> > >> > > > > > include/linux/pm_qos.h | 19 ++++-
> > >> > > > > > kernel/power/qos.c | 55 ++++++++++----
> > >> > > > > > 6 files changed, 293 insertions(+), 22 deletions(-)
> > >> > > > > > create mode 100644 drivers/input/input-cfboost.c
> > >> > > > > >
> > >> > > > >
> > >> > > > > The following is my version of part of this patch set I was tinkering
> > >> > > > > with. Its missing the cpufreq notification this change has and doesn't
> > >> > > > > do anything WRT cfboost.
> > >> > > > >
> > >> > > > > Would it be ok if we could consolidate our two implementations and
> > >> > > > > completely separate the cfboost stuff as a separate patch set?
> > >> > > > >
> > >> > > > > My code below is missing the cpufreq notification logic you have.
> > >> > > >
> > >> > > > Well, I have one substantial problem with this approach. Namely, our
> > >> > > > current PM QoS infrastructure is not suitable for throughput constraints,
> > >> > > > because they should be additive, unlike the latency ones.
> > >> > > >
> > >> > > > Namely, if sombody requests throughput X and someone else Y, the resulting
> > >> > > > combined throughput should be X+Y rather than max(X, Y).
> > >> > >
> > >> > > That can be done easy enough. However; in practice I'm not convinced
> > >> > > doing and additive aggregation of the requested QoS would be any better
> > >> > > than just taking the max.
> > >> >
> > >> > Well, I'd say it's necessary for correctness, perhaps not for the CPU, but in
> > >> > general. If Y is the max, then the subsystem that requested X may easily
> > >> > starve whoever requested the Y by using all of the bandwidth it asked for.
> > >>
> > >> I was thinking about this from the CPU point of view more over the day.
> > >> Given that there are many times more than one make the qos requests
> > >> additive will result in quickly requesting more cpu than is available
> > >> and waisting a lot of power. Also additive aggregation falls over a
> > >> bit on with multi-core.
> > >>
> > >> As the consumer of the cpu resources are tasks, and we can only run one
> > >> task at a time on a cpu, I'm talking myself into thinking that max
> > >> *is* the right way to go for cpu throughput (i.e. frequency).
> > There are case where the constraints values should be additive. The
> > best example is the main memory throughput and so the memory
> > controller frequency (or the L3 frequency on OMAP). The main problem
> > is to estimate the overhead of multiple simultaneous transfers.
> >
> > What do you think?
>
> I think the number of that get summed in you memory bus example needs to
> be tied to the number of DMA engines + CPU cores that can concurrently
> transfer on that bus. To sum all the request I think is too simplistic
> and will result in always maxing aggregate request
That still seems to be better than simply using the maximum requested
value.
Thanks,
Rafael
^ permalink raw reply
* Re: [PATCH 2/7] tboot: Add return values for tboot_sleep
From: Konrad Rzeszutek Wilk @ 2012-01-12 20:23 UTC (permalink / raw)
To: Cihula, Joseph
Cc: Brown, Len, x86@kernel.org, linux-kernel@vger.kernel.org,
linux-acpi@vger.kernel.org, tboot-devel@lists.sourceforge.net,
liang.tang@oracle.com, hpa@zytor.com,
linux-pm@lists.linux-foundation.org
In-Reply-To: <20120112174958.GA22515@phenom.dumpdata.com>
On Thu, Jan 12, 2012 at 09:49:58AM -0800, Konrad Rzeszutek Wilk wrote:
> On Tue, Jan 10, 2012 at 08:10:53PM +0000, Cihula, Joseph wrote:
> > ACK, but tboot_sleep() calls tboot_shutdown() and there are error conditions in that which you are not reflecting upward--i.e. you should make tboot_shutdown() return an 'int' and propagate its errors through tboot_sleep().
>
> Hey Joe,
>
> Thanks for looking at the patches.
>
> Right now [with this patch applied] the code looks as so:
>
> 297
> 298 tboot_shutdown(acpi_shutdown_map[sleep_state]);
> 299 return 0;
> 300 }
>
>
> If we do make tboot_shutdown() return an int, there will be a need to modify
> other callers: native_machine_emergency_restart, native_machine_halt,
> native_machine_power_off, and native_play_dead as well.
>
> Perhaps that could be done in another patch and leave this one as is
> where the 'tboot_sleep' would just return 0 instead of
> 'return tboot_shutdown(...)' ?
>
> Perhaps another way to do this is to extract the common code of tboot_sleep
> and tboot_shutdown?
Like this (not yet tested):
diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c
index 6410744..2f93a50 100644
--- a/arch/x86/kernel/tboot.c
+++ b/arch/x86/kernel/tboot.c
@@ -212,17 +212,16 @@ static int tboot_setup_sleep(void)
{
/* S3 shutdown requested, but S3 not supported by the kernel... */
BUG();
- return -1;
+ return -ENOSYS;
}
#endif
-void tboot_shutdown(u32 shutdown_type)
-{
- void (*shutdown)(void);
+static int tboot_check(u32 shutdown_type) {
+
if (!tboot_enabled())
- return;
+ return -ENODEV;
/*
* if we're being called before the 1:1 mapping is set up then just
@@ -230,12 +229,21 @@ void tboot_shutdown(u32 shutdown_type)
* due to very early panic()
*/
if (!tboot_pg_dir)
- return;
+ return -EBUSY;
/* if this is S3 then set regions to MAC */
- if (shutdown_type == TB_SHUTDOWN_S3)
- if (tboot_setup_sleep())
- return;
+ if (shutdown_type == TB_SHUTDOWN_S3) {
+ int err = tboot_setup_sleep();
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+static void __tboot_shutdown(u32 shutdown_type)
+{
+ void (*shutdown)(void);
tboot->shutdown_type = shutdown_type;
@@ -248,6 +256,13 @@ void tboot_shutdown(u32 shutdown_type)
while (1)
halt();
}
+void tboot_shutdown(u32 shutdown_type)
+{
+ if (!tboot_check(shutdown_type))
+ return;
+
+ __tboot_shutdown(shutdown_type);
+}
static void tboot_copy_fadt(const struct acpi_table_fadt *fadt)
{
@@ -279,9 +294,17 @@ static int tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control)
/* S3: */ TB_SHUTDOWN_S3,
/* S4: */ TB_SHUTDOWN_S4,
/* S5: */ TB_SHUTDOWN_S5 };
+ int err;
- if (!tboot_enabled())
- return 0;
+ if (sleep_state >= ACPI_S_STATE_COUNT ||
+ acpi_shutdown_map[sleep_state] == -1) {
+ pr_warning("unsupported sleep state 0x%x\n", sleep_state);
+ return -ENOSYS;
+ }
+
+ err = tboot_check(acpi_shutdown_map[sleep_state]);
+ if (!err && err != EBUSY)
+ return err;
tboot_copy_fadt(&acpi_gbl_FADT);
tboot->acpi_sinfo.pm1a_cnt_val = pm1a_control;
@@ -289,13 +312,7 @@ static int tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control)
/* we always use the 32b wakeup vector */
tboot->acpi_sinfo.vector_width = 32;
- if (sleep_state >= ACPI_S_STATE_COUNT ||
- acpi_shutdown_map[sleep_state] == -1) {
- pr_warning("unsupported sleep state 0x%x\n", sleep_state);
- return -1;
- }
-
- tboot_shutdown(acpi_shutdown_map[sleep_state]);
+ __tboot_shutdown((acpi_shutdown_map[sleep_state]));
return 0;
}
^ permalink raw reply related
* Re: [PATCH 2/7] tboot: Add return values for tboot_sleep
From: Konrad Rzeszutek Wilk @ 2012-01-12 17:49 UTC (permalink / raw)
To: Cihula, Joseph
Cc: Brown, Len, x86@kernel.org, linux-kernel@vger.kernel.org,
linux-acpi@vger.kernel.org, tboot-devel@lists.sourceforge.net,
liang.tang@oracle.com, hpa@zytor.com,
linux-pm@lists.linux-foundation.org
In-Reply-To: <9F57BF860713DF4BA3EFA4F8C6DFEDAC2420CBB9@ORSMSX101.amr.corp.intel.com>
On Tue, Jan 10, 2012 at 08:10:53PM +0000, Cihula, Joseph wrote:
> ACK, but tboot_sleep() calls tboot_shutdown() and there are error conditions in that which you are not reflecting upward--i.e. you should make tboot_shutdown() return an 'int' and propagate its errors through tboot_sleep().
Hey Joe,
Thanks for looking at the patches.
Right now [with this patch applied] the code looks as so:
297
298 tboot_shutdown(acpi_shutdown_map[sleep_state]);
299 return 0;
300 }
If we do make tboot_shutdown() return an int, there will be a need to modify
other callers: native_machine_emergency_restart, native_machine_halt,
native_machine_power_off, and native_play_dead as well.
Perhaps that could be done in another patch and leave this one as is
where the 'tboot_sleep' would just return 0 instead of
'return tboot_shutdown(...)' ?
Perhaps another way to do this is to extract the common code of tboot_sleep
and tboot_shutdown?
>
> Joe
>
> > -----Original Message-----
> > From: Konrad Rzeszutek Wilk [mailto:konrad.wilk@oracle.com]
> > Sent: Friday, December 16, 2011 2:38 PM
> > To: linux-kernel@vger.kernel.org; rjw@sisk.pl; x86@kernel.org; Brown, Len; Cihula, Joseph; linux-
> > pm@lists.linux-foundation.org; tboot-devel@lists.sourceforge.net; linux-acpi@vger.kernel.org;
> > liang.tang@oracle.com
> > Cc: hpa@zytor.com; Konrad Rzeszutek Wilk
> > Subject: [PATCH 2/7] tboot: Add return values for tboot_sleep
> >
> > . as appropiately. As tboot_sleep now returns values.
> > remove tboot_sleep_wrapper.
> >
> > Suggested-by: "Rafael J. Wysocki" <rjw@sisk.pl>
> > CC: Joseph Cihula <joseph.cihula@intel.com>
> > [v1: Return -1/0/+1 instead of ACPI_xx values]
> > Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> > ---
> > arch/x86/kernel/tboot.c | 13 ++++---------
> > 1 files changed, 4 insertions(+), 9 deletions(-)
> >
> > diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c index 1a4ab7d..6410744 100644
> > --- a/arch/x86/kernel/tboot.c
> > +++ b/arch/x86/kernel/tboot.c
> > @@ -272,7 +272,7 @@ static void tboot_copy_fadt(const struct acpi_table_fadt *fadt)
> > offsetof(struct acpi_table_facs, firmware_waking_vector); }
> >
> > -void tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control)
> > +static int tboot_sleep(u8 sleep_state, u32 pm1a_control, u32
> > +pm1b_control)
> > {
> > static u32 acpi_shutdown_map[ACPI_S_STATE_COUNT] = {
> > /* S0,1,2: */ -1, -1, -1,
> > @@ -281,7 +281,7 @@ void tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control)
> > /* S5: */ TB_SHUTDOWN_S5 };
> >
> > if (!tboot_enabled())
> > - return;
> > + return 0;
> >
> > tboot_copy_fadt(&acpi_gbl_FADT);
> > tboot->acpi_sinfo.pm1a_cnt_val = pm1a_control; @@ -292,15 +292,10 @@ void tboot_sleep(u8
> > sleep_state, u32 pm1a_control, u32 pm1b_control)
> > if (sleep_state >= ACPI_S_STATE_COUNT ||
> > acpi_shutdown_map[sleep_state] == -1) {
> > pr_warning("unsupported sleep state 0x%x\n", sleep_state);
> > - return;
> > + return -1;
> > }
> >
> > tboot_shutdown(acpi_shutdown_map[sleep_state]);
> > -}
> > -static int tboot_sleep_wrapper(u8 sleep_state, u32 pm1a_control,
> > - u32 pm1b_control)
> > -{
> > - tboot_sleep(sleep_state, pm1a_control, pm1b_control);
> > return 0;
> > }
> >
> > @@ -352,7 +347,7 @@ static __init int tboot_late_init(void)
> > atomic_set(&ap_wfs_count, 0);
> > register_hotcpu_notifier(&tboot_cpu_notifier);
> >
> > - acpi_os_set_prepare_sleep(&tboot_sleep_wrapper);
> > + acpi_os_set_prepare_sleep(&tboot_sleep);
> > return 0;
> > }
> >
> > --
> > 1.7.7.4
^ permalink raw reply
* Re: [PATCH 0/6] RFC: CPU frequency min/max as PM QoS params
From: Antti P Miettinen @ 2012-01-12 8:43 UTC (permalink / raw)
To: linux-pm
In-Reply-To: <201201120000.17044.rjw@sisk.pl>
"Rafael J. Wysocki" <rjw@sisk.pl> writes:
> On Wednesday, January 11, 2012, Antti P Miettinen wrote:
>> I think for CPU performance, it's probably simplest just to use
>> frequency. Mapping from GOPS/MIPS/FLOPS/FPS is probably more sensily
>> done by PM QoS client side.
>
> Well, unfortunately, frequency is kind of system-specific. I mean,
> you need to know what frequencies are supported/available to use that,
> so it would require the potential users to know the CPU internals.
>
> Thanks,
> Rafael
I would expect clients requesting for computing performance to require
system specific knowledge anyway. Computing performance is often
affected by target specific details (CPU, memory, interconnects). So
something like board specific configuration parameters would probably be
required for the PM QoS clients doing computing performance requests.
--Antti
^ permalink raw reply
* Re: [PATCH 0/6] RFC: CPU frequency min/max as PM QoS params
From: Antti P Miettinen @ 2012-01-12 8:37 UTC (permalink / raw)
To: linux-pm
In-Reply-To: <201201120015.55740.rjw@sisk.pl>
"Rafael J. Wysocki" <rjw@sisk.pl> writes:
>> By blocking sleep states we can address "system level latency" or "best case
>> latency" but as far as I can see PM QoS does not address "worst case
>> latency".
>
> I'm not sure what you mean by "worst case latency".
Umm.. the usual concept. If latency is the time from stimulus to
response, this time can vary based on context. One part of the context
is the hardware state but there is also the system load. So for example
the time from interrupt to display being updated is affected by hardware
state but also system load. As far as I understand, current PM QoS
latency requests addresses hardware state but do not account for
possible resource contention, e.g. several latency sensitive clients
(device drivers, tasks) competing for CPU. In this sense minimum CPU
frequency requests would be similar.
--Antti
^ permalink raw reply
* Re: [PATCH 0/6] RFC: CPU frequency min/max as PM QoS params
From: mark gross @ 2012-01-12 3:06 UTC (permalink / raw)
To: Jean Pihet; +Cc: linux-pm, Antti P Miettinen, markgross
In-Reply-To: <CAORVsuUgL=5N1s7j3mHTzVgpq5sFO5nkotAZ1PeC=s0GfkWGwA@mail.gmail.com>
On Tue, Jan 10, 2012 at 10:02:49PM +0100, Jean Pihet wrote:
> Hi Mark, Rafael,
>
> On Tue, Jan 10, 2012 at 9:46 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > On Tuesday, January 10, 2012, mark gross wrote:
> >> On Mon, Jan 09, 2012 at 10:27:29PM +0100, Rafael J. Wysocki wrote:
> >> > On Monday, January 09, 2012, mark gross wrote:
> >> > > On Sun, Jan 08, 2012 at 11:59:24PM +0100, Rafael J. Wysocki wrote:
> >> > > > On Friday, January 06, 2012, mark gross wrote:
> >> > > > > On Fri, Jan 06, 2012 at 02:36:20AM +0200, Antti P Miettinen wrote:
> >> > > > > > The inspiration for this patch series is the N9 CPU frequency boost
> >> > > > > > upon input events:
> >> > > > > >
> >> > > > > > http://www.spinics.net/lists/cpufreq/msg00667.html
> >> > > > > >
> >> > > > > > and the related changes in git://codeaurora.org/kernel/msm.git tree.
> >> > > > > > Those patches modify the ondemand cpufreq governor. This patch series
> >> > > > > > adds minimum and maximum CPU frequency as PM QoS parameters and
> >> > > > > > modifies the cpufreq core to enforce the PM QoS limits. There is also
> >> > > > > > an example module for boosting the frequency upon input events.
> >> > > > > >
> >> > > > > > I've been testing these changes against Ubuntu 3.2 kernel on a Dell
> >> > > > > > E6420 with the ACPI cpufreq driver. The patches are against
> >> > > > > > linux-next/master, compile tested against it.
> >> > > > > >
> >> > > > > > --Antti
> >> > > > > >
> >> > > > > > Alex Frid (1):
> >> > > > > > PM QoS: Simplify PM QoS expansion/merge
> >> > > > > >
> >> > > > > > Antti P Miettinen (5):
> >> > > > > > PM QoS: Add CPU frequency min/max as PM QoS params
> >> > > > > > cpufreq: Export user_policy min/max
> >> > > > > > cpufreq: Preserve sysfs min/max request
> >> > > > > > cpufreq: Enforce PM QoS min/max limits
> >> > > > > > input: CPU frequency booster
> >> > > > > >
> >> > > > > > drivers/cpufreq/cpufreq.c | 57 +++++++++++++-
> >> > > > > > drivers/input/Kconfig | 9 ++
> >> > > > > > drivers/input/Makefile | 1 +
> >> > > > > > drivers/input/input-cfboost.c | 174 +++++++++++++++++++++++++++++++++++++++++
> >> > > > > > include/linux/pm_qos.h | 19 ++++-
> >> > > > > > kernel/power/qos.c | 55 ++++++++++----
> >> > > > > > 6 files changed, 293 insertions(+), 22 deletions(-)
> >> > > > > > create mode 100644 drivers/input/input-cfboost.c
> >> > > > > >
> >> > > > >
> >> > > > > The following is my version of part of this patch set I was tinkering
> >> > > > > with. Its missing the cpufreq notification this change has and doesn't
> >> > > > > do anything WRT cfboost.
> >> > > > >
> >> > > > > Would it be ok if we could consolidate our two implementations and
> >> > > > > completely separate the cfboost stuff as a separate patch set?
> >> > > > >
> >> > > > > My code below is missing the cpufreq notification logic you have.
> >> > > >
> >> > > > Well, I have one substantial problem with this approach. Namely, our
> >> > > > current PM QoS infrastructure is not suitable for throughput constraints,
> >> > > > because they should be additive, unlike the latency ones.
> >> > > >
> >> > > > Namely, if sombody requests throughput X and someone else Y, the resulting
> >> > > > combined throughput should be X+Y rather than max(X, Y).
> >> > >
> >> > > That can be done easy enough. However; in practice I'm not convinced
> >> > > doing and additive aggregation of the requested QoS would be any better
> >> > > than just taking the max.
> >> >
> >> > Well, I'd say it's necessary for correctness, perhaps not for the CPU, but in
> >> > general. If Y is the max, then the subsystem that requested X may easily
> >> > starve whoever requested the Y by using all of the bandwidth it asked for.
> >>
> >> I was thinking about this from the CPU point of view more over the day.
> >> Given that there are many times more than one make the qos requests
> >> additive will result in quickly requesting more cpu than is available
> >> and waisting a lot of power. Also additive aggregation falls over a
> >> bit on with multi-core.
> >>
> >> As the consumer of the cpu resources are tasks, and we can only run one
> >> task at a time on a cpu, I'm talking myself into thinking that max
> >> *is* the right way to go for cpu throughput (i.e. frequency).
> There are case where the constraints values should be additive. The
> best example is the main memory throughput and so the memory
> controller frequency (or the L3 frequency on OMAP). The main problem
> is to estimate the overhead of multiple simultaneous transfers.
>
> What do you think?
I think the number of that get summed in you memory bus example needs to
be tied to the number of DMA engines + CPU cores that can concurrently
transfer on that bus. To sum all the request I think is too simplistic
and will result in always maxing aggregate request
--mark
>
> >
> > I agree, but I wonder what units of throughput should be used in that case?
> >
> > Rafael
>
> Regards,
> Jean
>
> > _______________________________________________
> > linux-pm mailing list
> > linux-pm@lists.linux-foundation.org
> > https://lists.linuxfoundation.org/mailman/listinfo/linux-pm
^ permalink raw reply
* Re: [PATCH 0/6] RFC: CPU frequency min/max as PM QoS params
From: mark gross @ 2012-01-12 3:01 UTC (permalink / raw)
To: Rafael J. Wysocki; +Cc: linux-pm, Antti P Miettinen, markgross
In-Reply-To: <201201102146.23001.rjw@sisk.pl>
On Tue, Jan 10, 2012 at 09:46:22PM +0100, Rafael J. Wysocki wrote:
> On Tuesday, January 10, 2012, mark gross wrote:
> > On Mon, Jan 09, 2012 at 10:27:29PM +0100, Rafael J. Wysocki wrote:
> > > On Monday, January 09, 2012, mark gross wrote:
> > > > On Sun, Jan 08, 2012 at 11:59:24PM +0100, Rafael J. Wysocki wrote:
> > > > > On Friday, January 06, 2012, mark gross wrote:
> > > > > > On Fri, Jan 06, 2012 at 02:36:20AM +0200, Antti P Miettinen wrote:
> > > > > > > The inspiration for this patch series is the N9 CPU frequency boost
> > > > > > > upon input events:
> > > > > > >
> > > > > > > http://www.spinics.net/lists/cpufreq/msg00667.html
> > > > > > >
> > > > > > > and the related changes in git://codeaurora.org/kernel/msm.git tree.
> > > > > > > Those patches modify the ondemand cpufreq governor. This patch series
> > > > > > > adds minimum and maximum CPU frequency as PM QoS parameters and
> > > > > > > modifies the cpufreq core to enforce the PM QoS limits. There is also
> > > > > > > an example module for boosting the frequency upon input events.
> > > > > > >
> > > > > > > I've been testing these changes against Ubuntu 3.2 kernel on a Dell
> > > > > > > E6420 with the ACPI cpufreq driver. The patches are against
> > > > > > > linux-next/master, compile tested against it.
> > > > > > >
> > > > > > > --Antti
> > > > > > >
> > > > > > > Alex Frid (1):
> > > > > > > PM QoS: Simplify PM QoS expansion/merge
> > > > > > >
> > > > > > > Antti P Miettinen (5):
> > > > > > > PM QoS: Add CPU frequency min/max as PM QoS params
> > > > > > > cpufreq: Export user_policy min/max
> > > > > > > cpufreq: Preserve sysfs min/max request
> > > > > > > cpufreq: Enforce PM QoS min/max limits
> > > > > > > input: CPU frequency booster
> > > > > > >
> > > > > > > drivers/cpufreq/cpufreq.c | 57 +++++++++++++-
> > > > > > > drivers/input/Kconfig | 9 ++
> > > > > > > drivers/input/Makefile | 1 +
> > > > > > > drivers/input/input-cfboost.c | 174 +++++++++++++++++++++++++++++++++++++++++
> > > > > > > include/linux/pm_qos.h | 19 ++++-
> > > > > > > kernel/power/qos.c | 55 ++++++++++----
> > > > > > > 6 files changed, 293 insertions(+), 22 deletions(-)
> > > > > > > create mode 100644 drivers/input/input-cfboost.c
> > > > > > >
> > > > > >
> > > > > > The following is my version of part of this patch set I was tinkering
> > > > > > with. Its missing the cpufreq notification this change has and doesn't
> > > > > > do anything WRT cfboost.
> > > > > >
> > > > > > Would it be ok if we could consolidate our two implementations and
> > > > > > completely separate the cfboost stuff as a separate patch set?
> > > > > >
> > > > > > My code below is missing the cpufreq notification logic you have.
> > > > >
> > > > > Well, I have one substantial problem with this approach. Namely, our
> > > > > current PM QoS infrastructure is not suitable for throughput constraints,
> > > > > because they should be additive, unlike the latency ones.
> > > > >
> > > > > Namely, if sombody requests throughput X and someone else Y, the resulting
> > > > > combined throughput should be X+Y rather than max(X, Y).
> > > >
> > > > That can be done easy enough. However; in practice I'm not convinced
> > > > doing and additive aggregation of the requested QoS would be any better
> > > > than just taking the max.
> > >
> > > Well, I'd say it's necessary for correctness, perhaps not for the CPU, but in
> > > general. If Y is the max, then the subsystem that requested X may easily
> > > starve whoever requested the Y by using all of the bandwidth it asked for.
> >
> > I was thinking about this from the CPU point of view more over the day.
> > Given that there are many times more than one make the qos requests
> > additive will result in quickly requesting more cpu than is available
> > and waisting a lot of power. Also additive aggregation falls over a
> > bit on with multi-core.
> >
> > As the consumer of the cpu resources are tasks, and we can only run one
> > task at a time on a cpu, I'm talking myself into thinking that max
> > *is* the right way to go for cpu throughput (i.e. frequency).
>
> I agree, but I wonder what units of throughput should be used in that case?
I was thinking of using the same units that cpufreq works in.
--mark
^ permalink raw reply
* Re: [PATCH 0/6] RFC: CPU frequency min/max as PM QoS params
From: Rafael J. Wysocki @ 2012-01-11 23:15 UTC (permalink / raw)
To: Antti P Miettinen; +Cc: linux-pm
In-Reply-To: <87vcoid7j5.fsf@amiettinen-lnx.nvidia.com>
On Wednesday, January 11, 2012, Antti P Miettinen wrote:
> "Rafael J. Wysocki" <rjw@sisk.pl> writes:
> > On Monday, January 09, 2012, Antti P Miettinen wrote:
> >> Hmm.. congestion is an issue for latency requests as well.
> >
> > I'm not sure what you mean. Care to elaborate?
> >
> > Rafael
>
> Well, I was just thinking that latencies can get hurt by system load
> just like throughput can suffer from load.
The idea with latencies is different. Latency constraints specify how
much time a given resource may be unavailable (due to power management).
So, when putting the resource into a low-power state we only need to
consider the minimum of those.
> By blocking sleep states we can address "system level latency" or "best case
> latency" but as far as I can see PM QoS does not address "worst case
> latency".
I'm not sure what you mean by "worst case latency".
Thanks,
Rafael
^ permalink raw reply
* Re: [PATCH 0/6] RFC: CPU frequency min/max as PM QoS params
From: Rafael J. Wysocki @ 2012-01-11 23:00 UTC (permalink / raw)
To: Antti P Miettinen; +Cc: linux-pm
In-Reply-To: <87r4z6d784.fsf@amiettinen-lnx.nvidia.com>
On Wednesday, January 11, 2012, Antti P Miettinen wrote:
> Jean Pihet <jean.pihet@newoldbits.com> writes:
> > There are case where the constraints values should be additive. The
> > best example is the main memory throughput and so the memory
> > controller frequency (or the L3 frequency on OMAP). The main problem
> > is to estimate the overhead of multiple simultaneous transfers.
> >
> > What do you think?
>
> This is a valid point. What tree/branch should I look at for the OMAP L3
> PM QoS?
>
> I think for CPU performance, it's probably simplest just to use
> frequency. Mapping from GOPS/MIPS/FLOPS/FPS is probably more sensily
> done by PM QoS client side.
Well, unfortunately, frequency is kind of system-specific. I mean,
you need to know what frequencies are supported/available to use that,
so it would require the potential users to know the CPU internals.
Thanks,
Rafael
^ permalink raw reply
* Re: [PATCH 4/6] cpufreq: Preserve sysfs min/max request
From: Antti P Miettinen @ 2012-01-11 21:56 UTC (permalink / raw)
To: linux-pm; +Cc: cpufreq
In-Reply-To: <1325844234-478-5-git-send-email-amiettinen@nvidia.com>
Any comments to this change?
Antti P Miettinen <amiettinen@nvidia.com> writes:
> Store the value received via sysfs as the user_policy
> min/max value instead of the currently enforced min/max.
> This allows restoring the user min/max values when
> constraints on enforced min/max change.
>
> Signed-off-by: Antti P Miettinen <amiettinen@nvidia.com>
> ---
> drivers/cpufreq/cpufreq.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> index e63b29f..65a512b 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -389,7 +389,7 @@ static ssize_t store_##file_name \
> return -EINVAL; \
> \
> ret = __cpufreq_set_policy(policy, &new_policy); \
> - policy->user_policy.object = policy->object; \
> + policy->user_policy.object = new_policy.object; \
> \
> return ret ? ret : count; \
> }
--Antti
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox