* Re: sysrq-o broken since 2.6.38
From: Rafael J. Wysocki @ 2012-01-08 21:35 UTC (permalink / raw)
To: Phil Oester; +Cc: linux-pm
In-Reply-To: <201201042352.59710.rjw@sisk.pl>
On Wednesday, January 04, 2012, Rafael J. Wysocki wrote:
> On Wednesday, January 04, 2012, Phil Oester wrote:
> > In commit 1eb208ae [PM: Make CONFIG_PM depend on (CONFIG_PM_SLEEP || CONFIG_PM_RUNTIME)],
> > sysrq-o option no longer works unless PM_SLEEP or PM_RUNTIME is enabled. I doubt
> > this was an intended consequence of this change. Could someone confirm?
>
> No, it wasn't.
>
> I'll try to find out what the problem is.
I don't really see what the problem is right now and I'm unable to reproduce it
on the boxes available to me at the moment.
Please send your .config.
Thanks,
Rafael
^ permalink raw reply
* Re: [PATCH v2] PM: HIBERNATION: skip the swap size check if the snapshot image size is anticipative
From: Rafael J. Wysocki @ 2012-01-08 21:31 UTC (permalink / raw)
To: Barry Song
Cc: Xiangzhen Ye, linux-kernel, workgroup.linux, linux-arm-kernel,
Barry Song, linux-pm
In-Reply-To: <CAGsJ_4ypEKZLXf0KU81=dRADcxesxKVyqg0UnEKGaxthNMZQ-g@mail.gmail.com>
On Friday, January 06, 2012, Barry Song wrote:
> 2012/1/6 Pavel Machek <pavel@ucw.cz>:
> > Hi!
> >
> > Is the check even useful these days? Should we remove it altogether?
>
> i think we can let users or distributions decide whether it is useful.
> On PC, disk space is not an issue, people might run many applications
> while doing hibernation, so snapshot is much big. an early check will
> improve user experience because people don't need to wait a long time
> and find space is not enough.
> for embedded system, SoC solutions can know whether the space is
> enough since they know what are running while doing hibernation, so
> they can skip the check by setting the flag in sysfs.
> that is why i had this patch sent.
I agree with Pavel that it's better to drop the check altogether.
The sysfs switch you're adding doesn't seem to be very useful, as PC
users won't touch it and whoever needs it to be 0, will always set it
that way and won't change it afterwards.
Thanks,
Rafael
> >> 2011/11/25 Barry Song <Barry.Song@csr.com>:
> >> > From: Barry Song <baohua.song@csr.com>
> >> >
> >> > Current swsusp requires swap partitions even larger than real saved pages
> >> > based on the worst compression ratio:
> >> > but for an embedded system, which has limited storage space, then it might
> >> > can't give the large partition to save snapshot.
> >> > In the another way, some embedded systems can definitely know the most size
> >> > needed for snapshot since they run some specific application lists.
> >> > So this patch provides the possibility for users to tell kernel even
> >> > the system has a little snapshot partition, but it is still enough.
> >> > For example, if the system need to save 120MB memory, origin swsusp will require
> >> > a 130MB partition to save snapshot. but if users know 30MB is enough for them(
> >> > compressed image will be less than 30MB), they just make a 30MB partition by
> >> > echo 0 > /sys/power/check_swap_size
> >> >
> >> > Signed-off-by: Barry Song <Baohua.Song@csr.com>
> >> > Cc: Xiangzhen Ye <Xiangzhen.Ye@csr.com>
> >> > ---
> >> > -v2:drop swap_enough bootargs and use /sys/power/check_swap_size node
> >> >
> >> > Documentation/power/interface.txt | 5 +++++
> >> > kernel/power/hibernate.c | 22 ++++++++++++++++++++++
> >> > kernel/power/power.h | 2 ++
> >> > kernel/power/swap.c | 9 +++++++++
> >> > 4 files changed, 38 insertions(+), 0 deletions(-)
> >> >
> >> > diff --git a/Documentation/power/interface.txt b/Documentation/power/interface.txt
> >> > index c537834..5e205f0 100644
> >> > --- a/Documentation/power/interface.txt
> >> > +++ b/Documentation/power/interface.txt
> >> > @@ -47,6 +47,11 @@ Writing to this file will accept one of
> >> > 'testproc'
> >> > 'test'
> >> >
> >> > +/sys/power/check_swap_size controls whether we can skip checking the swap
> >> > +partition size by worst compression ratio. If users know the swap partition
> >> > +is enough for compressed snapshot, write 0 to /sys/power/check_swap_size.
> >> > +It is useful for an embedded system with known running softwares.
> >> > +
> >> > /sys/power/image_size controls the size of the image created by
> >> > the suspend-to-disk mechanism. It can be written a string
> >> > representing a non-negative integer that will be used as an upper
> >> > diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
> >> > index 1c53f7f..5552473 100644
> >> > --- a/kernel/power/hibernate.c
> >> > +++ b/kernel/power/hibernate.c
> >> > @@ -1024,11 +1024,33 @@ static ssize_t reserved_size_store(struct kobject *kobj,
> >> >
> >> > power_attr(reserved_size);
> >> >
> >> > +static ssize_t check_swap_size_show(struct kobject *kobj, struct kobj_attribute *attr,
> >> > + char *buf)
> >> > +{
> >> > + return sprintf(buf, "%d\n", check_swap_size);
> >> > +}
> >> > +
> >> > +static ssize_t check_swap_size_store(struct kobject *kobj, struct kobj_attribute *attr,
> >> > + const char *buf, size_t n)
> >> > +{
> >> > + int check_size;
> >> > +
> >> > + if (sscanf(buf, "%d", &check_size) == 1) {
> >> > + check_swap_size = check_size;
> >> > + return n;
> >> > + }
> >> > +
> >> > + return -EINVAL;
> >> > +}
> >> > +
> >> > +power_attr(check_swap_size);
> >> > +
> >> > static struct attribute * g[] = {
> >> > &disk_attr.attr,
> >> > &resume_attr.attr,
> >> > &image_size_attr.attr,
> >> > &reserved_size_attr.attr,
> >> > + &check_swap_size_attr.attr,
> >> > NULL,
> >> > };
> >> >
> >> > diff --git a/kernel/power/power.h b/kernel/power/power.h
> >> > index 23a2db1..4f0fa78 100644
> >> > --- a/kernel/power/power.h
> >> > +++ b/kernel/power/power.h
> >> > @@ -74,6 +74,8 @@ static struct kobj_attribute _name##_attr = { \
> >> >
> >> > /* Preferred image size in bytes (default 500 MB) */
> >> > extern unsigned long image_size;
> >> > +/* If 0, skip checking whether the swap size is enough for compressed snapshot */
> >> > +extern int check_swap_size;
> >> > /* Size of memory reserved for drivers (default SPARE_PAGES x PAGE_SIZE) */
> >> > extern unsigned long reserved_size;
> >> > extern int in_suspend;
> >> > diff --git a/kernel/power/swap.c b/kernel/power/swap.c
> >> > index 11a594c..db90195 100644
> >> > --- a/kernel/power/swap.c
> >> > +++ b/kernel/power/swap.c
> >> > @@ -37,6 +37,12 @@
> >> > #define HIBERNATE_SIG "S1SUSPEND"
> >> >
> >> > /*
> >> > + * if users know swap partitions are enough for compressed snapshots,
> >> > + * echo 0 > /sys/power/check_swap_size
> >> > + */
> >> > +int check_swap_size = 1;
> >> > +
> >> > +/*
> >> > * The swap map is a data structure used for keeping track of each page
> >> > * written to a swap partition. It consists of many swap_map_page
> >> > * structures that contain each an array of MAP_PAGE_ENTRIES swap entries.
> >> > @@ -772,6 +778,9 @@ static int enough_swap(unsigned int nr_pages, unsigned int flags)
> >> > unsigned int free_swap = count_swap_pages(root_swap, 1);
> >> > unsigned int required;
> >> >
> >> > + if (!check_swap_size)
> >> > + return 1;
> >> > +
> >> > pr_debug("PM: Free swap pages: %u\n", free_swap);
> >> >
> >> > required = PAGES_FOR_IO + ((flags & SF_NOCOMPRESS_MODE) ?
> >> > --
> >> > 1.7.1
> >
> -barry
>
>
^ permalink raw reply
* Re: [PATCH 2/6] PM QoS: Add CPU frequency min/max as PM QoS params
From: Antti P Miettinen @ 2012-01-07 8:54 UTC (permalink / raw)
To: markgross; +Cc: linux-pm
In-Reply-To: <20120107034746.GB3119@mgross-G62>
From: mark gross <markgross@thegnar.org>
> On Fri, Jan 06, 2012 at 09:32:36PM +0200, Antti P Miettinen wrote:
>> mark gross <markgross@thegnar.org> writes:
[..]
>> > You should only have a cpu throughput qos. I.e. FREQ_MIN.
>> > FWIW in my patch I named it : PM_QOS_CPU_THROUGHPUT but, its just a
>> > different name to your PM_QOS_CPU_FREQ_MIN name.
>>
>> I anticipated getting this comment :-)
>
> I'm glad. Say did we talk at plumbers last year? This is starting to
> ring a bell.
Sorry - no, I've never been to plumbers :-)
> yes, there are a lot of interesting things one can do to attempt to
> somewhat gracefully deal with some sort of power or thermal envelope
> limitations. But, they are not PM_QoS.
Well - I'd say level of energy efficiency could easily be called PM
QoS, but taking the max out is easy enough.
--Antti
^ permalink raw reply
* Re: [PATCH 3/6] cpufreq: Export user_policy min/max
From: Antti P Miettinen @ 2012-01-07 8:47 UTC (permalink / raw)
To: markgross; +Cc: linux-pm, cpufreq
In-Reply-To: <20120107035328.GC3119@mgross-G62>
From: mark gross <markgross@thegnar.org>
> Maybe I'm missing something but cpufreq already has ABI for setting
> upper and lower bounds for frequencies.
>
> /sys/devices/system/cpu/cpu0/cpufreq/[scaling_min_freq,
> scaling_max_freq]
>
> --mark
Yes, and the patch just adds two read-only files,
/sys/devices/system/cpu/cpu?/cpufreq/policy_{min,max}_freq:
+show_one(policy_min_freq, user_policy.min);
+show_one(policy_max_freq, user_policy.max);
to show the user_policy.min/max in addition to the
policy->min/max. This is related to patch 4 which changes the
scaling_{min,max}_freq store function to store the received value to
user_policy instead of the enforced value. Related in turn to the
restoring of the policy values when PM QoS constraints get lifted. The
purpose of patch 3 is to allow inspecting the requested min/max in
addition to the enforced min/max.
--Antti
Adding cpufreq to cc, previous comments for context:
http://thread.gmane.org/gmane.linux.power-management.general/26532
^ permalink raw reply
* Re: [PATCH 3/6] cpufreq: Export user_policy min/max
From: mark gross @ 2012-01-07 3:53 UTC (permalink / raw)
To: ananaza; +Cc: linux-pm
In-Reply-To: <20120106.212926.720061341805749024.apm@brigitte.kvy.fi>
On Fri, Jan 06, 2012 at 09:29:26PM +0200, Antti P Miettinen wrote:
> [seems that posting via gmane is broken - resenting manually via mail
> - sorry if you get duplicates]
>
> mark gross <markgross@thegnar.org> writes:
> > Why do you need to export these values here and from the pmqos ABI?
> >
> > I don't think we want this change. Also, isn't it redundant WRT
> > existing CPU freq govoner sysfs output?
> >
> > --mark
>
> Hmm.. what do you mean by pmqos ABI? This is related to patch 4. Nothing
> critical, just an addition to be able to see the user_policy min/max in
> addition to the policy min/max. It's not redundant, it's an
> addition. Might be useful for e.g. tests.
Maybe I'm missing something but cpufreq already has ABI for setting
upper and lower bounds for frequencies.
/sys/devices/system/cpu/cpu0/cpufreq/[scaling_min_freq,
scaling_max_freq]
--mark
^ permalink raw reply
* Re: [PATCH 2/6] PM QoS: Add CPU frequency min/max as PM QoS params
From: mark gross @ 2012-01-07 3:47 UTC (permalink / raw)
To: ananaza; +Cc: linux-pm
In-Reply-To: <20120106.213236.1775053150950189700.apm@brigitte.kvy.fi>
On Fri, Jan 06, 2012 at 09:32:36PM +0200, Antti P Miettinen wrote:
> [seems that posting via gmane is broken - resenting manually via mail
> - sorry if you get duplicates]
>
> mark gross <markgross@thegnar.org> writes:
> > On Fri, Jan 06, 2012 at 02:36:22AM +0200, Antti P Miettinen wrote:
> [..]
> >> diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h
> >> index 5ac91d8..7b8d08b 100644
> >> --- a/include/linux/pm_qos.h
> >> +++ b/include/linux/pm_qos.h
> >> @@ -14,8 +14,11 @@ enum {
> >> PM_QOS_CPU_DMA_LATENCY,
> >> PM_QOS_NETWORK_LATENCY,
> >> PM_QOS_NETWORK_THROUGHPUT,
> >> + PM_QOS_CPU_FREQ_MIN,
> >> + PM_QOS_CPU_FREQ_MAX,
> > What is this about? How sould freq_max make any sense in the context of
> > constraining power mangement throutling? this is wrong.
> >
> > You should only have a cpu throughput qos. I.e. FREQ_MIN.
> > FWIW in my patch I named it : PM_QOS_CPU_THROUGHPUT but, its just a
> > different name to your PM_QOS_CPU_FREQ_MIN name.
>
> I anticipated getting this comment :-)
I'm glad. Say did we talk at plumbers last year? This is starting to
ring a bell.
> I originally added the max just for symmetry. But it could actually be
> useful for e.g. requesting a minimum level of energy efficiency. If your
> workload keeps CPU busy but does not need any specific throughput and
> energy is more critical to you, by limiting the maximum frequency you
> can request a level of energy efficiency (provided that the platform
> DVFS works in a sensible way). Max frequency could be useful also for
> thermal management.
yes, there are a lot of interesting things one can do to attempt to
somewhat gracefully deal with some sort of power or thermal envelope
limitations. But, they are not PM_QoS.
>
> Also, I think general "PM constraints" would be useful, not just
> "minimum level of service" requests so why not extend PM QoS towards a
> generic PM constraints framework?
I think you need to change the name of what you are talking about to
"operational envelopes" or "operational constraints" and not try to
attach it onto pm_qos. FWIW: I like "envelopes".
The problem always comes down to not giving the user what is asked
and how to deal with that in a way that doesn't make the device seem
defective.
For instance: Consider thermal envelopes Your watching a video on a
device and its getting hot but, not critical, yet. What do you do?
When do you do it?
You can dim the display, (but the user may turn it back up)
You can turn down the audio, (but the user may turn it back up)
You can current limit any charging (if charging is happening at that
time)
You can start closing files or rate limit the data going to user mode.
You can inject cpuidle for a fraction of every millisecond (or some PWM
like idle injection scheme)
You can stop the processes that are keeping the CPU / GPU busy.
Or you can simply shutdown or suspend the device because its hit a
thermal trigger point and needs a time out.
Another case is you have a battery powered device and the battery is
getting low such that the device will brown out if you light up the
screen or run the vibrator. How best to deal with this?
Most times its: tell the user battery is critical and shut down.
If there was a nice way to tell the user we are in low battery mode and
only critical operations are allowed then we could do something.
You can also consider a runtime PM like thing where devices are kept in
D1 (or lower) and to get to D0 they need to ask if the system can handle
the registered maxed out D0 state of the device.
But, you need a way to identify and exempt from this policy those
devices and processes processes are critical or won't dead lock the
system if you stop scheduling them or stop letting them go to D0.
Also I'm overlooking the problem of modeling system power needs and
measuring of instantaneous load. Not simple.
There is no infrastructure to deal with such limitations or operational
envelopes today. And there may never be a good way to let the user
down.
This is a challenging and interesting problem that will take touching a
lot of the kernel.
But, it is not pm_qos... IMO.
--mark
^ permalink raw reply
* Re: [PATCH 0/6] RFC: CPU frequency min/max as PM QoS params
From: mark gross @ 2012-01-07 2:57 UTC (permalink / raw)
To: ananaza; +Cc: linux-pm
In-Reply-To: <20120106.213839.2153351629911262951.apm@brigitte.kvy.fi>
On Fri, Jan 06, 2012 at 09:38:39PM +0200, Antti P Miettinen wrote:
> [seems that posting via gmane is broken - resending (heehee - I do
> resent the gmane problem :) manually via mail - sorry if you get
> duplicates]
FWIW I've been having odd email behavior WRT linux-pm. I'm not sure if
its my .procmailrc file or something else.
> mark gross <markgross@thegnar.org> writes:
> > diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> > index 987a165..4cbd58b 100644
> > --- a/drivers/cpufreq/cpufreq.c
> > +++ b/drivers/cpufreq/cpufreq.c
> [..]
> > +
> > + if (policy->min < pm_qos_request(PM_QOS_CPU_THROUGHPUT))
> > + policy->min = pm_qos_request(PM_QOS_CPU_THROUGHPUT);
> >
>
> Consider the following sequence
>
> - say original min is 100MHz
> - PM QoS requests 1GHz minimum
> - user requests 500MHz minimum via sysfs
> - PM QoS request is canceled
>
> After this the policy->min will be 1GHz. I'm not really happy with the
> min/max save/restore etc but something is needed to enable restoring the
> policy min/max when PM QoS constraints dissappear.
you are right. If CPUFREQ is to be QoS aware we need to have it save
the request from user mode and compute the max between the user request
and the pm_qos constraint.
--mark
^ permalink raw reply
* Re: [PATCH 0/6] RFC: CPU frequency min/max as PM QoS params
From: Antti P Miettinen @ 2012-01-06 19:38 UTC (permalink / raw)
To: linux-pm
In-Reply-To: <20120106154613.GI12530@mgross-G62>
[seems that posting via gmane is broken - resending (heehee - I do
resent the gmane problem :) manually via mail - sorry if you get
duplicates]
mark gross <markgross@thegnar.org> writes:
> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> index 987a165..4cbd58b 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
[..]
> +
> + if (policy->min < pm_qos_request(PM_QOS_CPU_THROUGHPUT))
> + policy->min = pm_qos_request(PM_QOS_CPU_THROUGHPUT);
>
Consider the following sequence
- say original min is 100MHz
- PM QoS requests 1GHz minimum
- user requests 500MHz minimum via sysfs
- PM QoS request is canceled
After this the policy->min will be 1GHz. I'm not really happy with the
min/max save/restore etc but something is needed to enable restoring the
policy min/max when PM QoS constraints dissappear.
--Antti
^ permalink raw reply
* Re: [PATCH 2/6] PM QoS: Add CPU frequency min/max as PM QoS params
From: Antti P Miettinen @ 2012-01-06 19:32 UTC (permalink / raw)
To: linux-pm
In-Reply-To: <20120106153027.GE12530@mgross-G62>
[seems that posting via gmane is broken - resenting manually via mail
- sorry if you get duplicates]
mark gross <markgross@thegnar.org> writes:
> On Fri, Jan 06, 2012 at 02:36:22AM +0200, Antti P Miettinen wrote:
[..]
>> diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h
>> index 5ac91d8..7b8d08b 100644
>> --- a/include/linux/pm_qos.h
>> +++ b/include/linux/pm_qos.h
>> @@ -14,8 +14,11 @@ enum {
>> PM_QOS_CPU_DMA_LATENCY,
>> PM_QOS_NETWORK_LATENCY,
>> PM_QOS_NETWORK_THROUGHPUT,
>> + PM_QOS_CPU_FREQ_MIN,
>> + PM_QOS_CPU_FREQ_MAX,
> What is this about? How sould freq_max make any sense in the context of
> constraining power mangement throutling? this is wrong.
>
> You should only have a cpu throughput qos. I.e. FREQ_MIN.
> FWIW in my patch I named it : PM_QOS_CPU_THROUGHPUT but, its just a
> different name to your PM_QOS_CPU_FREQ_MIN name.
I anticipated getting this comment :-)
I originally added the max just for symmetry. But it could actually be
useful for e.g. requesting a minimum level of energy efficiency. If your
workload keeps CPU busy but does not need any specific throughput and
energy is more critical to you, by limiting the maximum frequency you
can request a level of energy efficiency (provided that the platform
DVFS works in a sensible way). Max frequency could be useful also for
thermal management.
Also, I think general "PM constraints" would be useful, not just
"minimum level of service" requests so why not extend PM QoS towards a
generic PM constraints framework?
--Antti
^ permalink raw reply
* Re: [PATCH 3/6] cpufreq: Export user_policy min/max
From: Antti P Miettinen @ 2012-01-06 19:29 UTC (permalink / raw)
To: linux-pm
In-Reply-To: <20120106153320.GF12530@mgross-G62>
[seems that posting via gmane is broken - resenting manually via mail
- sorry if you get duplicates]
mark gross <markgross@thegnar.org> writes:
> Why do you need to export these values here and from the pmqos ABI?
>
> I don't think we want this change. Also, isn't it redundant WRT
> existing CPU freq govoner sysfs output?
>
> --mark
Hmm.. what do you mean by pmqos ABI? This is related to patch 4. Nothing
critical, just an addition to be able to see the user_policy min/max in
addition to the policy min/max. It's not redundant, it's an
addition. Might be useful for e.g. tests.
--Antti
> On Fri, Jan 06, 2012 at 02:36:23AM +0200, Antti P Miettinen wrote:
>> 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(-)
^ permalink raw reply
* Re: [PATCH 0/6] RFC: CPU frequency min/max as PM QoS params
From: mark gross @ 2012-01-06 18:27 UTC (permalink / raw)
To: Antti P Miettinen; +Cc: linux-pm
In-Reply-To: <1325810186-28986-1-git-send-email-amiettinen@nvidia.com>
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
>
> --
> 1.7.4.1
>
> _______________________________________________
> linux-pm mailing list
> linux-pm@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/linux-pm
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.
--mark
Signed-off-by: markgross <markgross@thegnar.org>
>From b4be99354c5af20cbd4041cddd6038e2353e06b4 Mon Sep 17 00:00:00 2001
>From: mgross <mgross@mini>
>Date: Sat, 24 Dec 2011 13:40:03 -0800
>Subject: [PATCH] Some devices have a subtle relationship with the CPU
throughput and need to set a minimum cpu frequency en order
for the device to not experience performance issues with
buffer under runs because the cpu was throttled too much to
be able to keep the buffers full enough.
One graphics benchmark has shown this issue on Intel SOC devices. The
graphics part ends up waiting on the cpu to fill the open GL instruction
queue between frames and thus graphic performance suffers because of the
cpu throttling because the CPU really isn't very busy while running the
benchmark.
---
drivers/cpufreq/cpufreq.c | 8 ++++++++
include/linux/pm_qos.h | 8 +++++---
kernel/power/qos.c | 19 +++++++++++++++++++
3 files changed, 32 insertions(+), 3 deletions(-)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 987a165..4cbd58b 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>
@@ -1629,6 +1630,9 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data,
pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
policy->min, policy->max);
+
+ if (policy->min < pm_qos_request(PM_QOS_CPU_THROUGHPUT))
+ policy->min = pm_qos_request(PM_QOS_CPU_THROUGHPUT);
memcpy(&policy->cpuinfo, &data->cpuinfo,
sizeof(struct cpufreq_cpuinfo));
@@ -1736,6 +1740,10 @@ int cpufreq_update_policy(unsigned int cpu)
policy.policy = data->user_policy.policy;
policy.governor = data->user_policy.governor;
+ if (policy.min < pm_qos_request(PM_QOS_CPU_THROUGHPUT))
+ policy.min = pm_qos_request(PM_QOS_CPU_THROUGHPUT);
+
+
/* BIOS might change freq behind our back
-> ask driver for current freq and notify governors about a change */
if (cpufreq_driver->get) {
diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h
index 83b0ea3..ead081c 100644
--- a/include/linux/pm_qos.h
+++ b/include/linux/pm_qos.h
@@ -11,13 +11,15 @@
#define PM_QOS_RESERVED 0
#define PM_QOS_CPU_DMA_LATENCY 1
-#define PM_QOS_NETWORK_LATENCY 2
-#define PM_QOS_NETWORK_THROUGHPUT 3
+#define PM_QOS_CPU_THROUGHPUT 2
+#define PM_QOS_NETWORK_LATENCY 3
+#define PM_QOS_NETWORK_THROUGHPUT 4
-#define PM_QOS_NUM_CLASSES 4
+#define PM_QOS_NUM_CLASSES 5
#define PM_QOS_DEFAULT_VALUE -1
#define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC)
+#define PM_QOS_CPU_THROUGHPUT_DEFAULT_VALUE 0
#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
diff --git a/kernel/power/qos.c b/kernel/power/qos.c
index 995e3bd..92951fa 100644
--- a/kernel/power/qos.c
+++ b/kernel/power/qos.c
@@ -60,6 +60,19 @@ static DEFINE_SPINLOCK(pm_qos_lock);
static struct pm_qos_object null_pm_qos;
+static BLOCKING_NOTIFIER_HEAD(cpu_throughput_notifier);
+static struct pm_qos_constraints cpu_throughput_constraints = {
+ .list = PLIST_HEAD_INIT(cpu_throughput_constraints.list),
+ .target_value = PM_QOS_CPU_THROUGHPUT_DEFAULT_VALUE,
+ .default_value = PM_QOS_CPU_THROUGHPUT_DEFAULT_VALUE,
+ .type = PM_QOS_MIN,
+ .notifiers = &cpu_throughput_notifier,
+};
+static struct pm_qos_object cpu_throughput_pm_qos = {
+ .constraints = &cpu_throughput_constraints,
+ .name = "cpu_throughput",
+};
+
static BLOCKING_NOTIFIER_HEAD(cpu_dma_lat_notifier);
static struct pm_qos_constraints cpu_dma_constraints = {
.list = PLIST_HEAD_INIT(cpu_dma_constraints.list),
@@ -104,6 +117,7 @@ static struct pm_qos_object network_throughput_pm_qos = {
static struct pm_qos_object *pm_qos_array[] = {
&null_pm_qos,
&cpu_dma_pm_qos,
+ &cpu_throughput_pm_qos,
&network_lat_pm_qos,
&network_throughput_pm_qos
};
@@ -475,6 +489,11 @@ static int __init pm_qos_power_init(void)
printk(KERN_ERR "pm_qos_param: cpu_dma_latency setup failed\n");
return ret;
}
+ ret = register_pm_qos_misc(&cpu_throughput_pm_qos);
+ if (ret < 0) {
+ printk(KERN_ERR "pm_qos_param: cpu_throughput 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");
--
1.7.5.4
^ permalink raw reply related
* Re: [PATCH 0/6] RFC: CPU frequency min/max as PM QoS params
From: mark gross @ 2012-01-06 15:46 UTC (permalink / raw)
To: Antti P Miettinen; +Cc: linux-pm
In-Reply-To: <1325810186-28986-1-git-send-email-amiettinen@nvidia.com>
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
>
> --
> 1.7.4.1
>
> _______________________________________________
> linux-pm mailing list
> linux-pm@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/linux-pm
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.
--mark
Signed-off-by: markgross <markgross@thegnar.org>
>From b4be99354c5af20cbd4041cddd6038e2353e06b4 Mon Sep 17 00:00:00 2001
From: mgross <mgross@mini>
Date: Sat, 24 Dec 2011 13:40:03 -0800
Subject: [PATCH] Some devices have a subtle relationship with the CPU
throughput and need to set a minimum cpu frequency en order
for the device to not experience performance issues with
buffer under runs because the cpu was throttled too much to
be able to keep the buffers full enough.
One graphics benchmark has shown this issue on Intel SOC devices. The
graphics part ends up waiting on the cpu to fill the open GL instruction
queue between frames and thus graphic performance suffers because of the
cpu throttling because the CPU really isn't very busy while running the
benchmark.
---
drivers/cpufreq/cpufreq.c | 8 ++++++++
include/linux/pm_qos.h | 8 +++++---
kernel/power/qos.c | 19 +++++++++++++++++++
3 files changed, 32 insertions(+), 3 deletions(-)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 987a165..4cbd58b 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>
@@ -1629,6 +1630,9 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data,
pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
policy->min, policy->max);
+
+ if (policy->min < pm_qos_request(PM_QOS_CPU_THROUGHPUT))
+ policy->min = pm_qos_request(PM_QOS_CPU_THROUGHPUT);
memcpy(&policy->cpuinfo, &data->cpuinfo,
sizeof(struct cpufreq_cpuinfo));
@@ -1736,6 +1740,10 @@ int cpufreq_update_policy(unsigned int cpu)
policy.policy = data->user_policy.policy;
policy.governor = data->user_policy.governor;
+ if (policy.min < pm_qos_request(PM_QOS_CPU_THROUGHPUT))
+ policy.min = pm_qos_request(PM_QOS_CPU_THROUGHPUT);
+
+
/* BIOS might change freq behind our back
-> ask driver for current freq and notify governors about a change */
if (cpufreq_driver->get) {
diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h
index 83b0ea3..ead081c 100644
--- a/include/linux/pm_qos.h
+++ b/include/linux/pm_qos.h
@@ -11,13 +11,15 @@
#define PM_QOS_RESERVED 0
#define PM_QOS_CPU_DMA_LATENCY 1
-#define PM_QOS_NETWORK_LATENCY 2
-#define PM_QOS_NETWORK_THROUGHPUT 3
+#define PM_QOS_CPU_THROUGHPUT 2
+#define PM_QOS_NETWORK_LATENCY 3
+#define PM_QOS_NETWORK_THROUGHPUT 4
-#define PM_QOS_NUM_CLASSES 4
+#define PM_QOS_NUM_CLASSES 5
#define PM_QOS_DEFAULT_VALUE -1
#define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC)
+#define PM_QOS_CPU_THROUGHPUT_DEFAULT_VALUE 0
#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
diff --git a/kernel/power/qos.c b/kernel/power/qos.c
index 995e3bd..92951fa 100644
--- a/kernel/power/qos.c
+++ b/kernel/power/qos.c
@@ -60,6 +60,19 @@ static DEFINE_SPINLOCK(pm_qos_lock);
static struct pm_qos_object null_pm_qos;
+static BLOCKING_NOTIFIER_HEAD(cpu_throughput_notifier);
+static struct pm_qos_constraints cpu_throughput_constraints = {
+ .list = PLIST_HEAD_INIT(cpu_throughput_constraints.list),
+ .target_value = PM_QOS_CPU_THROUGHPUT_DEFAULT_VALUE,
+ .default_value = PM_QOS_CPU_THROUGHPUT_DEFAULT_VALUE,
+ .type = PM_QOS_MIN,
+ .notifiers = &cpu_throughput_notifier,
+};
+static struct pm_qos_object cpu_throughput_pm_qos = {
+ .constraints = &cpu_throughput_constraints,
+ .name = "cpu_throughput",
+};
+
static BLOCKING_NOTIFIER_HEAD(cpu_dma_lat_notifier);
static struct pm_qos_constraints cpu_dma_constraints = {
.list = PLIST_HEAD_INIT(cpu_dma_constraints.list),
@@ -104,6 +117,7 @@ static struct pm_qos_object network_throughput_pm_qos = {
static struct pm_qos_object *pm_qos_array[] = {
&null_pm_qos,
&cpu_dma_pm_qos,
+ &cpu_throughput_pm_qos,
&network_lat_pm_qos,
&network_throughput_pm_qos
};
@@ -475,6 +489,11 @@ static int __init pm_qos_power_init(void)
printk(KERN_ERR "pm_qos_param: cpu_dma_latency setup failed\n");
return ret;
}
+ ret = register_pm_qos_misc(&cpu_throughput_pm_qos);
+ if (ret < 0) {
+ printk(KERN_ERR "pm_qos_param: cpu_throughput 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");
--
1.7.5.4
^ permalink raw reply related
* Re: [PATCH 6/6] input: CPU frequency booster
From: mark gross @ 2012-01-06 15:40 UTC (permalink / raw)
To: Antti P Miettinen; +Cc: linux-pm
In-Reply-To: <1325810186-28986-7-git-send-email-amiettinen@nvidia.com>
FWIW this looks ok. but isn't really a pm_qos change.
--mark
On Fri, Jan 06, 2012 at 02:36:26AM +0200, Antti P Miettinen wrote:
> 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
>
> _______________________________________________
> linux-pm mailing list
> linux-pm@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/linux-pm
^ permalink raw reply
* Re: [PATCH 5/6] cpufreq: Enforce PM QoS min/max limits
From: mark gross @ 2012-01-06 15:38 UTC (permalink / raw)
To: Antti P Miettinen; +Cc: linux-pm
In-Reply-To: <1325810186-28986-6-git-send-email-amiettinen@nvidia.com>
On Fri, Jan 06, 2012 at 02:36:25AM +0200, Antti P Miettinen wrote:
> Observe PM QoS CPU frequency minimum and maximum in addition
> to policy settings.
>
> Signed-off-by: Antti P Miettinen <amiettinen@nvidia.com>
> ---
> drivers/cpufreq/cpufreq.c | 49 +++++++++++++++++++++++++++++++++++++++++++-
> 1 files changed, 47 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> index 65a512b..cd90cd2b 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>
>
> @@ -1634,9 +1635,17 @@ 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 = pm_qos_request(PM_QOS_CPU_FREQ_MIN);
> + unsigned int qmax = pm_qos_request(PM_QOS_CPU_FREQ_MAX);
no max please.
>
> - 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 - %u) kHz\n",
> + policy->cpu, pmin, pmax, qmin, qmax);
> +
> + /* clamp the new policy to PM QoS limits */
> + policy->min = max(pmin, qmin);
> + policy->max = min(pmax, qmax);
>
> memcpy(&policy->cpuinfo, &data->cpuinfo,
> sizeof(struct cpufreq_cpuinfo));
> @@ -1711,6 +1720,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;
> }
>
FWIW the following is the part I had not finished in my version of your
patch set. I'll send my version in a reply after I finish my review of
your code. Maybe we can consolidate yours and mine?
--mark
> @@ -1904,9 +1916,36 @@ 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 struct notifier_block max_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 %s %lu\n",
> + b == &min_freq_notifier ? "min" : "max", 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;
> @@ -1916,6 +1955,12 @@ 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);
> + rc = pm_qos_add_notifier(PM_QOS_CPU_FREQ_MAX,
> + &max_freq_notifier);
> + BUG_ON(rc);
>
> return 0;
> }
> --
> 1.7.4.1
>
> _______________________________________________
> linux-pm mailing list
> linux-pm@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/linux-pm
^ permalink raw reply
* Re: [PATCH 3/6] cpufreq: Export user_policy min/max
From: mark gross @ 2012-01-06 15:33 UTC (permalink / raw)
To: Antti P Miettinen; +Cc: linux-pm
In-Reply-To: <1325810186-28986-4-git-send-email-amiettinen@nvidia.com>
Why do you need to export these values here and from the pmqos ABI?
I don't think we want this change. Also, isn't it redundant WRT
existing CPU freq govoner sysfs output?
--mark
On Fri, Jan 06, 2012 at 02:36:23AM +0200, Antti P Miettinen wrote:
> 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 8c2df34..e63b29f 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -364,6 +364,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);
> @@ -582,6 +584,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,
> @@ -595,6 +599,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
>
> _______________________________________________
> linux-pm mailing list
> linux-pm@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/linux-pm
^ permalink raw reply
* Re: [PATCH 2/6] PM QoS: Add CPU frequency min/max as PM QoS params
From: mark gross @ 2012-01-06 15:30 UTC (permalink / raw)
To: Antti P Miettinen; +Cc: linux-pm
In-Reply-To: <1325810186-28986-3-git-send-email-amiettinen@nvidia.com>
On Fri, Jan 06, 2012 at 02:36:22AM +0200, Antti P Miettinen wrote:
> Add minimum and maximum CPU frequency as PM QoS parameters.
>
> Signed-off-by: Antti P Miettinen <amiettinen@nvidia.com>
> ---
> include/linux/pm_qos.h | 5 +++++
> kernel/power/qos.c | 32 +++++++++++++++++++++++++++++++-
> 2 files changed, 36 insertions(+), 1 deletions(-)
>
> diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h
> index 5ac91d8..7b8d08b 100644
> --- a/include/linux/pm_qos.h
> +++ b/include/linux/pm_qos.h
> @@ -14,8 +14,11 @@ enum {
> PM_QOS_CPU_DMA_LATENCY,
> PM_QOS_NETWORK_LATENCY,
> PM_QOS_NETWORK_THROUGHPUT,
> + PM_QOS_CPU_FREQ_MIN,
> + PM_QOS_CPU_FREQ_MAX,
What is this about? How sould freq_max make any sense in the context of
constraining power mangement throutling? this is wrong.
You should only have a cpu throughput qos. I.e. FREQ_MIN.
FWIW in my patch I named it : PM_QOS_CPU_THROUGHPUT but, its just a
different name to your PM_QOS_CPU_FREQ_MIN name.
>
> /* insert new class ID */
> +
> PM_QOS_NUM_CLASSES,
> };
>
> @@ -25,6 +28,8 @@ 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
> +#define PM_QOS_CPU_FREQ_MAX_DEFAULT_VALUE LONG_MAX
PM_QOS_FREQ_MAX must go away.
--mark
>
> struct pm_qos_request {
> struct plist_node node;
> diff --git a/kernel/power/qos.c b/kernel/power/qos.c
> index d6d6dbd..66ae05e 100644
> --- a/kernel/power/qos.c
> +++ b/kernel/power/qos.c
> @@ -101,11 +101,41 @@ 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 BLOCKING_NOTIFIER_HEAD(cpu_freq_max_notifier);
> +static struct pm_qos_constraints cpu_freq_max_constraints = {
> + .list = PLIST_HEAD_INIT(cpu_freq_max_constraints.list),
> + .target_value = PM_QOS_CPU_FREQ_MAX_DEFAULT_VALUE,
> + .default_value = PM_QOS_CPU_FREQ_MAX_DEFAULT_VALUE,
> + .type = PM_QOS_MIN,
> + .notifiers = &cpu_freq_max_notifier,
> +};
> +static struct pm_qos_object cpu_freq_max_pm_qos = {
> + .constraints = &cpu_freq_max_constraints,
> + .name = "cpu_freq_max",
> +};
> +
> +
> 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,
> + &cpu_freq_max_pm_qos
> };
>
> static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf,
> --
> 1.7.4.1
>
> _______________________________________________
> linux-pm mailing list
> linux-pm@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/linux-pm
^ permalink raw reply
* Re: [PATCH 1/6] PM QoS: Simplify PM QoS expansion/merge
From: mark gross @ 2012-01-06 15:24 UTC (permalink / raw)
To: Antti P Miettinen; +Cc: linux-pm, Alex Frid
In-Reply-To: <1325810186-28986-2-git-send-email-amiettinen@nvidia.com>
Acked-by: markgross <markgross@thegnar.org>
On Fri, Jan 06, 2012 at 02:36:21AM +0200, Antti P Miettinen wrote:
> 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
>
> _______________________________________________
> 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-06 15:18 UTC (permalink / raw)
To: Antti P Miettinen; +Cc: linux-pm
In-Reply-To: <1325810186-28986-1-git-send-email-amiettinen@nvidia.com>
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.
wow, isn't this is timely :)
I was working on the same thing. I used different names. FWIW our
issue is motivated by some graphics workloads that get starved for
frames because the cpufreq governor sees nothing by < 50% CPU use so it
pushes the cpu into a low P-state which doesn't have throughput to feed
the next frame of OpenGL data before the next frame time. This is
pretty common for some graphics workloads.
I look forward to reviewing you path set!
--mark
> --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
>
> --
> 1.7.4.1
>
> _______________________________________________
> linux-pm mailing list
> linux-pm@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/linux-pm
^ permalink raw reply
* Re: [PATCH v2] PM: HIBERNATION: skip the swap size check if the snapshot image size is anticipative
From: Barry Song @ 2012-01-06 2:20 UTC (permalink / raw)
To: Pavel Machek
Cc: Xiangzhen Ye, linux-kernel, workgroup.linux, linux-arm-kernel,
Barry Song, linux-pm
In-Reply-To: <20120105184604.GA11065@atrey.karlin.mff.cuni.cz>
2012/1/6 Pavel Machek <pavel@ucw.cz>:
> Hi!
>
> Is the check even useful these days? Should we remove it altogether?
i think we can let users or distributions decide whether it is useful.
On PC, disk space is not an issue, people might run many applications
while doing hibernation, so snapshot is much big. an early check will
improve user experience because people don't need to wait a long time
and find space is not enough.
for embedded system, SoC solutions can know whether the space is
enough since they know what are running while doing hibernation, so
they can skip the check by setting the flag in sysfs.
that is why i had this patch sent.
>
> Pavel
>
>
>> Pavel ,Rafael, any feedback?
>> -barry
>>
>> 2011/11/25 Barry Song <Barry.Song@csr.com>:
>> > From: Barry Song <baohua.song@csr.com>
>> >
>> > Current swsusp requires swap partitions even larger than real saved pages
>> > based on the worst compression ratio:
>> > but for an embedded system, which has limited storage space, then it might
>> > can't give the large partition to save snapshot.
>> > In the another way, some embedded systems can definitely know the most size
>> > needed for snapshot since they run some specific application lists.
>> > So this patch provides the possibility for users to tell kernel even
>> > the system has a little snapshot partition, but it is still enough.
>> > For example, if the system need to save 120MB memory, origin swsusp will require
>> > a 130MB partition to save snapshot. but if users know 30MB is enough for them(
>> > compressed image will be less than 30MB), they just make a 30MB partition by
>> > echo 0 > /sys/power/check_swap_size
>> >
>> > Signed-off-by: Barry Song <Baohua.Song@csr.com>
>> > Cc: Xiangzhen Ye <Xiangzhen.Ye@csr.com>
>> > ---
>> > -v2:drop swap_enough bootargs and use /sys/power/check_swap_size node
>> >
>> > Documentation/power/interface.txt | 5 +++++
>> > kernel/power/hibernate.c | 22 ++++++++++++++++++++++
>> > kernel/power/power.h | 2 ++
>> > kernel/power/swap.c | 9 +++++++++
>> > 4 files changed, 38 insertions(+), 0 deletions(-)
>> >
>> > diff --git a/Documentation/power/interface.txt b/Documentation/power/interface.txt
>> > index c537834..5e205f0 100644
>> > --- a/Documentation/power/interface.txt
>> > +++ b/Documentation/power/interface.txt
>> > @@ -47,6 +47,11 @@ Writing to this file will accept one of
>> > 'testproc'
>> > 'test'
>> >
>> > +/sys/power/check_swap_size controls whether we can skip checking the swap
>> > +partition size by worst compression ratio. If users know the swap partition
>> > +is enough for compressed snapshot, write 0 to /sys/power/check_swap_size.
>> > +It is useful for an embedded system with known running softwares.
>> > +
>> > /sys/power/image_size controls the size of the image created by
>> > the suspend-to-disk mechanism. It can be written a string
>> > representing a non-negative integer that will be used as an upper
>> > diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
>> > index 1c53f7f..5552473 100644
>> > --- a/kernel/power/hibernate.c
>> > +++ b/kernel/power/hibernate.c
>> > @@ -1024,11 +1024,33 @@ static ssize_t reserved_size_store(struct kobject *kobj,
>> >
>> > power_attr(reserved_size);
>> >
>> > +static ssize_t check_swap_size_show(struct kobject *kobj, struct kobj_attribute *attr,
>> > + char *buf)
>> > +{
>> > + return sprintf(buf, "%d\n", check_swap_size);
>> > +}
>> > +
>> > +static ssize_t check_swap_size_store(struct kobject *kobj, struct kobj_attribute *attr,
>> > + const char *buf, size_t n)
>> > +{
>> > + int check_size;
>> > +
>> > + if (sscanf(buf, "%d", &check_size) == 1) {
>> > + check_swap_size = check_size;
>> > + return n;
>> > + }
>> > +
>> > + return -EINVAL;
>> > +}
>> > +
>> > +power_attr(check_swap_size);
>> > +
>> > static struct attribute * g[] = {
>> > &disk_attr.attr,
>> > &resume_attr.attr,
>> > &image_size_attr.attr,
>> > &reserved_size_attr.attr,
>> > + &check_swap_size_attr.attr,
>> > NULL,
>> > };
>> >
>> > diff --git a/kernel/power/power.h b/kernel/power/power.h
>> > index 23a2db1..4f0fa78 100644
>> > --- a/kernel/power/power.h
>> > +++ b/kernel/power/power.h
>> > @@ -74,6 +74,8 @@ static struct kobj_attribute _name##_attr = { \
>> >
>> > /* Preferred image size in bytes (default 500 MB) */
>> > extern unsigned long image_size;
>> > +/* If 0, skip checking whether the swap size is enough for compressed snapshot */
>> > +extern int check_swap_size;
>> > /* Size of memory reserved for drivers (default SPARE_PAGES x PAGE_SIZE) */
>> > extern unsigned long reserved_size;
>> > extern int in_suspend;
>> > diff --git a/kernel/power/swap.c b/kernel/power/swap.c
>> > index 11a594c..db90195 100644
>> > --- a/kernel/power/swap.c
>> > +++ b/kernel/power/swap.c
>> > @@ -37,6 +37,12 @@
>> > #define HIBERNATE_SIG "S1SUSPEND"
>> >
>> > /*
>> > + * if users know swap partitions are enough for compressed snapshots,
>> > + * echo 0 > /sys/power/check_swap_size
>> > + */
>> > +int check_swap_size = 1;
>> > +
>> > +/*
>> > * The swap map is a data structure used for keeping track of each page
>> > * written to a swap partition. It consists of many swap_map_page
>> > * structures that contain each an array of MAP_PAGE_ENTRIES swap entries.
>> > @@ -772,6 +778,9 @@ static int enough_swap(unsigned int nr_pages, unsigned int flags)
>> > unsigned int free_swap = count_swap_pages(root_swap, 1);
>> > unsigned int required;
>> >
>> > + if (!check_swap_size)
>> > + return 1;
>> > +
>> > pr_debug("PM: Free swap pages: %u\n", free_swap);
>> >
>> > required = PAGES_FOR_IO + ((flags & SF_NOCOMPRESS_MODE) ?
>> > --
>> > 1.7.1
>
-barry
_______________________________________________
linux-pm mailing list
linux-pm@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/linux-pm
^ permalink raw reply
* Re: [PATCH] s3c_adc_battery: average over more than one adc sample
From: Anton Vorontsov @ 2012-01-06 2:17 UTC (permalink / raw)
To: Heiko Stübner
Cc: Vasily Khoruzhick, Linux PM mailing list, David Woodhouse,
linux-kernel
In-Reply-To: <201112291252.08563.heiko@sntech.de>
On Thu, Dec 29, 2011 at 12:52:07PM +0100, Heiko Stübner wrote:
> Some sources for adc battery information provide only inaccurate results
> where the read value differs from the real value with positive and negative
> offsets. For such sources it can be more accurate to collect two or more
> value sample and use the average of all collected values.
>
> This patch adds pdata options volt_samples, current_samples and
> backup_volt_samples to specifiy the number of samples to collect,
> reads the specified number of samples and calculates the average of those.
> For unset sample-number-values a default of 1 is assumed.
>
> Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> ---
Applied, thanks!
--
Anton Vorontsov
Email: cbouatmailru@gmail.com
_______________________________________________
linux-pm mailing list
linux-pm@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/linux-pm
^ permalink raw reply
* [PATCH 6/6] input: CPU frequency booster
From: Antti P Miettinen @ 2012-01-06 0:36 UTC (permalink / raw)
To: linux-pm; +Cc: Antti P Miettinen
In-Reply-To: <1325810186-28986-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 5/6] cpufreq: Enforce PM QoS min/max limits
From: Antti P Miettinen @ 2012-01-06 0:36 UTC (permalink / raw)
To: linux-pm; +Cc: Antti P Miettinen
In-Reply-To: <1325810186-28986-1-git-send-email-amiettinen@nvidia.com>
Observe PM QoS CPU frequency minimum and maximum in addition
to policy settings.
Signed-off-by: Antti P Miettinen <amiettinen@nvidia.com>
---
drivers/cpufreq/cpufreq.c | 49 +++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 47 insertions(+), 2 deletions(-)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 65a512b..cd90cd2b 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>
@@ -1634,9 +1635,17 @@ 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 = pm_qos_request(PM_QOS_CPU_FREQ_MIN);
+ unsigned int qmax = pm_qos_request(PM_QOS_CPU_FREQ_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 - %u) kHz\n",
+ policy->cpu, pmin, pmax, qmin, qmax);
+
+ /* clamp the new policy to PM QoS limits */
+ policy->min = max(pmin, qmin);
+ policy->max = min(pmax, qmax);
memcpy(&policy->cpuinfo, &data->cpuinfo,
sizeof(struct cpufreq_cpuinfo));
@@ -1711,6 +1720,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;
}
@@ -1904,9 +1916,36 @@ 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 struct notifier_block max_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 %s %lu\n",
+ b == &min_freq_notifier ? "min" : "max", 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;
@@ -1916,6 +1955,12 @@ 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);
+ rc = pm_qos_add_notifier(PM_QOS_CPU_FREQ_MAX,
+ &max_freq_notifier);
+ BUG_ON(rc);
return 0;
}
--
1.7.4.1
^ permalink raw reply related
* [PATCH 4/6] cpufreq: Preserve sysfs min/max request
From: Antti P Miettinen @ 2012-01-06 0:36 UTC (permalink / raw)
To: linux-pm; +Cc: Antti P Miettinen
In-Reply-To: <1325810186-28986-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 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; \
}
--
1.7.4.1
^ permalink raw reply related
* [PATCH 3/6] cpufreq: Export user_policy min/max
From: Antti P Miettinen @ 2012-01-06 0:36 UTC (permalink / raw)
To: linux-pm; +Cc: Antti P Miettinen
In-Reply-To: <1325810186-28986-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 8c2df34..e63b29f 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -364,6 +364,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);
@@ -582,6 +584,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,
@@ -595,6 +599,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 2/6] PM QoS: Add CPU frequency min/max as PM QoS params
From: Antti P Miettinen @ 2012-01-06 0:36 UTC (permalink / raw)
To: linux-pm; +Cc: Antti P Miettinen
In-Reply-To: <1325810186-28986-1-git-send-email-amiettinen@nvidia.com>
Add minimum and maximum CPU frequency as PM QoS parameters.
Signed-off-by: Antti P Miettinen <amiettinen@nvidia.com>
---
include/linux/pm_qos.h | 5 +++++
kernel/power/qos.c | 32 +++++++++++++++++++++++++++++++-
2 files changed, 36 insertions(+), 1 deletions(-)
diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h
index 5ac91d8..7b8d08b 100644
--- a/include/linux/pm_qos.h
+++ b/include/linux/pm_qos.h
@@ -14,8 +14,11 @@ enum {
PM_QOS_CPU_DMA_LATENCY,
PM_QOS_NETWORK_LATENCY,
PM_QOS_NETWORK_THROUGHPUT,
+ PM_QOS_CPU_FREQ_MIN,
+ PM_QOS_CPU_FREQ_MAX,
/* insert new class ID */
+
PM_QOS_NUM_CLASSES,
};
@@ -25,6 +28,8 @@ 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
+#define PM_QOS_CPU_FREQ_MAX_DEFAULT_VALUE LONG_MAX
struct pm_qos_request {
struct plist_node node;
diff --git a/kernel/power/qos.c b/kernel/power/qos.c
index d6d6dbd..66ae05e 100644
--- a/kernel/power/qos.c
+++ b/kernel/power/qos.c
@@ -101,11 +101,41 @@ 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 BLOCKING_NOTIFIER_HEAD(cpu_freq_max_notifier);
+static struct pm_qos_constraints cpu_freq_max_constraints = {
+ .list = PLIST_HEAD_INIT(cpu_freq_max_constraints.list),
+ .target_value = PM_QOS_CPU_FREQ_MAX_DEFAULT_VALUE,
+ .default_value = PM_QOS_CPU_FREQ_MAX_DEFAULT_VALUE,
+ .type = PM_QOS_MIN,
+ .notifiers = &cpu_freq_max_notifier,
+};
+static struct pm_qos_object cpu_freq_max_pm_qos = {
+ .constraints = &cpu_freq_max_constraints,
+ .name = "cpu_freq_max",
+};
+
+
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,
+ &cpu_freq_max_pm_qos
};
static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf,
--
1.7.4.1
^ permalink raw reply related
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