Messages in this thread Patch in this message | | | From | Yun Hsiang <> | Subject | [PATCH v3 1/1] sched/uclamp: add SCHED_FLAG_UTIL_CLAMP_RESET flag to reset uclamp | Date | Sun, 25 Oct 2020 15:36:32 +0800 |
| |
If the user wants to stop controlling uclamp and let the task inherit the value from the group, we need a method to reset.
Add SCHED_FLAG_UTIL_CLAMP_RESET flag to allow the user to reset uclamp via sched_setattr syscall.
The policy is _CLAMP_RESET => reset both min and max _CLAMP_RESET | _CLAMP_MIN => reset min value _CLAMP_RESET | _CLAMP_MAX => reset max value _CLAMP_RESET | _CLAMP_MIN | _CLAMP_MAX => reset both min and max
Signed-off-by: Yun Hsiang <hsiang023167@gmail.com> --- include/uapi/linux/sched.h | 7 +++++-- kernel/sched/core.c | 41 +++++++++++++++++++++++++++++++------- 2 files changed, 39 insertions(+), 9 deletions(-)
diff --git a/include/uapi/linux/sched.h b/include/uapi/linux/sched.h index 3bac0a8ceab2..6c823ddb1a1e 100644 --- a/include/uapi/linux/sched.h +++ b/include/uapi/linux/sched.h @@ -132,17 +132,20 @@ struct clone_args { #define SCHED_FLAG_KEEP_PARAMS 0x10 #define SCHED_FLAG_UTIL_CLAMP_MIN 0x20 #define SCHED_FLAG_UTIL_CLAMP_MAX 0x40 +#define SCHED_FLAG_UTIL_CLAMP_RESET 0x80 #define SCHED_FLAG_KEEP_ALL (SCHED_FLAG_KEEP_POLICY | \ SCHED_FLAG_KEEP_PARAMS) #define SCHED_FLAG_UTIL_CLAMP (SCHED_FLAG_UTIL_CLAMP_MIN | \ - SCHED_FLAG_UTIL_CLAMP_MAX) + SCHED_FLAG_UTIL_CLAMP_MAX | \ + SCHED_FLAG_UTIL_CLAMP_RESET) #define SCHED_FLAG_ALL (SCHED_FLAG_RESET_ON_FORK | \ SCHED_FLAG_RECLAIM | \ SCHED_FLAG_DL_OVERRUN | \ SCHED_FLAG_KEEP_ALL | \ - SCHED_FLAG_UTIL_CLAMP) + SCHED_FLAG_UTIL_CLAMP | \ + SCHED_FLAG_UTIL_CLAMP_RESET) #endif /* _UAPI_LINUX_SCHED_H */ diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 8160ab5263f8..b337f8d3b5ae 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -1438,9 +1438,22 @@ static int uclamp_validate(struct task_struct *p, return 0; } +static unsigned int __default_uclamp_value(struct task_struct *p, + int clamp_id) +{ + if (rt_task(p) && clamp_id == UCLAMP_MIN) + return sysctl_sched_uclamp_util_min_rt_default; + else + return uclamp_none(clamp_id); +} + static void __setscheduler_uclamp(struct task_struct *p, const struct sched_attr *attr) { + int reset = attr->sched_flags & SCHED_FLAG_UTIL_CLAMP_RESET; + bool user_defined; + unsigned int clamp_value; + unsigned long flags = attr->sched_flags & SCHED_FLAG_UTIL_CLAMP; enum uclamp_id clamp_id; /* @@ -1451,7 +1464,8 @@ static void __setscheduler_uclamp(struct task_struct *p, struct uclamp_se *uc_se = &p->uclamp_req[clamp_id]; /* Keep using defined clamps across class changes */ - if (uc_se->user_defined) + if (flags != SCHED_FLAG_UTIL_CLAMP_RESET && + uc_se->user_defined) continue; /* @@ -1462,20 +1476,33 @@ static void __setscheduler_uclamp(struct task_struct *p, __uclamp_update_util_min_rt_default(p); else uclamp_se_set(uc_se, uclamp_none(clamp_id), false); - } - if (likely(!(attr->sched_flags & SCHED_FLAG_UTIL_CLAMP))) + if (likely(!flags || flags == SCHED_FLAG_UTIL_CLAMP_RESET)) return; - if (attr->sched_flags & SCHED_FLAG_UTIL_CLAMP_MIN) { + if (flags & SCHED_FLAG_UTIL_CLAMP_MIN) { + if (reset) { + clamp_value = __default_uclamp_value(p, UCLAMP_MIN); + user_defined = false; + } else { + clamp_value = attr->sched_util_min; + user_defined = true; + } uclamp_se_set(&p->uclamp_req[UCLAMP_MIN], - attr->sched_util_min, true); + clamp_value, user_defined); } - if (attr->sched_flags & SCHED_FLAG_UTIL_CLAMP_MAX) { + if (flags & SCHED_FLAG_UTIL_CLAMP_MAX) { + if (reset) { + clamp_value = __default_uclamp_value(p, UCLAMP_MAX); + user_defined = false; + } else { + clamp_value = attr->sched_util_max; + user_defined = true; + } uclamp_se_set(&p->uclamp_req[UCLAMP_MAX], - attr->sched_util_max, true); + clamp_value, user_defined); } } -- 2.25.1
| |