linux-pm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] powercap/drivers/idle_inject: Specify idle state max latency
@ 2020-03-26 14:46 Daniel Lezcano
  2020-03-26 19:14 ` Rafael J. Wysocki
  0 siblings, 1 reply; 5+ messages in thread
From: Daniel Lezcano @ 2020-03-26 14:46 UTC (permalink / raw)
  To: rafael
  Cc: daniel.lezcano, Rafael J. Wysocki,
	open list:POWER MANAGEMENT CORE, open list

Currently the idle injection framework uses the play_idle() function
which puts the current CPU in an idle state. The idle state is the
deepest one, as specified by the latency constraint when calling the
subsequent play_idle_precise() function with the INT_MAX.

The idle_injection is used by the cpuidle_cooling device which
computes the idle / run duration to mitigate the temperature by
injecting idle cycles. The cooling device has no control on the depth
of the idle state.

Allow finer control of the idle injection mechanism by allowing to
specify the latency for the idle state. Thus the cooling device has
the ability to have a guarantee on the exit latency of the idle states
it is injecting.

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 drivers/powercap/idle_inject.c | 27 ++++++++++++++++++++++++++-
 include/linux/idle_inject.h    |  6 ++++++
 2 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/drivers/powercap/idle_inject.c b/drivers/powercap/idle_inject.c
index cd1270614cc6..15e6f9b8023f 100644
--- a/drivers/powercap/idle_inject.c
+++ b/drivers/powercap/idle_inject.c
@@ -61,12 +61,14 @@ struct idle_inject_thread {
  * @timer: idle injection period timer
  * @idle_duration_us: duration of CPU idle time to inject
  * @run_duration_us: duration of CPU run time to allow
+ * @latency_us: max allowed latency
  * @cpumask: mask of CPUs affected by idle injection
  */
 struct idle_inject_device {
 	struct hrtimer timer;
 	unsigned int idle_duration_us;
 	unsigned int run_duration_us;
+	unsigned int latency_us;
 	unsigned long int cpumask[0];
 };
 
@@ -138,7 +140,8 @@ static void idle_inject_fn(unsigned int cpu)
 	 */
 	iit->should_run = 0;
 
-	play_idle(READ_ONCE(ii_dev->idle_duration_us));
+	play_idle_precise(READ_ONCE(ii_dev->idle_duration_us) * NSEC_PER_USEC,
+			  READ_ONCE(ii_dev->latency_us) * NSEC_PER_USEC);
 }
 
 /**
@@ -169,6 +172,27 @@ void idle_inject_get_duration(struct idle_inject_device *ii_dev,
 	*idle_duration_us = READ_ONCE(ii_dev->idle_duration_us);
 }
 
+/**
+ * idle_inject_set_latency - set the maximum latency allowed
+ * @latency_us: set the latency requirement for the idle state
+ */
+void idle_inject_set_latency(struct idle_inject_device *ii_dev,
+			     unsigned int latency_us)
+{
+	WRITE_ONCE(ii_dev->latency_us, latency_us);
+}
+
+/**
+ * idle_inject_get_latency - get the allowed latency
+ *
+ * Return: an unsigned int corresponding to the latency requirement
+ * for the idle state
+ */
+unsigned int idle_inject_get_latency(struct idle_inject_device *ii_dev)
+{
+	return READ_ONCE(ii_dev->latency_us);
+}
+
 /**
  * idle_inject_start - start idle injections
  * @ii_dev: idle injection control device structure
@@ -297,6 +321,7 @@ struct idle_inject_device *idle_inject_register(struct cpumask *cpumask)
 	cpumask_copy(to_cpumask(ii_dev->cpumask), cpumask);
 	hrtimer_init(&ii_dev->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
 	ii_dev->timer.function = idle_inject_timer_fn;
+	ii_dev->latency_us = UINT_MAX;
 
 	for_each_cpu(cpu, to_cpumask(ii_dev->cpumask)) {
 
diff --git a/include/linux/idle_inject.h b/include/linux/idle_inject.h
index a445cd1a36c5..b573fee589b9 100644
--- a/include/linux/idle_inject.h
+++ b/include/linux/idle_inject.h
@@ -26,4 +26,10 @@ void idle_inject_set_duration(struct idle_inject_device *ii_dev,
 void idle_inject_get_duration(struct idle_inject_device *ii_dev,
 				 unsigned int *run_duration_us,
 				 unsigned int *idle_duration_us);
+
+void idle_inject_set_latency(struct idle_inject_device *ii_dev,
+			     unsigned int latency_ns);
+
+unsigned int idle_inject_get_latency(struct idle_inject_device *ii_dev);
+
 #endif /* __IDLE_INJECT_H__ */
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] powercap/drivers/idle_inject: Specify idle state max latency
  2020-03-26 14:46 [PATCH] powercap/drivers/idle_inject: Specify idle state max latency Daniel Lezcano
@ 2020-03-26 19:14 ` Rafael J. Wysocki
  2020-03-26 19:20   ` Daniel Lezcano
  0 siblings, 1 reply; 5+ messages in thread
From: Rafael J. Wysocki @ 2020-03-26 19:14 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Rafael J. Wysocki, Rafael J. Wysocki,
	open list:POWER MANAGEMENT CORE, open list

On Thu, Mar 26, 2020 at 3:48 PM Daniel Lezcano
<daniel.lezcano@linaro.org> wrote:
>
> Currently the idle injection framework uses the play_idle() function
> which puts the current CPU in an idle state. The idle state is the
> deepest one, as specified by the latency constraint when calling the
> subsequent play_idle_precise() function with the INT_MAX.
>
> The idle_injection is used by the cpuidle_cooling device which
> computes the idle / run duration to mitigate the temperature by
> injecting idle cycles. The cooling device has no control on the depth
> of the idle state.
>
> Allow finer control of the idle injection mechanism by allowing to
> specify the latency for the idle state. Thus the cooling device has
> the ability to have a guarantee on the exit latency of the idle states
> it is injecting.
>
> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> ---
>  drivers/powercap/idle_inject.c | 27 ++++++++++++++++++++++++++-
>  include/linux/idle_inject.h    |  6 ++++++
>  2 files changed, 32 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/powercap/idle_inject.c b/drivers/powercap/idle_inject.c
> index cd1270614cc6..15e6f9b8023f 100644
> --- a/drivers/powercap/idle_inject.c
> +++ b/drivers/powercap/idle_inject.c
> @@ -61,12 +61,14 @@ struct idle_inject_thread {
>   * @timer: idle injection period timer
>   * @idle_duration_us: duration of CPU idle time to inject
>   * @run_duration_us: duration of CPU run time to allow
> + * @latency_us: max allowed latency
>   * @cpumask: mask of CPUs affected by idle injection
>   */
>  struct idle_inject_device {
>         struct hrtimer timer;
>         unsigned int idle_duration_us;
>         unsigned int run_duration_us;
> +       unsigned int latency_us;
>         unsigned long int cpumask[0];
>  };
>
> @@ -138,7 +140,8 @@ static void idle_inject_fn(unsigned int cpu)
>          */
>         iit->should_run = 0;
>
> -       play_idle(READ_ONCE(ii_dev->idle_duration_us));
> +       play_idle_precise(READ_ONCE(ii_dev->idle_duration_us) * NSEC_PER_USEC,
> +                         READ_ONCE(ii_dev->latency_us) * NSEC_PER_USEC);
>  }
>
>  /**
> @@ -169,6 +172,27 @@ void idle_inject_get_duration(struct idle_inject_device *ii_dev,
>         *idle_duration_us = READ_ONCE(ii_dev->idle_duration_us);
>  }
>
> +/**
> + * idle_inject_set_latency - set the maximum latency allowed
> + * @latency_us: set the latency requirement for the idle state
> + */
> +void idle_inject_set_latency(struct idle_inject_device *ii_dev,
> +                            unsigned int latency_us)
> +{
> +       WRITE_ONCE(ii_dev->latency_us, latency_us);
> +}
> +
> +/**
> + * idle_inject_get_latency - get the allowed latency
> + *
> + * Return: an unsigned int corresponding to the latency requirement
> + * for the idle state
> + */
> +unsigned int idle_inject_get_latency(struct idle_inject_device *ii_dev)
> +{
> +       return READ_ONCE(ii_dev->latency_us);
> +}
> +
>  /**
>   * idle_inject_start - start idle injections
>   * @ii_dev: idle injection control device structure
> @@ -297,6 +321,7 @@ struct idle_inject_device *idle_inject_register(struct cpumask *cpumask)
>         cpumask_copy(to_cpumask(ii_dev->cpumask), cpumask);
>         hrtimer_init(&ii_dev->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
>         ii_dev->timer.function = idle_inject_timer_fn;
> +       ii_dev->latency_us = UINT_MAX;
>
>         for_each_cpu(cpu, to_cpumask(ii_dev->cpumask)) {
>
> diff --git a/include/linux/idle_inject.h b/include/linux/idle_inject.h
> index a445cd1a36c5..b573fee589b9 100644
> --- a/include/linux/idle_inject.h
> +++ b/include/linux/idle_inject.h
> @@ -26,4 +26,10 @@ void idle_inject_set_duration(struct idle_inject_device *ii_dev,
>  void idle_inject_get_duration(struct idle_inject_device *ii_dev,
>                                  unsigned int *run_duration_us,
>                                  unsigned int *idle_duration_us);
> +
> +void idle_inject_set_latency(struct idle_inject_device *ii_dev,
> +                            unsigned int latency_ns);
> +
> +unsigned int idle_inject_get_latency(struct idle_inject_device *ii_dev);
> +
>  #endif /* __IDLE_INJECT_H__ */
> --

I would like to see a user of idle_inject_get_latency() before this goes in.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] powercap/drivers/idle_inject: Specify idle state max latency
  2020-03-26 19:14 ` Rafael J. Wysocki
@ 2020-03-26 19:20   ` Daniel Lezcano
  2020-03-26 19:37     ` Rafael J. Wysocki
  0 siblings, 1 reply; 5+ messages in thread
From: Daniel Lezcano @ 2020-03-26 19:20 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Rafael J. Wysocki, open list:POWER MANAGEMENT CORE, open list

On 26/03/2020 20:14, Rafael J. Wysocki wrote:
> On Thu, Mar 26, 2020 at 3:48 PM Daniel Lezcano
> <daniel.lezcano@linaro.org> wrote:
>>
>> Currently the idle injection framework uses the play_idle()
>> function which puts the current CPU in an idle state. The idle
>> state is the deepest one, as specified by the latency constraint
>> when calling the subsequent play_idle_precise() function with the
>> INT_MAX.
>>
>> The idle_injection is used by the cpuidle_cooling device which
>> computes the idle / run duration to mitigate the temperature by
>> injecting idle cycles. The cooling device has no control on the
>> depth of the idle state.
>>
>> Allow finer control of the idle injection mechanism by allowing
>> to specify the latency for the idle state. Thus the cooling
>> device has the ability to have a guarantee on the exit latency of
>> the idle states it is injecting.
>>
>> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> ---
>> drivers/powercap/idle_inject.c | 27 ++++++++++++++++++++++++++-
>> include/linux/idle_inject.h    |  6 ++++++ 2 files changed, 32
>> insertions(+), 1 deletion(-)

[ ... ]

>> + +void idle_inject_set_latency(struct idle_inject_device
>> *ii_dev, +                            unsigned int latency_ns);
>> + +unsigned int idle_inject_get_latency(struct idle_inject_device
>> *ii_dev); + #endif /* __IDLE_INJECT_H__ */ --
>
> I would like to see a user of idle_inject_get_latency() before this
> goes in.

Do you mean a user for the set/get or the get only? If the latter,
there is no user yet I just added it to have an usual get/set helpers,
if that hurts, I can resend by removing it. If the former, there is a
patch I'm about to send which depends on the 'set'.


-- 
<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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] powercap/drivers/idle_inject: Specify idle state max latency
  2020-03-26 19:20   ` Daniel Lezcano
@ 2020-03-26 19:37     ` Rafael J. Wysocki
  2020-03-26 19:47       ` Daniel Lezcano
  0 siblings, 1 reply; 5+ messages in thread
From: Rafael J. Wysocki @ 2020-03-26 19:37 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Rafael J. Wysocki, Rafael J. Wysocki,
	open list:POWER MANAGEMENT CORE, open list

On Thu, Mar 26, 2020 at 8:20 PM Daniel Lezcano
<daniel.lezcano@linaro.org> wrote:
>
> On 26/03/2020 20:14, Rafael J. Wysocki wrote:
> > On Thu, Mar 26, 2020 at 3:48 PM Daniel Lezcano
> > <daniel.lezcano@linaro.org> wrote:
> >>
> >> Currently the idle injection framework uses the play_idle()
> >> function which puts the current CPU in an idle state. The idle
> >> state is the deepest one, as specified by the latency constraint
> >> when calling the subsequent play_idle_precise() function with the
> >> INT_MAX.
> >>
> >> The idle_injection is used by the cpuidle_cooling device which
> >> computes the idle / run duration to mitigate the temperature by
> >> injecting idle cycles. The cooling device has no control on the
> >> depth of the idle state.
> >>
> >> Allow finer control of the idle injection mechanism by allowing
> >> to specify the latency for the idle state. Thus the cooling
> >> device has the ability to have a guarantee on the exit latency of
> >> the idle states it is injecting.
> >>
> >> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> ---
> >> drivers/powercap/idle_inject.c | 27 ++++++++++++++++++++++++++-
> >> include/linux/idle_inject.h    |  6 ++++++ 2 files changed, 32
> >> insertions(+), 1 deletion(-)
>
> [ ... ]
>
> >> + +void idle_inject_set_latency(struct idle_inject_device
> >> *ii_dev, +                            unsigned int latency_ns);
> >> + +unsigned int idle_inject_get_latency(struct idle_inject_device
> >> *ii_dev); + #endif /* __IDLE_INJECT_H__ */ --
> >
> > I would like to see a user of idle_inject_get_latency() before this
> > goes in.
>
> Do you mean a user for the set/get or the get only? If the latter,
> there is no user yet I just added it to have an usual get/set helpers,
> if that hurts, I can resend by removing it. If the former, there is a
> patch I'm about to send which depends on the 'set'.

So I wouldn't add the "get" thing at all if it has no users.

Also it would be better to send this patch along with the other one
depending on it.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] powercap/drivers/idle_inject: Specify idle state max latency
  2020-03-26 19:37     ` Rafael J. Wysocki
@ 2020-03-26 19:47       ` Daniel Lezcano
  0 siblings, 0 replies; 5+ messages in thread
From: Daniel Lezcano @ 2020-03-26 19:47 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Rafael J. Wysocki, open list:POWER MANAGEMENT CORE, open list

On 26/03/2020 20:37, Rafael J. Wysocki wrote:
> On Thu, Mar 26, 2020 at 8:20 PM Daniel Lezcano
> <daniel.lezcano@linaro.org> wrote:
>>
>> On 26/03/2020 20:14, Rafael J. Wysocki wrote:
>>> On Thu, Mar 26, 2020 at 3:48 PM Daniel Lezcano
>>> <daniel.lezcano@linaro.org> wrote:
>>>>
>>>> Currently the idle injection framework uses the play_idle()
>>>> function which puts the current CPU in an idle state. The
>>>> idle state is the deepest one, as specified by the latency
>>>> constraint when calling the subsequent play_idle_precise()
>>>> function with the INT_MAX.
>>>>
>>>> The idle_injection is used by the cpuidle_cooling device
>>>> which computes the idle / run duration to mitigate the
>>>> temperature by injecting idle cycles. The cooling device has
>>>> no control on the depth of the idle state.
>>>>
>>>> Allow finer control of the idle injection mechanism by
>>>> allowing to specify the latency for the idle state. Thus the
>>>> cooling device has the ability to have a guarantee on the
>>>> exit latency of the idle states it is injecting.
>>>>
>>>> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
>>>> --- drivers/powercap/idle_inject.c | 27
>>>> ++++++++++++++++++++++++++- include/linux/idle_inject.h    |
>>>> 6 ++++++ 2 files changed, 32 insertions(+), 1 deletion(-)
>>
>> [ ... ]
>>
>>>> + +void idle_inject_set_latency(struct idle_inject_device
>>>> *ii_dev, +                            unsigned int
>>>> latency_ns); + +unsigned int idle_inject_get_latency(struct
>>>> idle_inject_device *ii_dev); + #endif /* __IDLE_INJECT_H__ */
>>>> --
>>>
>>> I would like to see a user of idle_inject_get_latency() before
>>> this goes in.
>>
>> Do you mean a user for the set/get or the get only? If the
>> latter, there is no user yet I just added it to have an usual
>> get/set helpers, if that hurts, I can resend by removing it. If
>> the former, there is a patch I'm about to send which depends on
>> the 'set'.
>
> So I wouldn't add the "get" thing at all if it has no users.

Ok

> Also it would be better to send this patch along with the other
> one depending on it.

Sure will resend along with the other patches.



-- 
<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

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-03-26 19:47 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-26 14:46 [PATCH] powercap/drivers/idle_inject: Specify idle state max latency Daniel Lezcano
2020-03-26 19:14 ` Rafael J. Wysocki
2020-03-26 19:20   ` Daniel Lezcano
2020-03-26 19:37     ` Rafael J. Wysocki
2020-03-26 19:47       ` Daniel Lezcano

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).