mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-11-01 17:08:10 +00:00
acbc661032
The powercap/idle_inject core uses play_idle_precise() to inject idle time. But play_idle_precise() can't ensure that the CPU is fully idle for the specified duration because of wakeups due to interrupts. To compensate for the reduced idle time due to these wakes, the caller can adjust requested idle time for the next cycle. The goal of idle injection is to keep system at some idle percent on average, so this is fine to overshoot or undershoot instantaneous idle times. The idle inject core provides an interface idle_inject_set_duration() to set idle and runtime duration. Some architectures provide interface to get actual idle time observed by the hardware. So, the effective idle percent can be adjusted using the hardware feedback. For example, Intel CPUs provides package idle counters, which is currently used by Intel powerclamp driver to readjust runtime duration. When the caller's desired idle time over a period is less or greater than the actual CPU idle time observed by the hardware, caller can readjust idle and runtime duration for the next cycle. The only way this can be done currently is by monitoring hardware idle time from a different software thread and readjust idle and runtime duration using idle_inject_set_duration(). This can be avoided by adding a callback which callers can register and readjust from this callback function. Add a capability to register an optional update() callback, which can be called from the idle inject core before waking up CPUs for idle injection. This callback can be registered via a new interface: idle_inject_register_full(). During this process of constantly adjusting idle and runtime duration there can be some cases where actual idle time is more than the desired. In this case idle inject can be skipped for a cycle. If update() callback returns false, then the idle inject core skips waking up CPUs for the idle injection. Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
36 lines
1 KiB
C
36 lines
1 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* Copyright (C) 2018 Linaro Ltd
|
|
*
|
|
* Author: Daniel Lezcano <daniel.lezcano@linaro.org>
|
|
*
|
|
*/
|
|
#ifndef __IDLE_INJECT_H__
|
|
#define __IDLE_INJECT_H__
|
|
|
|
/* private idle injection device structure */
|
|
struct idle_inject_device;
|
|
|
|
struct idle_inject_device *idle_inject_register(struct cpumask *cpumask);
|
|
|
|
struct idle_inject_device *idle_inject_register_full(struct cpumask *cpumask,
|
|
bool (*update)(void));
|
|
|
|
void idle_inject_unregister(struct idle_inject_device *ii_dev);
|
|
|
|
int idle_inject_start(struct idle_inject_device *ii_dev);
|
|
|
|
void idle_inject_stop(struct idle_inject_device *ii_dev);
|
|
|
|
void idle_inject_set_duration(struct idle_inject_device *ii_dev,
|
|
unsigned int run_duration_us,
|
|
unsigned int idle_duration_us);
|
|
|
|
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_us);
|
|
|
|
#endif /* __IDLE_INJECT_H__ */
|