here's the response i got:
the logic has been changed as
https://lore.kernel.org/all/[email protected]/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 <[email protected]> wrote:
>
> On 12/10/21 2:05 PM, enh wrote:
> > On Fri, Dec 10, 2021 at 3:46 AM Rob Landley <[email protected]
> > 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
_______________________________________________
Toybox mailing list
[email protected]
http://lists.landley.net/listinfo.cgi/toybox-landley.net