* Re: [linux-pm] [PATCH 1/4] thermal: Add a new trip type to use cooling device instance number
From: Amit Kachhap @ 2012-04-04 4:23 UTC (permalink / raw)
To: eduardo.valentin
Cc: R, Durgadoss, linaro-dev@lists.linaro.org, patches@linaro.org,
linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org,
linux-pm@lists.linux-foundation.org, rob.lee@linaro.org
In-Reply-To: <20120403141545.GA27497@besouro>
Hi Eduardo,
On 3 April 2012 19:45, Eduardo Valentin <eduardo.valentin@ti.com> wrote:
> Hello,
>
> On Thu, Feb 23, 2012 at 04:50:14PM +0530, Amit Kachhap wrote:
>> On 23 February 2012 12:16, R, Durgadoss <durgadoss.r@intel.com> wrote:
>> > Hi Amit,
>> >
>> >> -----Original Message-----
>> >> From: amit kachhap [mailto:amitdanielk@gmail.com] On Behalf Of Amit Daniel
>> >> Kachhap
>> >> Sent: Wednesday, February 22, 2012 3:44 PM
>> >> To: linux-pm@lists.linux-foundation.org
>> >> Cc: linux-kernel@vger.kernel.org; mjg59@srcf.ucam.org; linux-
>> >> acpi@vger.kernel.org; lenb@kernel.org; linaro-dev@lists.linaro.org;
>> >> amit.kachhap@linaro.org; R, Durgadoss; rob.lee@linaro.org; patches@linaro.org
>> >> Subject: [PATCH 1/4] thermal: Add a new trip type to use cooling device
>> >> instance number
>> >>
>> >> 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 | 45 ++++++++++++++++++++++++++++++++--
>> >> include/linux/thermal.h | 1 +
>> >> 3 files changed, 45 insertions(+), 5 deletions(-)
>> >>
>> >> diff --git a/Documentation/thermal/sysfs-api.txt b/Documentation/thermal/sysfs-
>> >> api.txt
>> >> index 1733ab9..7a0c080 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 220ce7e..d4c9b20 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");
>> >> }
>> >> @@ -1034,10 +1036,10 @@ EXPORT_SYMBOL(thermal_cooling_device_unregister);
>> >>
>> >> void thermal_zone_device_update(struct thermal_zone_device *tz)
>> >> {
>> >> - int count, ret = 0;
>> >> - long temp, trip_temp;
>> >> + int count, ret = 0, inst_id;
>> >> + 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_instance *instance, *state_instance;
>> >> struct thermal_cooling_device *cdev;
>> >>
>> >> mutex_lock(&tz->lock);
>> >> @@ -1086,6 +1088,43 @@ 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;
>> >> +
>> >> + inst_id = 0;
>> >> + /*
>> >> + *For this instance how many instance of same
>> >> + *cooling device occured before
>> >> + */
>> >> +
>> >> + list_for_each_entry(state_instance,
>> >> + &tz->cooling_devices, node) {
>> >> + if (instance->cdev ==
>> >> + state_instance->cdev)
>> >> + inst_id++;
>> >> + if (state_instance->trip == count)
>> >> + break;
>> >> + }
>> >
>> > Can you explain a bit more on this loop and the set_cur_state below ?
>> > Sorry, I don't get the logic behind this..
>>
>> This loop is basically finding the instance id of the same cooling device.
>> Say we have done like this,
>> thermal_zone_bind_cooling_device(thermal, 2, cdev);
>> thermal_zone_bind_cooling_device(thermal, 3, cdev);
>> thermal_zone_bind_cooling_device(thermal, 4, cdev);
>>
>> In above same cooling device cdev is binded to trip no 2,3 and 4 with
>> inst_id generated as 1,2,3 respectively. so set_cur_state for those
>> trip reached will be called as,
>> set_cur_state(cdev, 1);
>> set_cur_state(cdev, 2);
>> set_cur_state(cdev, 3);
>
> In this case, why a simple state = get_cur_state() followed by a
> set_cur_state(++state) / set_cur_state(--state) is not enough?
Thanks for looking into the patch. Well actually what you are
suggesting is exactly happening in PASSIVE trip types where the states
are incremented or decremented based on thermal trend. On the contrary
what this part of code is doing is to jump to a fixed state as and
when a trip point is reached. The cooling effect of a frequency level
is known beforehand and hence jumping into that is safe and also this
does not cause performance degradation by going into a much lower
frequency state just for temperature stablization.
>
> Another thing is if we want to do jumps in the sequence?
>
> set_cur_state(cdev, 1);
> set_cur_state(cdev, 3);
> set_cur_state(cdev, 6);
>
> But for that we need a table mapping, trip vs. state.
>
>
> What do you think?
In the current thermal_zone_device_update implementation all the
checks are currently based on increase in temperature. So even though
we want to go to set_cur_state(cdev, 6) we have to follow
set_cur_state(cdev, 1), set_cur_state(cdev, 2) ,..... and finally
set_cur_state(cdev, 6). So mapping table may not be needed as state
transition is one by one. This a type of limitation but I think there
can be some kind of modification in the way the
thermal_zone_device_update calls all the lower temperature cooling
devices instead of jumping directly to the final trip point cooling
devices.
>
>>
>> Thanks,
>> Amit D
>>
>> >
>> > Thanks,
>> > Durga
>> >
>> >> +
>> >> + cdev = instance->cdev;
>> >> + cdev->ops->get_max_state(cdev, &max_state);
>> >> +
>> >> + if ((temp >= trip_temp) &&
>> >> + (inst_id <= max_state))
>> >> + cdev->ops->set_cur_state(cdev, inst_id);
>> >> + else if ((temp < trip_temp) &&
>> >> + (--inst_id <= max_state))
>> >> + cdev->ops->set_cur_state(cdev, inst_id);
>> >> +
>> >> + 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 796f1ff..8df901f 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-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: [3.0.y, 3.2.y, 3.3.y] Re: [PATCH 04/76] ACPICA: Fix regression in FADT revision checks
From: Josh Boyer @ 2012-04-03 20:15 UTC (permalink / raw)
To: Jonathan Nieder
Cc: Greg Kroah-Hartman, Len Brown, linux-acpi, linux-pm, linux-kernel,
Julian Anastasov, Len Brown, wzab, stable
In-Reply-To: <20120403195804.GA19239@burratino>
On Tue, Apr 3, 2012 at 3:58 PM, Jonathan Nieder <jrnieder@gmail.com> wrote:
> Hi Greg,
>
> Josh Boyer wrote:
>> On Fri, Mar 30, 2012 at 6:13 AM, Len Brown <lenb@kernel.org> wrote:
>
>>> From: Julian Anastasov <ja@ssi.bg>
>>>
>>> commit 64b3db22c04586997ab4be46dd5a5b99f8a2d390 (2.6.39),
>>> "Remove use of unreliable FADT revision field" causes regression
>>> for old P4 systems because now cst_control and other fields are
>>> not reset to 0.
> [...]
>>> The fix is to update acpi_gbl_FADT.header.length after
>>> the original value is used to check for old revisions.
>>>
>>> https://bugzilla.kernel.org/show_bug.cgi?id=42700
>>> https://bugzilla.redhat.com/show_bug.cgi?id=727865
>>>
>>> Signed-off-by: Julian Anastasov <ja@ssi.bg>
>>> Acked-by: Bob Moore <robert.moore@intel.com>
>>> Signed-off-by: Len Brown <len.brown@intel.com>
>>
>> This one should go into the stable trees.
>
> Please apply
>
> 3e80acd1af40 "ACPICA: Fix regression in FADT revision checks"
>
> which is in linus's master to the 3.0.y, 3.2.y, and 3.3.y series to
> fix this old boot problem. (Many affected people disabled HT in the
> BIOS to work around it in the meantime.)
>
> WZab (cc-ed) has tested that the patch addresses the problem when
> applied to the 3.2.y and 3.3.y branches. [1] has details.
We've had this applied in Fedora on 3.2 and 3.3 for a while now as
well.
josh
^ permalink raw reply
* [3.0.y, 3.2.y, 3.3.y] Re: [PATCH 04/76] ACPICA: Fix regression in FADT revision checks
From: Jonathan Nieder @ 2012-04-03 19:58 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Len Brown, linux-acpi, linux-pm, linux-kernel, Julian Anastasov,
Len Brown, Josh Boyer, wzab, stable
In-Reply-To: <CA+5PVA4EBdoxgSrYKYRnaO2qSXDP_rxeQEogD+6jkKPi8sQB-g@mail.gmail.com>
Hi Greg,
Josh Boyer wrote:
> On Fri, Mar 30, 2012 at 6:13 AM, Len Brown <lenb@kernel.org> wrote:
>> From: Julian Anastasov <ja@ssi.bg>
>>
>> commit 64b3db22c04586997ab4be46dd5a5b99f8a2d390 (2.6.39),
>> "Remove use of unreliable FADT revision field" causes regression
>> for old P4 systems because now cst_control and other fields are
>> not reset to 0.
[...]
>> The fix is to update acpi_gbl_FADT.header.length after
>> the original value is used to check for old revisions.
>>
>> https://bugzilla.kernel.org/show_bug.cgi?id=42700
>> https://bugzilla.redhat.com/show_bug.cgi?id=727865
>>
>> Signed-off-by: Julian Anastasov <ja@ssi.bg>
>> Acked-by: Bob Moore <robert.moore@intel.com>
>> Signed-off-by: Len Brown <len.brown@intel.com>
>
> This one should go into the stable trees.
Please apply
3e80acd1af40 "ACPICA: Fix regression in FADT revision checks"
which is in linus's master to the 3.0.y, 3.2.y, and 3.3.y series to
fix this old boot problem. (Many affected people disabled HT in the
BIOS to work around it in the meantime.)
WZab (cc-ed) has tested that the patch addresses the problem when
applied to the 3.2.y and 3.3.y branches. [1] has details.
Thanks,
Jonathan
[1] https://bugzilla.kernel.org/show_bug.cgi?id=38262
--
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: [PATCH] Use safe_halt() rather than halt() in acpi_idle_play_deay()
From: Boris Ostrovsky @ 2012-04-03 16:52 UTC (permalink / raw)
To: Tony Luck; +Cc: Len Brown, linux-acpi, linux-pm, linux-kernel, Len Brown
In-Reply-To: <4f7b27487632dad07@agluck-desktop.sc.intel.com>
On 04/03/12 12:37, Luck, Tony: <tony.luck@intel.com wrote:
> ACPI code is shared by arch/x86 and arch/ia64. ia64 doesn't provide a plain
> "halt()" function. Use safe_halt() instead.
>
> Signed-off-by: Tony Luck<tony.luck@intel.com>
>
> ---
>
> E-mail discussion indicated this would be OK. Please check on x86
> before applying.
Tested-by: Boris Ostrovsky <boris.ostrovsky@amd.com>
-boris
>
> diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
> index b3447f6..f3decb3 100644
> --- a/drivers/acpi/processor_idle.c
> +++ b/drivers/acpi/processor_idle.c
> @@ -786,7 +786,7 @@ static int acpi_idle_play_dead(struct cpuidle_device *dev, int index)
> while (1) {
>
> if (cx->entry_method == ACPI_CSTATE_HALT)
> - halt();
> + safe_halt();
> else if (cx->entry_method == ACPI_CSTATE_SYSTEMIO) {
> inb(cx->address);
> /* See comment in acpi_idle_do_entry() */
>
^ permalink raw reply
* [PATCH] Use safe_halt() rather than halt() in acpi_idle_play_deay()
From: Luck, Tony: <tony.luck@intel.com> @ 2012-04-03 16:37 UTC (permalink / raw)
To: Boris Ostrovsky; +Cc: linux-acpi, linux-pm, linux-kernel, Len Brown
In-Reply-To: <4F79EBAA.7040602@amd.com>
ACPI code is shared by arch/x86 and arch/ia64. ia64 doesn't provide a plain
"halt()" function. Use safe_halt() instead.
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
E-mail discussion indicated this would be OK. Please check on x86
before applying.
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index b3447f6..f3decb3 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -786,7 +786,7 @@ static int acpi_idle_play_dead(struct cpuidle_device *dev, int index)
while (1) {
if (cx->entry_method == ACPI_CSTATE_HALT)
- halt();
+ safe_halt();
else if (cx->entry_method == ACPI_CSTATE_SYSTEMIO) {
inb(cx->address);
/* See comment in acpi_idle_do_entry() */
^ permalink raw reply related
* Re: [linux-pm] [PATCH 1/4] thermal: Add a new trip type to use cooling device instance number
From: Eduardo Valentin @ 2012-04-03 14:15 UTC (permalink / raw)
To: Amit Kachhap
Cc: R, Durgadoss, linaro-dev@lists.linaro.org, patches@linaro.org,
linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org,
linux-pm@lists.linux-foundation.org, rob.lee@linaro.org
In-Reply-To: <CAK44p233Gsh3WavAEJPRcyAHERYttnJFDXsOAmAGK7tv6jhNGQ@mail.gmail.com>
Hello,
On Thu, Feb 23, 2012 at 04:50:14PM +0530, Amit Kachhap wrote:
> On 23 February 2012 12:16, R, Durgadoss <durgadoss.r@intel.com> wrote:
> > Hi Amit,
> >
> >> -----Original Message-----
> >> From: amit kachhap [mailto:amitdanielk@gmail.com] On Behalf Of Amit Daniel
> >> Kachhap
> >> Sent: Wednesday, February 22, 2012 3:44 PM
> >> To: linux-pm@lists.linux-foundation.org
> >> Cc: linux-kernel@vger.kernel.org; mjg59@srcf.ucam.org; linux-
> >> acpi@vger.kernel.org; lenb@kernel.org; linaro-dev@lists.linaro.org;
> >> amit.kachhap@linaro.org; R, Durgadoss; rob.lee@linaro.org; patches@linaro.org
> >> Subject: [PATCH 1/4] thermal: Add a new trip type to use cooling device
> >> instance number
> >>
> >> 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 | 45 ++++++++++++++++++++++++++++++++--
> >> include/linux/thermal.h | 1 +
> >> 3 files changed, 45 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/Documentation/thermal/sysfs-api.txt b/Documentation/thermal/sysfs-
> >> api.txt
> >> index 1733ab9..7a0c080 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 220ce7e..d4c9b20 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");
> >> }
> >> @@ -1034,10 +1036,10 @@ EXPORT_SYMBOL(thermal_cooling_device_unregister);
> >>
> >> void thermal_zone_device_update(struct thermal_zone_device *tz)
> >> {
> >> - int count, ret = 0;
> >> - long temp, trip_temp;
> >> + int count, ret = 0, inst_id;
> >> + 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_instance *instance, *state_instance;
> >> struct thermal_cooling_device *cdev;
> >>
> >> mutex_lock(&tz->lock);
> >> @@ -1086,6 +1088,43 @@ 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;
> >> +
> >> + inst_id = 0;
> >> + /*
> >> + *For this instance how many instance of same
> >> + *cooling device occured before
> >> + */
> >> +
> >> + list_for_each_entry(state_instance,
> >> + &tz->cooling_devices, node) {
> >> + if (instance->cdev ==
> >> + state_instance->cdev)
> >> + inst_id++;
> >> + if (state_instance->trip == count)
> >> + break;
> >> + }
> >
> > Can you explain a bit more on this loop and the set_cur_state below ?
> > Sorry, I don't get the logic behind this..
>
> This loop is basically finding the instance id of the same cooling device.
> Say we have done like this,
> thermal_zone_bind_cooling_device(thermal, 2, cdev);
> thermal_zone_bind_cooling_device(thermal, 3, cdev);
> thermal_zone_bind_cooling_device(thermal, 4, cdev);
>
> In above same cooling device cdev is binded to trip no 2,3 and 4 with
> inst_id generated as 1,2,3 respectively. so set_cur_state for those
> trip reached will be called as,
> set_cur_state(cdev, 1);
> set_cur_state(cdev, 2);
> set_cur_state(cdev, 3);
In this case, why a simple state = get_cur_state() followed by a
set_cur_state(++state) / set_cur_state(--state) is not enough?
Another thing is if we want to do jumps in the sequence?
set_cur_state(cdev, 1);
set_cur_state(cdev, 3);
set_cur_state(cdev, 6);
But for that we need a table mapping, trip vs. state.
What do you think?
>
> Thanks,
> Amit D
>
> >
> > Thanks,
> > Durga
> >
> >> +
> >> + cdev = instance->cdev;
> >> + cdev->ops->get_max_state(cdev, &max_state);
> >> +
> >> + if ((temp >= trip_temp) &&
> >> + (inst_id <= max_state))
> >> + cdev->ops->set_cur_state(cdev, inst_id);
> >> + else if ((temp < trip_temp) &&
> >> + (--inst_id <= max_state))
> >> + cdev->ops->set_cur_state(cdev, inst_id);
> >> +
> >> + 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 796f1ff..8df901f 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-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: [PATCH][V3] cpuidle : use percpu cpuidle in the core code
From: Srivatsa S. Bhat @ 2012-04-03 5:49 UTC (permalink / raw)
To: Daniel Lezcano; +Cc: linux-pm, patches, linaro-dev
In-Reply-To: <1333394401-20701-1-git-send-email-daniel.lezcano@linaro.org>
On 04/03/2012 12:50 AM, Daniel Lezcano wrote:
> The usual cpuidle initialization routines register the driver and
> then register a cpuidle device per cpu.
>
> By default, most drivers initialize the device state count with the
> driver state count.
>
> We can then add a new function 'cpuidle_register' where we register
> the driver and the devices. These devices can be defined in a global
> static variable in cpuidle.c. We will be able to factor out and
> remove a lot of duplicate lines of code.
>
> As we still have some drivers, with different initialization routines,
> we keep 'cpuidle_register_driver' and 'cpuidle_register_device' as low
> level initialization routines to do some specific operations on the
> cpuidle devices.
>
> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Looks good to me now.
Acked-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Regards,
Srivatsa S. Bhat
> ---
> drivers/cpuidle/cpuidle.c | 42 ++++++++++++++++++++++++++++++++++++++++++
> include/linux/cpuidle.h | 3 +++
> 2 files changed, 45 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
> index 87411ce..4d1f79b 100644
> --- a/drivers/cpuidle/cpuidle.c
> +++ b/drivers/cpuidle/cpuidle.c
> @@ -23,6 +23,7 @@
> #include "cpuidle.h"
>
> DEFINE_PER_CPU(struct cpuidle_device *, cpuidle_devices);
> +DEFINE_PER_CPU(struct cpuidle_device, cpuidle_device);
>
> DEFINE_MUTEX(cpuidle_lock);
> LIST_HEAD(cpuidle_detected_devices);
> @@ -419,6 +420,47 @@ int cpuidle_register_device(struct cpuidle_device *dev)
>
> EXPORT_SYMBOL_GPL(cpuidle_register_device);
>
> +/*
> + * cpuidle_register : register cpuidle driver and devices
> + * Note this function must be called after smp_init.
> + * @drv : the cpuidle driver
> + * Returns 0 on success, < 0 otherwise
> + */
> +int cpuidle_register(struct cpuidle_driver *drv)
> +{
> + int ret, cpu, i;
> + struct cpuidle_device *dev;
> +
> + ret = cpuidle_register_driver(drv);
> + if (ret)
> + return ret;
> +
> + for_each_online_cpu(cpu) {
> + dev = &per_cpu(cpuidle_device, cpu);
> + dev->cpu = cpu;
> +
> + ret = cpuidle_register_device(dev);
> + if (ret)
> + goto out_unregister;
> + }
> +
> +out:
> + return ret;
> +
> +out_unregister:
> + for_each_online_cpu(i) {
> + if (i == cpu)
> + break;
> + dev = &per_cpu(cpuidle_device, i);
> + cpuidle_unregister_device(dev);
> + }
> +
> + cpuidle_unregister_driver(drv);
> +
> + goto out;
> +}
> +EXPORT_SYMBOL_GPL(cpuidle_register);
> +
> /**
> * cpuidle_unregister_device - unregisters a CPU's idle PM feature
> * @dev: the cpu
> diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
> index 6c26a3d..3475294 100644
> --- a/include/linux/cpuidle.h
> +++ b/include/linux/cpuidle.h
> @@ -135,6 +135,7 @@ struct cpuidle_driver {
> #ifdef CONFIG_CPU_IDLE
> extern void disable_cpuidle(void);
> extern int cpuidle_idle_call(void);
> +extern int cpuidle_register(struct cpuidle_driver *drv);
> extern int cpuidle_register_driver(struct cpuidle_driver *drv);
> struct cpuidle_driver *cpuidle_get_driver(void);
> extern void cpuidle_unregister_driver(struct cpuidle_driver *drv);
> @@ -154,6 +155,8 @@ extern int cpuidle_play_dead(void);
> #else
> static inline void disable_cpuidle(void) { }
> static inline int cpuidle_idle_call(void) { return -ENODEV; }
> +static inline int cpuidle_register(struct cpuidle_driver *drv)
> +{return -ENODEV; }
> static inline int cpuidle_register_driver(struct cpuidle_driver *drv)
> {return -ENODEV; }
> static inline struct cpuidle_driver *cpuidle_get_driver(void) {return NULL; }
^ permalink raw reply
* [PATCH][V3] cpuidle : use percpu cpuidle in the core code
From: Daniel Lezcano @ 2012-04-02 19:20 UTC (permalink / raw)
To: lenb; +Cc: linux-pm, linaro-dev, srivatsa.bhat, patches
The usual cpuidle initialization routines register the driver and
then register a cpuidle device per cpu.
By default, most drivers initialize the device state count with the
driver state count.
We can then add a new function 'cpuidle_register' where we register
the driver and the devices. These devices can be defined in a global
static variable in cpuidle.c. We will be able to factor out and
remove a lot of duplicate lines of code.
As we still have some drivers, with different initialization routines,
we keep 'cpuidle_register_driver' and 'cpuidle_register_device' as low
level initialization routines to do some specific operations on the
cpuidle devices.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
drivers/cpuidle/cpuidle.c | 42 ++++++++++++++++++++++++++++++++++++++++++
include/linux/cpuidle.h | 3 +++
2 files changed, 45 insertions(+), 0 deletions(-)
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index 87411ce..4d1f79b 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -23,6 +23,7 @@
#include "cpuidle.h"
DEFINE_PER_CPU(struct cpuidle_device *, cpuidle_devices);
+DEFINE_PER_CPU(struct cpuidle_device, cpuidle_device);
DEFINE_MUTEX(cpuidle_lock);
LIST_HEAD(cpuidle_detected_devices);
@@ -419,6 +420,47 @@ int cpuidle_register_device(struct cpuidle_device *dev)
EXPORT_SYMBOL_GPL(cpuidle_register_device);
+/*
+ * cpuidle_register : register cpuidle driver and devices
+ * Note this function must be called after smp_init.
+ * @drv : the cpuidle driver
+ * Returns 0 on success, < 0 otherwise
+ */
+int cpuidle_register(struct cpuidle_driver *drv)
+{
+ int ret, cpu, i;
+ struct cpuidle_device *dev;
+
+ ret = cpuidle_register_driver(drv);
+ if (ret)
+ return ret;
+
+ for_each_online_cpu(cpu) {
+ dev = &per_cpu(cpuidle_device, cpu);
+ dev->cpu = cpu;
+
+ ret = cpuidle_register_device(dev);
+ if (ret)
+ goto out_unregister;
+ }
+
+out:
+ return ret;
+
+out_unregister:
+ for_each_online_cpu(i) {
+ if (i == cpu)
+ break;
+ dev = &per_cpu(cpuidle_device, i);
+ cpuidle_unregister_device(dev);
+ }
+
+ cpuidle_unregister_driver(drv);
+
+ goto out;
+}
+EXPORT_SYMBOL_GPL(cpuidle_register);
+
/**
* cpuidle_unregister_device - unregisters a CPU's idle PM feature
* @dev: the cpu
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index 6c26a3d..3475294 100644
--- a/include/linux/cpuidle.h
+++ b/include/linux/cpuidle.h
@@ -135,6 +135,7 @@ struct cpuidle_driver {
#ifdef CONFIG_CPU_IDLE
extern void disable_cpuidle(void);
extern int cpuidle_idle_call(void);
+extern int cpuidle_register(struct cpuidle_driver *drv);
extern int cpuidle_register_driver(struct cpuidle_driver *drv);
struct cpuidle_driver *cpuidle_get_driver(void);
extern void cpuidle_unregister_driver(struct cpuidle_driver *drv);
@@ -154,6 +155,8 @@ extern int cpuidle_play_dead(void);
#else
static inline void disable_cpuidle(void) { }
static inline int cpuidle_idle_call(void) { return -ENODEV; }
+static inline int cpuidle_register(struct cpuidle_driver *drv)
+{return -ENODEV; }
static inline int cpuidle_register_driver(struct cpuidle_driver *drv)
{return -ENODEV; }
static inline struct cpuidle_driver *cpuidle_get_driver(void) {return NULL; }
--
1.7.5.4
^ permalink raw reply related
* [PATCH] x86: Use safe_halt() instead of halt() in acpi_idle_play_dead()
From: Boris Ostrovsky @ 2012-04-02 18:56 UTC (permalink / raw)
To: x86, len.brown, tony.luck, konrad.wilk
Cc: linux-acpi, linux-pm, linux-kernel, Boris Ostrovsky
Using halt() in acpi_idle_play_dead() breaks ia64 build. Use safe_halt()
instead.
Signed-off-by: Boris Ostrovsky <boris.ostrovsky@amd.com>
---
drivers/acpi/processor_idle.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 6b1d32a..784f9a7 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -786,7 +786,7 @@ static int acpi_idle_play_dead(struct cpuidle_device *dev, int index)
while (1) {
if (cx->entry_method == ACPI_CSTATE_HALT)
- halt();
+ safe_halt();
else if (cx->entry_method == ACPI_CSTATE_SYSTEMIO) {
inb(cx->address);
/* See comment in acpi_idle_do_entry() */
--
1.7.3.4
^ permalink raw reply related
* Re: [PATCH 58/76] idle, x86: Allow off-lined CPU to enter deeper C states
From: Boris Ostrovsky @ 2012-04-02 18:10 UTC (permalink / raw)
To: Tony Luck; +Cc: Len Brown, linux-acpi, linux-pm, linux-kernel, Len Brown
In-Reply-To: <CA+8MBbKv25Uu3fJeBhyj5cQvB6FN+KqgnP67UGhwvF+p635g7w@mail.gmail.com>
On 04/02/12 14:02, Tony Luck wrote:
>> x86 halt() causes processor to go to C1 state (which is often not the
>> deepest). But other than that it seems similar to what you are describing.
>
> OK - then Konrad's suggestion of using "safe_halt()" here rather than
> "halt()" would work for ia64.
I originally didn't want to use safe_halt() because the CPU will wake up
on an unmasked HW interrupt unlike halt(). But I guess we are not
supposed to get any such interrupts when we are off-lining a CPU so
safe_halt() should be OK.
Thanks.
-boris
^ permalink raw reply
* Re: [PATCH 58/76] idle, x86: Allow off-lined CPU to enter deeper C states
From: Tony Luck @ 2012-04-02 18:02 UTC (permalink / raw)
To: Boris Ostrovsky; +Cc: Len Brown, linux-acpi, linux-pm, linux-kernel, Len Brown
In-Reply-To: <4F79E83C.5090506@amd.com>
> x86 halt() causes processor to go to C1 state (which is often not the
> deepest). But other than that it seems similar to what you are describing.
OK - then Konrad's suggestion of using "safe_halt()" here rather than
"halt()" would work for ia64.
Other architectures don't use APCI - so this should just be localized to
x86 and ia64
-Tony
^ permalink raw reply
* Re: [PATCH 58/76] idle, x86: Allow off-lined CPU to enter deeper C states
From: Boris Ostrovsky @ 2012-04-02 17:56 UTC (permalink / raw)
To: Tony Luck; +Cc: Len Brown, linux-acpi, linux-pm, linux-kernel, Len Brown
In-Reply-To: <CA+8MBbJnrhKmy5f_pbL8Ogi1ihM-51hfqCDY5gUQ1hkvw7p22Q@mail.gmail.com>
On 04/02/12 13:25, Tony Luck wrote:
>>> + while (1) {
>>> +
>>> + if (cx->entry_method == ACPI_CSTATE_HALT)
>>> + halt();
>
> What's the intent here? I think that I can just set up a function pointer
> named "halt" on ia64 and point it to my cpu_halt() function (which looks
> for the deepest C-state, and then calls PAL to enter it. Is that equivalent
> to what the x86 "halt()" function does?
x86 halt() causes processor to go to C1 state (which is often not the
deepest). But other than that it seems similar to what you are describing.
However, the fix that you are proposing will only help ia64 and I wonder
whether others architectures may have the same problem?
(And I don't think inb/inl should cause you any trouble since they are
already used, for example, in acpi_idle_do_entry())
-boris
^ permalink raw reply
* Re: [PATCH 58/76] idle, x86: Allow off-lined CPU to enter deeper C states
From: Konrad Rzeszutek Wilk @ 2012-04-02 17:45 UTC (permalink / raw)
To: Tony Luck
Cc: Len Brown, linux-acpi, linux-pm, linux-kernel, Boris Ostrovsky,
Len Brown
In-Reply-To: <CA+8MBbJnrhKmy5f_pbL8Ogi1ihM-51hfqCDY5gUQ1hkvw7p22Q@mail.gmail.com>
On Mon, Apr 02, 2012 at 10:25:27AM -0700, Tony Luck wrote:
> >> + while (1) {
> >> +
> >> + if (cx->entry_method == ACPI_CSTATE_HALT)
> >> + halt();
>
> What's the intent here? I think that I can just set up a function pointer
> named "halt" on ia64 and point it to my cpu_halt() function (which looks
> for the deepest C-state, and then calls PAL to enter it. Is that equivalent
> to what the x86 "halt()" function does?
Or use the appropiate safe_halt() which should work on IA64.
>
> -Tony
> --
> 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
--
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: [PATCH 58/76] idle, x86: Allow off-lined CPU to enter deeper C states
From: Tony Luck @ 2012-04-02 17:25 UTC (permalink / raw)
To: Len Brown; +Cc: linux-acpi, linux-pm, linux-kernel, Boris Ostrovsky, Len Brown
In-Reply-To: <CA+8MBbLROfbyfAGZ0xn1tZVHsndeTUNrn=-gHhsfzkocBLh=iQ@mail.gmail.com>
>> + while (1) {
>> +
>> + if (cx->entry_method == ACPI_CSTATE_HALT)
>> + halt();
What's the intent here? I think that I can just set up a function pointer
named "halt" on ia64 and point it to my cpu_halt() function (which looks
for the deepest C-state, and then calls PAL to enter it. Is that equivalent
to what the x86 "halt()" function does?
-Tony
--
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: [PATCH 58/76] idle, x86: Allow off-lined CPU to enter deeper C states
From: Tony Luck @ 2012-04-02 16:13 UTC (permalink / raw)
To: Len Brown; +Cc: linux-acpi, linux-pm, linux-kernel, Boris Ostrovsky, Len Brown
In-Reply-To: <1a022e3f1be11730bd8747b1af96a0274bf6356e.1333101989.git.len.brown@intel.com>
On Fri, Mar 30, 2012 at 3:14 AM, Len Brown <lenb@kernel.org> wrote:
> From: Boris Ostrovsky <boris.ostrovsky@amd.com>
This bit breaks ia64 build:
> +
> +/**
> + * acpi_idle_play_dead - enters an ACPI state for long-term idle (i.e. off-lining)
> + * @dev: the target CPU
> + * @index: the index of suggested state
> + */
> +static int acpi_idle_play_dead(struct cpuidle_device *dev, int index)
> +{
> + struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
> + struct acpi_processor_cx *cx = cpuidle_get_statedata(state_usage);
> +
> + ACPI_FLUSH_CPU_CACHE();
> +
> + while (1) {
> +
> + if (cx->entry_method == ACPI_CSTATE_HALT)
> + halt();
> + else if (cx->entry_method == ACPI_CSTATE_SYSTEMIO) {
> + inb(cx->address);
> + /* See comment in acpi_idle_do_entry() */
> + inl(acpi_gbl_FADT.xpm_timer_block.address);
> + } else
> + return -ENODEV;
> + }
drivers/acpi/processor_idle.c: In function 'acpi_idle_play_dead':
drivers/acpi/processor_idle.c:789: error: implicit declaration of
function 'halt'
So the initial compiler complaint is just about "halt()" - but those "inb()" and
"inl()" parts don't look very ia64 compatible either.
-Tony
^ permalink raw reply
* Re: [PATCH][V2] cpuidle : use percpu cpuidle in the core code
From: Daniel Lezcano @ 2012-04-02 13:46 UTC (permalink / raw)
To: Srivatsa S. Bhat; +Cc: linux-pm, patches, linaro-dev, amit.kucheria
In-Reply-To: <4F79A7EC.5000003@linux.vnet.ibm.com>
On 04/02/2012 03:21 PM, Srivatsa S. Bhat wrote:
> On 04/02/2012 06:18 PM, Daniel Lezcano wrote:
>
>> The usual cpuidle initialization routines are to register the
>> driver, then register a cpuidle device per cpu.
>>
>> With the device's state count default initialization with the
>> driver's state count, the code initialization remains mostly the
>> same in the different drivers.
>>
>> We can then add a new function 'cpuidle_register' where we register
>> the driver and the devices. These devices can be defined in a global
>> static variable in cpuidle.c. We will be able to factor out and
>> remove a lot of duplicate lines of code.
>>
>> As we still have some drivers, with different initialization routines,
>> we keep 'cpuidle_register_driver' and 'cpuidle_register_device' as low
>> level initialization routines to do some specific operations on the
>> cpuidle devices.
>>
>> Signed-off-by: Daniel Lezcano<daniel.lezcano@linaro.org>
>
>> +/*
>> + * cpuidle_register : register cpuidle driver and devices
>> + * Note this function must be called after smp_init.
>> + * @drv : the cpuidle driver
>> + * Returns 0 on success,< 0 otherwise
>> + */
>> +int cpuidle_register(struct cpuidle_driver *drv)
>> +{
>> + int ret, cpu, i;
>> + struct cpuidle_device *dev;
>> +
>> + ret = cpuidle_register_driver(drv);
>> + if (ret)
>> + return ret;
>> +
>> + for_each_online_cpu(cpu) {
>> + dev =&per_cpu(cpuidle_device, cpu);
>> + dev->cpu = cpu;
>> +
>> + ret = cpuidle_register_device(dev);
>> + if (ret)
>> + goto out_unregister;
>> + }
>> +
>> +out:
>> + return ret;
>> +
>> +out_unregister:
>> + for_each_online_cpu(i) {
>> + if (i == cpu)
>> + break;
>> + dev =&per_cpu(cpuidle_device, cpu);
>
>
> ^^^
> That must have been "i" instead of "cpu"...
Oops, right ! Good catch.
Thanks
-- Daniel
--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
_______________________________________________
linux-pm mailing list
linux-pm@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/linux-pm
^ permalink raw reply
* Re: [PATCH][V2] cpuidle : use percpu cpuidle in the core code
From: Srivatsa S. Bhat @ 2012-04-02 13:21 UTC (permalink / raw)
To: Daniel Lezcano; +Cc: linux-pm, patches, linaro-dev, amit.kucheria
In-Reply-To: <1333370928-1930-1-git-send-email-daniel.lezcano@linaro.org>
On 04/02/2012 06:18 PM, Daniel Lezcano wrote:
> The usual cpuidle initialization routines are to register the
> driver, then register a cpuidle device per cpu.
>
> With the device's state count default initialization with the
> driver's state count, the code initialization remains mostly the
> same in the different drivers.
>
> We can then add a new function 'cpuidle_register' where we register
> the driver and the devices. These devices can be defined in a global
> static variable in cpuidle.c. We will be able to factor out and
> remove a lot of duplicate lines of code.
>
> As we still have some drivers, with different initialization routines,
> we keep 'cpuidle_register_driver' and 'cpuidle_register_device' as low
> level initialization routines to do some specific operations on the
> cpuidle devices.
>
> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> +/*
> + * cpuidle_register : register cpuidle driver and devices
> + * Note this function must be called after smp_init.
> + * @drv : the cpuidle driver
> + * Returns 0 on success, < 0 otherwise
> + */
> +int cpuidle_register(struct cpuidle_driver *drv)
> +{
> + int ret, cpu, i;
> + struct cpuidle_device *dev;
> +
> + ret = cpuidle_register_driver(drv);
> + if (ret)
> + return ret;
> +
> + for_each_online_cpu(cpu) {
> + dev = &per_cpu(cpuidle_device, cpu);
> + dev->cpu = cpu;
> +
> + ret = cpuidle_register_device(dev);
> + if (ret)
> + goto out_unregister;
> + }
> +
> +out:
> + return ret;
> +
> +out_unregister:
> + for_each_online_cpu(i) {
> + if (i == cpu)
> + break;
> + dev = &per_cpu(cpuidle_device, cpu);
^^^
That must have been "i" instead of "cpu"...
> + cpuidle_unregister_device(dev);
> + }
> +
> + cpuidle_unregister_driver(drv);
> +
> + goto out;
> +}
> +EXPORT_SYMBOL_GPL(cpuidle_register);
> +
Regards,
Srivatsa S. Bhat
^ permalink raw reply
* Re: [PATCH][V2] cpuidle : use percpu cpuidle in the core code
From: Amit Kucheria @ 2012-04-02 12:59 UTC (permalink / raw)
To: Daniel Lezcano
Cc: linux-pm-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
patches-QSEj5FYQhm4dnm+yROfE0A, linaro-dev-cunTk1MwBs8s++Sfvej+rw,
srivatsa.bhat-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
lenb-DgEjT+Ai2ygdnm+yROfE0A
In-Reply-To: <1333370928-1930-1-git-send-email-daniel.lezcano-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
On Mon, Apr 2, 2012 at 3:48 PM, Daniel Lezcano
<daniel.lezcano-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
> The usual cpuidle initialization routines are to register the
s/are to//
> driver, then register a cpuidle device per cpu.
>
> With the device's state count default initialization with the
> driver's state count, the code initialization remains mostly the
> same in the different drivers.
The following is a bit easier to read and captures your point, I think:
By default, most drivers initialize the device state count with the
driver state count.
> We can then add a new function 'cpuidle_register' where we register
> the driver and the devices. These devices can be defined in a global
> static variable in cpuidle.c. We will be able to factor out and
> remove a lot of duplicate lines of code.
>
> As we still have some drivers, with different initialization routines,
> we keep 'cpuidle_register_driver' and 'cpuidle_register_device' as low
> level initialization routines to do some specific operations on the
> cpuidle devices.
>
> Signed-off-by: Daniel Lezcano <daniel.lezcano-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> ---
> drivers/cpuidle/cpuidle.c | 42 ++++++++++++++++++++++++++++++++++++++++++
> include/linux/cpuidle.h | 3 +++
> 2 files changed, 45 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
> index 87411ce..151c55a 100644
> --- a/drivers/cpuidle/cpuidle.c
> +++ b/drivers/cpuidle/cpuidle.c
> @@ -23,6 +23,7 @@
> #include "cpuidle.h"
>
> DEFINE_PER_CPU(struct cpuidle_device *, cpuidle_devices);
> +DEFINE_PER_CPU(struct cpuidle_device, cpuidle_device);
>
> DEFINE_MUTEX(cpuidle_lock);
> LIST_HEAD(cpuidle_detected_devices);
> @@ -419,6 +420,47 @@ int cpuidle_register_device(struct cpuidle_device *dev)
>
> EXPORT_SYMBOL_GPL(cpuidle_register_device);
>
> +/*
> + * cpuidle_register : register cpuidle driver and devices
> + * Note this function must be called after smp_init.
> + * @drv : the cpuidle driver
> + * Returns 0 on success, < 0 otherwise
> + */
> +int cpuidle_register(struct cpuidle_driver *drv)
> +{
> + int ret, cpu, i;
> + struct cpuidle_device *dev;
> +
> + ret = cpuidle_register_driver(drv);
> + if (ret)
> + return ret;
> +
> + for_each_online_cpu(cpu) {
> + dev = &per_cpu(cpuidle_device, cpu);
> + dev->cpu = cpu;
> +
> + ret = cpuidle_register_device(dev);
> + if (ret)
> + goto out_unregister;
> + }
> +
> +out:
> + return ret;
> +
> +out_unregister:
> + for_each_online_cpu(i) {
> + if (i == cpu)
> + break;
> + dev = &per_cpu(cpuidle_device, cpu);
> + cpuidle_unregister_device(dev);
> + }
> +
> + cpuidle_unregister_driver(drv);
> +
> + goto out;
> +}
> +EXPORT_SYMBOL_GPL(cpuidle_register);
> +
> /**
> * cpuidle_unregister_device - unregisters a CPU's idle PM feature
> * @dev: the cpu
> diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
> index 6c26a3d..3475294 100644
> --- a/include/linux/cpuidle.h
> +++ b/include/linux/cpuidle.h
> @@ -135,6 +135,7 @@ struct cpuidle_driver {
> #ifdef CONFIG_CPU_IDLE
> extern void disable_cpuidle(void);
> extern int cpuidle_idle_call(void);
> +extern int cpuidle_register(struct cpuidle_driver *drv);
> extern int cpuidle_register_driver(struct cpuidle_driver *drv);
> struct cpuidle_driver *cpuidle_get_driver(void);
> extern void cpuidle_unregister_driver(struct cpuidle_driver *drv);
> @@ -154,6 +155,8 @@ extern int cpuidle_play_dead(void);
> #else
> static inline void disable_cpuidle(void) { }
> static inline int cpuidle_idle_call(void) { return -ENODEV; }
> +static inline int cpuidle_register(struct cpuidle_driver *drv)
> +{return -ENODEV; }
> static inline int cpuidle_register_driver(struct cpuidle_driver *drv)
> {return -ENODEV; }
> static inline struct cpuidle_driver *cpuidle_get_driver(void) {return NULL; }
> --
> 1.7.5.4
>
>
> _______________________________________________
> linaro-dev mailing list
> linaro-dev-cunTk1MwBs8s++Sfvej+rw@public.gmane.org
> http://lists.linaro.org/mailman/listinfo/linaro-dev
^ permalink raw reply
* [PATCH][V2] cpuidle : use percpu cpuidle in the core code
From: Daniel Lezcano @ 2012-04-02 12:48 UTC (permalink / raw)
To: lenb; +Cc: linux-pm, linaro-dev, srivatsa.bhat, patches
The usual cpuidle initialization routines are to register the
driver, then register a cpuidle device per cpu.
With the device's state count default initialization with the
driver's state count, the code initialization remains mostly the
same in the different drivers.
We can then add a new function 'cpuidle_register' where we register
the driver and the devices. These devices can be defined in a global
static variable in cpuidle.c. We will be able to factor out and
remove a lot of duplicate lines of code.
As we still have some drivers, with different initialization routines,
we keep 'cpuidle_register_driver' and 'cpuidle_register_device' as low
level initialization routines to do some specific operations on the
cpuidle devices.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
drivers/cpuidle/cpuidle.c | 42 ++++++++++++++++++++++++++++++++++++++++++
include/linux/cpuidle.h | 3 +++
2 files changed, 45 insertions(+), 0 deletions(-)
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index 87411ce..151c55a 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -23,6 +23,7 @@
#include "cpuidle.h"
DEFINE_PER_CPU(struct cpuidle_device *, cpuidle_devices);
+DEFINE_PER_CPU(struct cpuidle_device, cpuidle_device);
DEFINE_MUTEX(cpuidle_lock);
LIST_HEAD(cpuidle_detected_devices);
@@ -419,6 +420,47 @@ int cpuidle_register_device(struct cpuidle_device *dev)
EXPORT_SYMBOL_GPL(cpuidle_register_device);
+/*
+ * cpuidle_register : register cpuidle driver and devices
+ * Note this function must be called after smp_init.
+ * @drv : the cpuidle driver
+ * Returns 0 on success, < 0 otherwise
+ */
+int cpuidle_register(struct cpuidle_driver *drv)
+{
+ int ret, cpu, i;
+ struct cpuidle_device *dev;
+
+ ret = cpuidle_register_driver(drv);
+ if (ret)
+ return ret;
+
+ for_each_online_cpu(cpu) {
+ dev = &per_cpu(cpuidle_device, cpu);
+ dev->cpu = cpu;
+
+ ret = cpuidle_register_device(dev);
+ if (ret)
+ goto out_unregister;
+ }
+
+out:
+ return ret;
+
+out_unregister:
+ for_each_online_cpu(i) {
+ if (i == cpu)
+ break;
+ dev = &per_cpu(cpuidle_device, cpu);
+ cpuidle_unregister_device(dev);
+ }
+
+ cpuidle_unregister_driver(drv);
+
+ goto out;
+}
+EXPORT_SYMBOL_GPL(cpuidle_register);
+
/**
* cpuidle_unregister_device - unregisters a CPU's idle PM feature
* @dev: the cpu
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index 6c26a3d..3475294 100644
--- a/include/linux/cpuidle.h
+++ b/include/linux/cpuidle.h
@@ -135,6 +135,7 @@ struct cpuidle_driver {
#ifdef CONFIG_CPU_IDLE
extern void disable_cpuidle(void);
extern int cpuidle_idle_call(void);
+extern int cpuidle_register(struct cpuidle_driver *drv);
extern int cpuidle_register_driver(struct cpuidle_driver *drv);
struct cpuidle_driver *cpuidle_get_driver(void);
extern void cpuidle_unregister_driver(struct cpuidle_driver *drv);
@@ -154,6 +155,8 @@ extern int cpuidle_play_dead(void);
#else
static inline void disable_cpuidle(void) { }
static inline int cpuidle_idle_call(void) { return -ENODEV; }
+static inline int cpuidle_register(struct cpuidle_driver *drv)
+{return -ENODEV; }
static inline int cpuidle_register_driver(struct cpuidle_driver *drv)
{return -ENODEV; }
static inline struct cpuidle_driver *cpuidle_get_driver(void) {return NULL; }
--
1.7.5.4
^ permalink raw reply related
* Re: [PATCH 17/76] thermal_sys: convert printks to pr_<level>
From: Eduardo Valentin @ 2012-04-01 19:13 UTC (permalink / raw)
To: Joe Perches
Cc: Len Brown, linux-kernel, linux-acpi, Jesper Juhl, linux-pm,
Andrew Morton
In-Reply-To: <1333134530.27601.2.camel@joe2Laptop>
Hello Joe,
On Fri, Mar 30, 2012 at 12:08:50PM -0700, Joe Perches wrote:
> On Fri, 2012-03-30 at 16:41 +0300, Eduardo Valentin wrote:
> > On Fri, Mar 30, 2012 at 06:13:20AM -0400, Len Brown wrote:
> > > From: Joe Perches <joe@perches.com>
> > > Use the current logging style.
> []
> > We should get the struct dev in thermal_zone_device, I think it makes
> > more sense to use the dev_* helper functions.
> []
> > The orig argument could probably be changed to a thermal zone device
> > and the we use it's id as orig for the message.
> > What do you think?
>
> dev_<level> should be used instead of pr_<level> when
> an appropriate struct device * is available.
Agreed that we need a struct device *. My comments are based on the fact
that you have one of it inside the struct therma_zone_device, field device.
Isn't that struct device appropriated enough to be used by the dev_* functions?
>
> cheers, Joe
>
Cheers,
Eduardo
^ permalink raw reply
* Re: [linux-pm] [PATCH 46/76] ACPI: Introduce ACPI D3_COLD state support
From: Rafael J. Wysocki @ 2012-04-01 6:53 UTC (permalink / raw)
To: linux-pm, Len Brown, Lin Ming
Cc: linux-acpi, Len Brown, linux-kernel, Linux PM mailing list
In-Reply-To: <3ebc81b8937d2bc1d0d0064bed29434dfce490aa.1333101989.git.len.brown@intel.com>
On Friday, March 30, 2012, Len Brown wrote:
> From: Zhang Rui <rui.zhang@intel.com>
>
> If a device has _PR3, it means the device supports D3_COLD.
> Add the ability to validate and enter D3_COLD state in ACPI.
This patch is wrong, IMO.
Namely, _PR3 lists power resources that are supposed to be "on"
in D3, which means that in that state the device is not completely
off, so this must be D3_hot and not D3_cold.
So. _PR3 means D3_hot is supported. D3_cold, on the other hand,
is always supported, although it may not be accessible through any
direct software action (for example, it may be necessary to power
down a bus to put devices on it into D3_cold).
Thanks,
Rafael
> Signed-off-by: Zhang Rui <rui.zhang@intel.com>
> Signed-off-by: Lin Ming <ming.m.lin@intel.com>
> Signed-off-by: Len Brown <len.brown@intel.com>
> ---
> drivers/acpi/power.c | 4 ++--
> drivers/acpi/scan.c | 7 +++++++
> 2 files changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
> index 9ac2a9f..0d681fb 100644
> --- a/drivers/acpi/power.c
> +++ b/drivers/acpi/power.c
> @@ -500,14 +500,14 @@ int acpi_power_transition(struct acpi_device *device, int state)
> {
> int result;
>
> - if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
> + if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD))
> return -EINVAL;
>
> if (device->power.state == state)
> return 0;
>
> if ((device->power.state < ACPI_STATE_D0)
> - || (device->power.state > ACPI_STATE_D3))
> + || (device->power.state > ACPI_STATE_D3_COLD))
> return -ENODEV;
>
> /* TBD: Resources must be ordered. */
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index 8ab80ba..571396c 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -885,6 +885,13 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
> acpi_bus_add_power_resource(ps->resources.handles[j]);
> }
>
> + /* The exist of _PR3 indicates D3Cold support */
> + if (i == ACPI_STATE_D3) {
> + status = acpi_get_handle(device->handle, object_name, &handle);
> + if (ACPI_SUCCESS(status))
> + device->power.states[ACPI_STATE_D3_COLD].flags.valid = 1;
> + }
> +
> /* Evaluate "_PSx" to see if we can do explicit sets */
> object_name[2] = 'S';
> status = acpi_get_handle(device->handle, object_name, &handle);
>
^ permalink raw reply
* Re: [PATCH] cpuidle : use percpu cpuidle in the core code
From: Srivatsa S. Bhat @ 2012-03-31 7:45 UTC (permalink / raw)
To: Daniel Lezcano; +Cc: linux-pm, linaro-dev, patches
In-Reply-To: <4F75DCBE.8000309@linaro.org>
On 03/30/2012 09:48 PM, Daniel Lezcano wrote:
> On 03/30/2012 01:59 PM, Srivatsa S. Bhat wrote:
>> On 03/30/2012 05:15 PM, Daniel Lezcano wrote:
>>
>>> On 03/30/2012 01:25 PM, Srivatsa S. Bhat wrote:
>>>> On 03/30/2012 04:18 PM, Daniel Lezcano wrote:
>>>>
>>>>> The usual cpuidle initialization routines are to register the
>>>>> driver, then register a cpuidle device per cpu.
>>>>>
>>>>> With the device's state count default initialization with the
>>>>> driver's state count, the code initialization remains mostly the
>>>>> same in the different drivers.
>>>>>
>>>>> We can then add a new function 'cpuidle_register' where we register
>>>>> the driver and the devices. These devices can be defined in a global
>>>>> static variable in cpuidle.c. We will be able to factor out and
>>>>> remove a lot of duplicate lines of code.
>>>>>
>>>>> As we still have some drivers, with different initialization routines,
>>>>> we keep 'cpuidle_register_driver' and 'cpuidle_register_device' as low
>>>>> level initialization routines to do some specific operations on the
>>>>> cpuidle devices.
>>>>>
>>>>> Signed-off-by: Daniel Lezcano<daniel.lezcano@linaro.org>
>>>>> ---
>>>>> drivers/cpuidle/cpuidle.c | 34 ++++++++++++++++++++++++++++++++++
>>>>> include/linux/cpuidle.h | 3 +++
>>>>> 2 files changed, 37 insertions(+), 0 deletions(-)
>>>>>
>>>>> diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
>>>>> index b8a1faf..2a174e8 100644
>>>>> --- a/drivers/cpuidle/cpuidle.c
>>>>> +++ b/drivers/cpuidle/cpuidle.c
>>>>> @@ -23,6 +23,7 @@
>>>>> #include "cpuidle.h"
>>>>>
>>>>> DEFINE_PER_CPU(struct cpuidle_device *, cpuidle_devices);
>>>>> +DEFINE_PER_CPU(struct cpuidle_device, cpuidle_device);
>>>>>
>>>>> DEFINE_MUTEX(cpuidle_lock);
>>>>> LIST_HEAD(cpuidle_detected_devices);
>>>>> @@ -391,6 +392,39 @@ int cpuidle_register_device(struct
>>>>> cpuidle_device *dev)
>>>>>
>>>>> EXPORT_SYMBOL_GPL(cpuidle_register_device);
>>>>>
>>>>> +int cpuidle_register(struct cpuidle_driver *drv)
>>>>> +{
>>>>> + int ret, cpu;
>>>>> + struct cpuidle_device *dev;
>>>>> +
>>>>> + ret = cpuidle_register_driver(drv);
>>>>> + if (ret)
>>>>> + return ret;
>>>>> +
>>>>> + for_each_online_cpu(cpu) {
>>>>> + dev =&per_cpu(cpuidle_device, cpu);
>>>>> + dev->cpu = cpu;
>>>>> +
>>>>> + ret = cpuidle_register_device(dev);
>>>>> + if (ret)
>>>>> + goto out_unregister;
>>>>> + }
>>>>> +
>>>>
>>>>
>>>> Isn't this racy with respect to CPU hotplug?
>>>
>>> No, I don't think so. Do you see a race ?
>>
>>
>> Well, that depends on when/where this function gets called.
>> This patch introduces the function. Where is the caller?
>
> There is no caller for the moment because they are in the different arch
> specific code in the different trees.
>
> But the callers will be in the init calls at boot up.
>
>> As of now, if you are calling this in boot-up code, its not racy.
>
> Most of the caller are in the boot-up code, in device_init or
> module_init. The other ones are doing some specific initialization on
> the cpuidle_device (cpuinit, like acpi) and can't use the
> cpuidle_register function.
>
>> However, there have been attempts to speed up boot times by trying
>> to online cpus in parallel with the rest of the kernel initialization[1].
>> In that case, unless your call is an early init call, it can race
>> with CPU hotplug.
>>
>> [1]. https://lkml.org/lkml/2012/1/30/647
>
> Aha ! Now I understand the race you were talking about. Thanks for the
> pointer. It is very interesting.
>
> I realize if the cpus boot up in parallel, that will break a lot of
> things and, for my concern, that will break most of the cpuidle drivers.
>
Exactly!
> So far the cpu bootup parallelization is not there, so from my POV, my
> patch is correct as we will factor out in a single place some code which
> will be potentially broken by this parallelization in the future. It
> will be easier to fix that in a single place rather in multiple drivers.
>
> Thanks for spotting this potential problem. This is something I will
> keep in mind for the future.
>
Sure, that would be great!
>>>>> +out:
>>>>> + return ret;
>>>>> +
>>>>> +out_unregister:
>>>>> + for_each_online_cpu(cpu) {
>>>>> + dev =&per_cpu(cpuidle_device, cpu);
>>>>> + cpuidle_unregister_device(dev);
>>>>> + }
>>>>> +
>>>>
>>>>
>>>> This could be improved I guess.. What if the registration fails
>>>> for the first cpu itself? Then looping over entire online cpumask
>>>> would be a waste of time..
>>>
>>> Certainly in a critical section that would make sense, but for 4,8 or 16
>>> cpus in an initialization path at boot time... Anyway, I can add what is
>>> proposed in https://lkml.org/lkml/2012/3/22/143.
>>>
>>
>>
>> What about servers with a lot more CPUs, like say 128 or even more? :-)
>>
>> Moreover I don't see any downsides to the optimization. So should be good
>> to add it in any case...
>
> Yes, no problem. I will add it.
>
Thanks!
Regards,
Srivatsa S. Bhat
IBM Linux Technology Center
^ permalink raw reply
* Re: [linux-pm] [PATCH 17/76] thermal_sys: convert printks to pr_<level>
From: Joe Perches @ 2012-03-30 19:08 UTC (permalink / raw)
To: eduardo.valentin
Cc: Len Brown, linux-acpi, linux-pm, Len Brown, Andrew Morton,
Jesper Juhl, linux-kernel
In-Reply-To: <20120330134119.GA13130@besouro>
On Fri, 2012-03-30 at 16:41 +0300, Eduardo Valentin wrote:
> On Fri, Mar 30, 2012 at 06:13:20AM -0400, Len Brown wrote:
> > From: Joe Perches <joe@perches.com>
> > Use the current logging style.
[]
> We should get the struct dev in thermal_zone_device, I think it makes
> more sense to use the dev_* helper functions.
[]
> The orig argument could probably be changed to a thermal zone device
> and the we use it's id as orig for the message.
> What do you think?
dev_<level> should be used instead of pr_<level> when
an appropriate struct device * is available.
cheers, Joe
^ permalink raw reply
* Re: [PATCH] cpuidle : use percpu cpuidle in the core code
From: Daniel Lezcano @ 2012-03-30 16:18 UTC (permalink / raw)
To: Srivatsa S. Bhat; +Cc: linux-pm, linaro-dev, patches
In-Reply-To: <4F75A015.2010609@linux.vnet.ibm.com>
On 03/30/2012 01:59 PM, Srivatsa S. Bhat wrote:
> On 03/30/2012 05:15 PM, Daniel Lezcano wrote:
>
>> On 03/30/2012 01:25 PM, Srivatsa S. Bhat wrote:
>>> On 03/30/2012 04:18 PM, Daniel Lezcano wrote:
>>>
>>>> The usual cpuidle initialization routines are to register the
>>>> driver, then register a cpuidle device per cpu.
>>>>
>>>> With the device's state count default initialization with the
>>>> driver's state count, the code initialization remains mostly the
>>>> same in the different drivers.
>>>>
>>>> We can then add a new function 'cpuidle_register' where we register
>>>> the driver and the devices. These devices can be defined in a global
>>>> static variable in cpuidle.c. We will be able to factor out and
>>>> remove a lot of duplicate lines of code.
>>>>
>>>> As we still have some drivers, with different initialization routines,
>>>> we keep 'cpuidle_register_driver' and 'cpuidle_register_device' as low
>>>> level initialization routines to do some specific operations on the
>>>> cpuidle devices.
>>>>
>>>> Signed-off-by: Daniel Lezcano<daniel.lezcano@linaro.org>
>>>> ---
>>>> drivers/cpuidle/cpuidle.c | 34 ++++++++++++++++++++++++++++++++++
>>>> include/linux/cpuidle.h | 3 +++
>>>> 2 files changed, 37 insertions(+), 0 deletions(-)
>>>>
>>>> diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
>>>> index b8a1faf..2a174e8 100644
>>>> --- a/drivers/cpuidle/cpuidle.c
>>>> +++ b/drivers/cpuidle/cpuidle.c
>>>> @@ -23,6 +23,7 @@
>>>> #include "cpuidle.h"
>>>>
>>>> DEFINE_PER_CPU(struct cpuidle_device *, cpuidle_devices);
>>>> +DEFINE_PER_CPU(struct cpuidle_device, cpuidle_device);
>>>>
>>>> DEFINE_MUTEX(cpuidle_lock);
>>>> LIST_HEAD(cpuidle_detected_devices);
>>>> @@ -391,6 +392,39 @@ int cpuidle_register_device(struct
>>>> cpuidle_device *dev)
>>>>
>>>> EXPORT_SYMBOL_GPL(cpuidle_register_device);
>>>>
>>>> +int cpuidle_register(struct cpuidle_driver *drv)
>>>> +{
>>>> + int ret, cpu;
>>>> + struct cpuidle_device *dev;
>>>> +
>>>> + ret = cpuidle_register_driver(drv);
>>>> + if (ret)
>>>> + return ret;
>>>> +
>>>> + for_each_online_cpu(cpu) {
>>>> + dev =&per_cpu(cpuidle_device, cpu);
>>>> + dev->cpu = cpu;
>>>> +
>>>> + ret = cpuidle_register_device(dev);
>>>> + if (ret)
>>>> + goto out_unregister;
>>>> + }
>>>> +
>>>
>>>
>>> Isn't this racy with respect to CPU hotplug?
>>
>> No, I don't think so. Do you see a race ?
>
>
> Well, that depends on when/where this function gets called.
> This patch introduces the function. Where is the caller?
There is no caller for the moment because they are in the different arch
specific code in the different trees.
But the callers will be in the init calls at boot up.
> As of now, if you are calling this in boot-up code, its not racy.
Most of the caller are in the boot-up code, in device_init or
module_init. The other ones are doing some specific initialization on
the cpuidle_device (cpuinit, like acpi) and can't use the
cpuidle_register function.
> However, there have been attempts to speed up boot times by trying
> to online cpus in parallel with the rest of the kernel initialization[1].
> In that case, unless your call is an early init call, it can race
> with CPU hotplug.
>
> [1]. https://lkml.org/lkml/2012/1/30/647
Aha ! Now I understand the race you were talking about. Thanks for the
pointer. It is very interesting.
I realize if the cpus boot up in parallel, that will break a lot of
things and, for my concern, that will break most of the cpuidle drivers.
So far the cpu bootup parallelization is not there, so from my POV, my
patch is correct as we will factor out in a single place some code which
will be potentially broken by this parallelization in the future. It
will be easier to fix that in a single place rather in multiple drivers.
Thanks for spotting this potential problem. This is something I will
keep in mind for the future.
>>>> +out:
>>>> + return ret;
>>>> +
>>>> +out_unregister:
>>>> + for_each_online_cpu(cpu) {
>>>> + dev =&per_cpu(cpuidle_device, cpu);
>>>> + cpuidle_unregister_device(dev);
>>>> + }
>>>> +
>>>
>>>
>>> This could be improved I guess.. What if the registration fails
>>> for the first cpu itself? Then looping over entire online cpumask
>>> would be a waste of time..
>>
>> Certainly in a critical section that would make sense, but for 4,8 or 16
>> cpus in an initialization path at boot time... Anyway, I can add what is
>> proposed in https://lkml.org/lkml/2012/3/22/143.
>>
>
>
> What about servers with a lot more CPUs, like say 128 or even more? :-)
>
> Moreover I don't see any downsides to the optimization. So should be good
> to add it in any case...
Yes, no problem. I will add it.
Thanks !
-- Daniel
--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
_______________________________________________
linux-pm mailing list
linux-pm@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/linux-pm
^ permalink raw reply
* Re: Regarding CPU idle C states
From: Zhichao Li @ 2012-03-30 15:48 UTC (permalink / raw)
To: Valentin, Eduardo; +Cc: ShuoX Liu, linux-pm
In-Reply-To: <CAGF5oy-igUy1GjB86hqnFF_ch5CqnDGO5rSJ_tQk1A6iammmpQ@mail.gmail.com>
Thanks for the email, Eduardo. It's useful.
Basically, we'd like to save power while maintaining performance in
storage systems with domain knowledge aware algorithm. Our previous
research papers can be found here:
http://www.fsl.cs.sunysb.edu/~zhicli/#_Publications
We can now start with the patch adding sysfs entry for C states and
provide kernel support, and try to play with them in the user level.
Regards,
On Fri, Mar 30, 2012 at 2:41 AM, Valentin, Eduardo
<eduardo.valentin@ti.com> wrote:
> Hello Zhichao,
>
> On Thu, Mar 29, 2012 at 11:58 PM, Zhichao Li <lzcmichael@gmail.com> wrote:
>> Hi,
>>
>> I am a third year PhD student working on power management in storage
>> systems, under the Linux platform.
>
> Good :-)
>
>>
>> We are exploring CPU DVFS, and also idle CPU C states. We figured out
>> that the scheduling of CPU frequencies is exported to user level with
>> the "userspace" governor. However, it seems the multiple idle C states
>> are only scheduled in the kernel space (governors like "menu" and
>> "ladder").
>
> OK. Which kind of exploration you are performing? Any published paper
> you would like to point?
>
>>
>> We wonder whether there is any existing kernel module or existing
>> kernel patch that can export the various idle CPU C states to the user
>> level for user's control as well. If you could guide us to such
>> code/patch, or if you have plan to do so, we'd be more than happy to
>> help you testing the code for various idle CPU C states in the user
>> level.
>
>
> Have you seen this patch?
> https://lkml.org/lkml/2012/3/5/30
>
> It's original purpose is for debugging. One can enable of disable the
> C states available. There has been some discussion about that patch
> regarding its usage for userspace based governors. But it should be
> enough for your purpose. In theory you could keep enabled only the C
> state you want to force to be reached.
>
>
>>
>> Thanks for your time. Appreciated it!
>>
>> Regards,
>>
>> --
>> Zhichao Li
>> File Systems and Storage Lab
>> Computer Science Department
>> Stony Brook University
>> _______________________________________________
>> linux-pm mailing list
>> linux-pm@lists.linux-foundation.org
>> https://lists.linuxfoundation.org/mailman/listinfo/linux-pm
>
>
>
> --
>
> Eduardo Valentin
--
Zhichao Li
File Systems and Storage Lab
Computer Science Department
Stony Brook University
^ 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