mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 17:30:02 +00:00
![Qais Yousef](/assets/img/avatar_default.png)
RT tasks by default run at the highest capacity/performance level. When uclamp is selected this default behavior is retained by enforcing the requested uclamp.min (p->uclamp_req[UCLAMP_MIN]) of the RT tasks to be uclamp_none(UCLAMP_MAX), which is SCHED_CAPACITY_SCALE; the maximum value. This is also referred to as 'the default boost value of RT tasks'. See commit1a00d99997
("sched/uclamp: Set default clamps for RT tasks"). On battery powered devices, it is desired to control this default (currently hardcoded) behavior at runtime to reduce energy consumed by RT tasks. For example, a mobile device manufacturer where big.LITTLE architecture is dominant, the performance of the little cores varies across SoCs, and on high end ones the big cores could be too power hungry. Given the diversity of SoCs, the new knob allows manufactures to tune the best performance/power for RT tasks for the particular hardware they run on. They could opt to further tune the value when the user selects a different power saving mode or when the device is actively charging. The runtime aspect of it further helps in creating a single kernel image that can be run on multiple devices that require different tuning. Keep in mind that a lot of RT tasks in the system are created by the kernel. On Android for instance I can see over 50 RT tasks, only a handful of which created by the Android framework. To control the default behavior globally by system admins and device integrator, introduce the new sysctl_sched_uclamp_util_min_rt_default to change the default boost value of the RT tasks. I anticipate this to be mostly in the form of modifying the init script of a particular device. To avoid polluting the fast path with unnecessary code, the approach taken is to synchronously do the update by traversing all the existing tasks in the system. This could race with a concurrent fork(), which is dealt with by introducing sched_post_fork() function which will ensure the racy fork will get the right update applied. Tested on Juno-r2 in combination with the RT capacity awareness [1]. By default an RT task will go to the highest capacity CPU and run at the maximum frequency, which is particularly energy inefficient on high end mobile devices because the biggest core[s] are 'huge' and power hungry. With this patch the RT task can be controlled to run anywhere by default, and doesn't cause the frequency to be maximum all the time. Yet any task that really needs to be boosted can easily escape this default behavior by modifying its requested uclamp.min value (p->uclamp_req[UCLAMP_MIN]) via sched_setattr() syscall. [1]804d402fb6
: ("sched/rt: Make RT capacity-aware") Signed-off-by: Qais Yousef <qais.yousef@arm.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lkml.kernel.org/r/20200716110347.19553-2-qais.yousef@arm.com
101 lines
3.2 KiB
C
101 lines
3.2 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _LINUX_SCHED_SYSCTL_H
|
|
#define _LINUX_SCHED_SYSCTL_H
|
|
|
|
#include <linux/types.h>
|
|
|
|
struct ctl_table;
|
|
|
|
#ifdef CONFIG_DETECT_HUNG_TASK
|
|
|
|
#ifdef CONFIG_SMP
|
|
extern unsigned int sysctl_hung_task_all_cpu_backtrace;
|
|
#else
|
|
#define sysctl_hung_task_all_cpu_backtrace 0
|
|
#endif /* CONFIG_SMP */
|
|
|
|
extern int sysctl_hung_task_check_count;
|
|
extern unsigned int sysctl_hung_task_panic;
|
|
extern unsigned long sysctl_hung_task_timeout_secs;
|
|
extern unsigned long sysctl_hung_task_check_interval_secs;
|
|
extern int sysctl_hung_task_warnings;
|
|
int proc_dohung_task_timeout_secs(struct ctl_table *table, int write,
|
|
void *buffer, size_t *lenp, loff_t *ppos);
|
|
#else
|
|
/* Avoid need for ifdefs elsewhere in the code */
|
|
enum { sysctl_hung_task_timeout_secs = 0 };
|
|
#endif
|
|
|
|
extern unsigned int sysctl_sched_latency;
|
|
extern unsigned int sysctl_sched_min_granularity;
|
|
extern unsigned int sysctl_sched_wakeup_granularity;
|
|
extern unsigned int sysctl_sched_child_runs_first;
|
|
|
|
enum sched_tunable_scaling {
|
|
SCHED_TUNABLESCALING_NONE,
|
|
SCHED_TUNABLESCALING_LOG,
|
|
SCHED_TUNABLESCALING_LINEAR,
|
|
SCHED_TUNABLESCALING_END,
|
|
};
|
|
extern enum sched_tunable_scaling sysctl_sched_tunable_scaling;
|
|
|
|
extern unsigned int sysctl_numa_balancing_scan_delay;
|
|
extern unsigned int sysctl_numa_balancing_scan_period_min;
|
|
extern unsigned int sysctl_numa_balancing_scan_period_max;
|
|
extern unsigned int sysctl_numa_balancing_scan_size;
|
|
|
|
#ifdef CONFIG_SCHED_DEBUG
|
|
extern __read_mostly unsigned int sysctl_sched_migration_cost;
|
|
extern __read_mostly unsigned int sysctl_sched_nr_migrate;
|
|
|
|
int sched_proc_update_handler(struct ctl_table *table, int write,
|
|
void *buffer, size_t *length, loff_t *ppos);
|
|
#endif
|
|
|
|
/*
|
|
* control realtime throttling:
|
|
*
|
|
* /proc/sys/kernel/sched_rt_period_us
|
|
* /proc/sys/kernel/sched_rt_runtime_us
|
|
*/
|
|
extern unsigned int sysctl_sched_rt_period;
|
|
extern int sysctl_sched_rt_runtime;
|
|
|
|
extern unsigned int sysctl_sched_dl_period_max;
|
|
extern unsigned int sysctl_sched_dl_period_min;
|
|
|
|
#ifdef CONFIG_UCLAMP_TASK
|
|
extern unsigned int sysctl_sched_uclamp_util_min;
|
|
extern unsigned int sysctl_sched_uclamp_util_max;
|
|
extern unsigned int sysctl_sched_uclamp_util_min_rt_default;
|
|
#endif
|
|
|
|
#ifdef CONFIG_CFS_BANDWIDTH
|
|
extern unsigned int sysctl_sched_cfs_bandwidth_slice;
|
|
#endif
|
|
|
|
#ifdef CONFIG_SCHED_AUTOGROUP
|
|
extern unsigned int sysctl_sched_autogroup_enabled;
|
|
#endif
|
|
|
|
extern int sysctl_sched_rr_timeslice;
|
|
extern int sched_rr_timeslice;
|
|
|
|
int sched_rr_handler(struct ctl_table *table, int write, void *buffer,
|
|
size_t *lenp, loff_t *ppos);
|
|
int sched_rt_handler(struct ctl_table *table, int write, void *buffer,
|
|
size_t *lenp, loff_t *ppos);
|
|
int sysctl_sched_uclamp_handler(struct ctl_table *table, int write,
|
|
void *buffer, size_t *lenp, loff_t *ppos);
|
|
int sysctl_numa_balancing(struct ctl_table *table, int write, void *buffer,
|
|
size_t *lenp, loff_t *ppos);
|
|
int sysctl_schedstats(struct ctl_table *table, int write, void *buffer,
|
|
size_t *lenp, loff_t *ppos);
|
|
|
|
#if defined(CONFIG_ENERGY_MODEL) && defined(CONFIG_CPU_FREQ_GOV_SCHEDUTIL)
|
|
extern unsigned int sysctl_sched_energy_aware;
|
|
int sched_energy_aware_handler(struct ctl_table *table, int write,
|
|
void *buffer, size_t *lenp, loff_t *ppos);
|
|
#endif
|
|
|
|
#endif /* _LINUX_SCHED_SYSCTL_H */
|