[Toybox] more general sched_setattr/sched_getattr command?

enh enh at google.com
Thu Jan 13 12:44:50 PST 2022


here's the response i got:

the logic has been changed as
https://lore.kernel.org/all/20210617165155.3774110-1-qais.yousef@arm.com/T/#u
partially

uclamp_tg_restrict is the one to apply group value towards per-task value.

static inline struct uclamp_se

uclamp_tg_restrict(struct task_struct *p, enum uclamp_id clamp_id)
{
/* Copy by value as we could modify it */
struct uclamp_se uc_req = p->uclamp_req[clamp_id];
#ifdef CONFIG_UCLAMP_TASK_GROUP
unsigned int tg_min, tg_max, value;

/*
* Tasks in autogroups or root task group will be
* restricted by system defaults.
*/
if (task_group_is_autogroup(task_group(p)))
return uc_req;
if (task_group(p) == &root_task_group)
return uc_req;

tg_min = task_group(p)->uclamp[UCLAMP_MIN].value;
tg_max = task_group(p)->uclamp[UCLAMP_MAX].value;
value = uc_req.value;
value = clamp(value, tg_min, tg_max);
uclamp_se_set(&uc_req, value, false);
#endif

return uc_req;
}

/*
 * The effective clamp bucket index of a task depends on, by increasing
 * priority:
 * - the task specific clamp value, when explicitly requested from userspace
 * - the task group effective clamp value, for tasks not either in the root
 *   group or in an autogroup
 * - the system default clamp value, defined by the sysadmin
 */
static inline struct uclamp_se
uclamp_eff_get(struct task_struct *p, enum uclamp_id clamp_id)
{
struct uclamp_se uc_req = uclamp_tg_restrict(p, clamp_id);
struct uclamp_se uc_max = uclamp_default[clamp_id];

/* System default restrictions always apply */
if (unlikely(uc_req.value > uc_max.value))
return uc_max;

return uc_req;
}

On Sat, Dec 18, 2021 at 9:28 AM Rob Landley <rob at landley.net> wrote:
>
> On 12/10/21 2:05 PM, enh wrote:
> > On Fri, Dec 10, 2021 at 3:46 AM Rob Landley <rob at landley.net
> >     Could you ask them what uclamp_validate() in kernel/sched/core.c is trying to
> >     do? It seems like if you've set container limits for the largest or smallest
> >     allowed uclamp values (like that wiki page was going on about). then it checks
> >     THOSE instead of the ones provided by the user to see if they cross. Overwrites
> >     the ones provided by the user entirely, and doesn't check them. So I THINK if I
> >     set the container min limit to 1 and the container max limit to 1023, I could
> >     then have a process within the container request a min of 1000 and a max of 100
> >     and it would pass this function? (Or am I misreading it?)
> >
> > i must be misreading it too, because i don't even know which lines you're
> > referring to, unless we were looking at different versions...
> > https://elixir.bootlin.com/linux/latest/source/kernel/sched/core.c#L1780
>
> Yup, that part:
>
> static int uclamp_validate(struct task_struct *p,
>                            const struct sched_attr *attr)
> {
>         int util_min = p->uclamp_req[UCLAMP_MIN].value;
>         int util_max = p->uclamp_req[UCLAMP_MAX].value;
>
>         if (attr->sched_flags & SCHED_FLAG_UTIL_CLAMP_MIN) {
>                 util_min = attr->sched_util_min;
>
>                 if (util_min + 1 > SCHED_CAPACITY_SCALE + 1)
>                         return -EINVAL;
>         }
>
>         if (attr->sched_flags & SCHED_FLAG_UTIL_CLAMP_MAX) {
>                 util_max = attr->sched_util_max;
>
>                 if (util_max + 1 > SCHED_CAPACITY_SCALE + 1)
>                         return -EINVAL;
>         }
>
>         if (util_min != -1 && util_max != -1 && util_min > util_max)
>                 return -EINVAL;
>
> See how util_min is set from uclamp_req at the start, but when
> SCHED_FLAG_UTIL_CLAMP_MIN the local variable gets overwritten by the attr->
> version, and there's only one util_min > util_max test?
>
> If SCHED_FLAG_UTIIL_CLAMP_BLAH is set, the uclamp_req versions of sched_util_min
> and sched_util_max are never examined by this function. Just fetched and then
> overwritten.
>
> I.E:
>
> static int uclamp_validate(struct task_struct *p,
>                            const struct sched_attr *attr)
> {
>         int util_min = p->uclamp_req[UCLAMP_MIN].value;
>
>         if (attr->sched_flags & SCHED_FLAG_UTIL_CLAMP_MIN)
>                 util_min = attr->sched_util_min;
>
>         if (test util_min)
>                 return -EINVAL;
>
>
> Rob


More information about the Toybox mailing list