History

sched/uclamp: Add a new sysctl to control RT default boost value

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 commit 1a00d999971c ("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] 804d402fb6f6: ("sched/rt: Make RT capacity-aware")

Qais Yousef committed 6 years ago

Commit 13685c41 parent e65855a6 files · +131 −8Browse files

Showing the changes to include/linux (3 of 6 files). Show all

Unified · Split

3 files
  1. include/linux/sched.h +8 −2
  2. include/linux/sched/sysctl.h +1 −0
  3. include/linux/sched/task.h +1 −0
include/linux/sched.h+8−2
@@ -686,9 +686,15 @@ struct task_struct { · 685 unmodified lines
686 struct sched_dl_entity dl;686 struct sched_dl_entity dl;
687 687
688#ifdef CONFIG_UCLAMP_TASK688#ifdef CONFIG_UCLAMP_TASK
689 /* Clamp values requested for a scheduling entity */689 /*
690 * Clamp values requested for a scheduling entity.
691 * Must be updated with task_rq_lock() held.
692 */
690 struct uclamp_se uclamp_req[UCLAMP_CNT];693 struct uclamp_se uclamp_req[UCLAMP_CNT];
691 /* Effective clamp values used for a scheduling entity */694 /*
695 * Effective clamp values used for a scheduling entity.
696 * Must be updated with task_rq_lock() held.
697 */
692 struct uclamp_se uclamp[UCLAMP_CNT];698 struct uclamp_se uclamp[UCLAMP_CNT];
693#endif699#endif
694 700
include/linux/sched/sysctl.h+1−0
@@ -67,6 +67,7 @@ extern unsigned int sysctl_sched_dl_period_min; · 66 unmodified lines
67#ifdef CONFIG_UCLAMP_TASK67#ifdef CONFIG_UCLAMP_TASK
68extern unsigned int sysctl_sched_uclamp_util_min;68extern unsigned int sysctl_sched_uclamp_util_min;
69extern unsigned int sysctl_sched_uclamp_util_max;69extern unsigned int sysctl_sched_uclamp_util_max;
70extern unsigned int sysctl_sched_uclamp_util_min_rt_default;
70#endif71#endif
71 72
72#ifdef CONFIG_CFS_BANDWIDTH73#ifdef CONFIG_CFS_BANDWIDTH
include/linux/sched/task.h+1−0
@@ -55,6 +55,7 @@ extern asmlinkage void schedule_tail(struct task_struct *prev); · 54 unmodified lines
55extern void init_idle(struct task_struct *idle, int cpu);55extern void init_idle(struct task_struct *idle, int cpu);
56 56
57extern int sched_fork(unsigned long clone_flags, struct task_struct *p);57extern int sched_fork(unsigned long clone_flags, struct task_struct *p);
58extern void sched_post_fork(struct task_struct *p);
58extern void sched_dead(struct task_struct *p);59extern void sched_dead(struct task_struct *p);
59 60
60void __noreturn do_task_dead(void);61void __noreturn do_task_dead(void);