/** * struct cpuidle_cooling_device - data for the idle cooling device * @ii_dev: an atomic to keep track of the last task exiting the idle cycle * @state: a normalized integer giving the state of the cooling device
*/ struct cpuidle_cooling_device { struct idle_inject_device *ii_dev; unsignedlong state;
};
/** * cpuidle_cooling_runtime - Running time computation * @idle_duration_us: CPU idle time to inject in microseconds * @state: a percentile based number * * The running duration is computed from the idle injection duration * which is fixed. If we reach 100% of idle injection ratio, that * means the running duration is zero. If we have a 50% ratio * injection, that means we have equal duration for idle and for * running duration. * * The formula is deduced as follows: * * running = idle x ((100 / ratio) - 1) * * For precision purpose for integer math, we use the following: * * running = (idle x 100) / ratio - idle * * For example, if we have an injected duration of 50%, then we end up * with 10ms of idle injection and 10ms of running duration. * * Return: An unsigned int for a usec based runtime duration.
*/ staticunsignedint cpuidle_cooling_runtime(unsignedint idle_duration_us, unsignedlong state)
{ if (!state) return 0;
/** * cpuidle_cooling_get_max_state - Get the maximum state * @cdev : the thermal cooling device * @state : a pointer to the state variable to be filled * * The function always returns 100 as the injection ratio. It is * percentile based for consistency across different platforms. * * Return: The function can not fail, it is always zero
*/ staticint cpuidle_cooling_get_max_state(struct thermal_cooling_device *cdev, unsignedlong *state)
{ /* * Depending on the configuration or the hardware, the running * cycle and the idle cycle could be different. We want to * unify that to an 0..100 interval, so the set state * interface will be the same whatever the platform is. * * The state 100% will make the cluster 100% ... idle. A 0% * injection ratio means no idle injection at all and 50% * means for 10ms of idle injection, we have 10ms of running * time.
*/
*state = 100;
return 0;
}
/** * cpuidle_cooling_get_cur_state - Get the current cooling state * @cdev: the thermal cooling device * @state: a pointer to the state * * The function just copies the state value from the private thermal * cooling device structure, the mapping is 1 <-> 1. * * Return: The function can not fail, it is always zero
*/ staticint cpuidle_cooling_get_cur_state(struct thermal_cooling_device *cdev, unsignedlong *state)
{ struct cpuidle_cooling_device *idle_cdev = cdev->devdata;
*state = idle_cdev->state;
return 0;
}
/** * cpuidle_cooling_set_cur_state - Set the current cooling state * @cdev: the thermal cooling device * @state: the target state * * The function checks first if we are initiating the mitigation which * in turn wakes up all the idle injection tasks belonging to the idle * cooling device. In any case, it updates the internal state for the * cooling device. * * Return: The function can not fail, it is always zero
*/ staticint cpuidle_cooling_set_cur_state(struct thermal_cooling_device *cdev, unsignedlong state)
{ struct cpuidle_cooling_device *idle_cdev = cdev->devdata; struct idle_inject_device *ii_dev = idle_cdev->ii_dev; unsignedlong current_state = idle_cdev->state; unsignedint runtime_us, idle_duration_us;
/** * __cpuidle_cooling_register: register the cooling device * @drv: a cpuidle driver structure pointer * @np: a device node structure pointer used for the thermal binding * * This function is in charge of allocating the cpuidle cooling device * structure, the idle injection, initialize them and register the * cooling device to the thermal framework. * * Return: zero on success, a negative value returned by one of the * underlying subsystem in case of error
*/ staticint __cpuidle_cooling_register(struct device_node *np, struct cpuidle_driver *drv)
{ struct idle_inject_device *ii_dev; struct cpuidle_cooling_device *idle_cdev; struct thermal_cooling_device *cdev; struct device *dev; unsignedint idle_duration_us = TICK_USEC; unsignedint latency_us = UINT_MAX; char *name; int ret;
idle_cdev = kzalloc(sizeof(*idle_cdev), GFP_KERNEL); if (!idle_cdev) {
ret = -ENOMEM; goto out;
}
ii_dev = idle_inject_register(drv->cpumask); if (!ii_dev) {
ret = -EINVAL; goto out_kfree;
}
/** * cpuidle_cooling_register - Idle cooling device initialization function * @drv: a cpuidle driver structure pointer * * This function is in charge of creating a cooling device per cpuidle * driver and register it to the thermal framework.
*/ void cpuidle_cooling_register(struct cpuidle_driver *drv)
{ struct device_node *cooling_node; struct device_node *cpu_node; int cpu, ret;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.