Re: [PATCH 2/2] sched/psi: iterate through cgroups directly

From: Johannes Weiner
Date: Wed Feb 08 2023 - 14:20:18 EST


On Wed, Feb 08, 2023 at 06:29:56PM +0100, Michal Koutný wrote:
> On Thu, Feb 09, 2023 at 12:16:54AM +0800, Kairui Song <ryncsn@xxxxxxxxx> wrote:
> > Signed-off-by: Kairui Song <kasong@xxxxxxxxxxx>
> > Signed-off-by: Kairui Song <ryncsn@xxxxxxxxx>
>
> Typo?
>
> > -static inline struct psi_group *task_psi_group(struct task_struct *task)
> > +static inline struct psi_group *psi_iter_first(struct task_struct *task, void **iter)
> > {
> > #ifdef CONFIG_CGROUPS
> > - if (static_branch_likely(&psi_cgroups_enabled))
> > - return cgroup_psi(task_dfl_cgroup(task));
> > + if (static_branch_likely(&psi_cgroups_enabled)) {
> > + struct cgroup *cgroup = task_dfl_cgroup(task);
> > +
> > + *iter = cgroup_parent(cgroup);
>
> This seems to skip a cgroup level -- maybe that's the observed
> performance gain?

Hm, I don't think it does. It sets up *iter to point to the parent for
the _next() call, but it returns task_dfl_cgroup()->psi. The next call
does the same: cgroup = *iter, *iter = parent, return cgroup->psi.

It could be a bit more readable to have *iter always point to the
current cgroup - but no strong preference either way from me:

psi_groups_first(task, iter)
{
#ifdef CONFIG_CGROUPS
if (static_branch_likely(&psi_cgroups_enabled)) {
struct cgroup *cgroup = task_dfl_cgroup(task);

*iter = cgroup;
return cgroup_psi(cgroup);
}
#endif
return &psi_system;
}

psi_groups_next(iter)
{
#ifdef CONFIG_CGROUPS
if (static_branch_likely(&psi_cgroups_enabled)) {
struct cgroup *cgroup = *iter;

if (cgroup) {
*iter = cgroup_parent(cgroup);
return cgroup_psi(cgroup);
}
}
return NULL;
#endif
}