Messages in this thread | | | From | "Rafael J. Wysocki" <> | Date | Thu, 26 Mar 2020 20:14:34 +0100 | Subject | Re: [PATCH] powercap/drivers/idle_inject: Specify idle state max latency |
| |
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.
| |