Re: Task group cleanups and optimizations (was: Re: [RFC 00/60] Coscheduling for Linux)

From: Peter Zijlstra
Date: Mon Sep 17 2018 - 05:48:59 EST


On Sat, Sep 15, 2018 at 10:48:20AM +0200, Jan H. Schönherr wrote:
> On 09/14/2018 06:25 PM, Jan H. Schönherr wrote:
> > On 09/14/2018 01:12 PM, Peter Zijlstra wrote:
> >>
> >> There are known scalability problems with the existing cgroup muck; you
> >> just made things a ton worse. The existing cgroup overhead is
> >> significant, you also made that many times worse.
> >>
> >> The cgroup stuff needs cleanups and optimization, not this.
>
> [...]
>
> > With respect to the need of cleanups and optimizations: I agree, that
> > task groups are a bit messy. For example, here's my current wish list
> > off the top of my head:
> >
> > a) lazy scheduler operations; for example: when dequeuing a task, don't bother
> > walking up the task group hierarchy to dequeue all the SEs -- do it lazily
> > when encountering an empty CFS RQ during picking when we hold the lock anyway.

That sounds like it will wreck the runnable_weight accounting. Although,
if, as you write below, we do away with the hierarchical runqueues, that
isn't in fact needed anymore I think.

Still, even without runnable_weight, I suspect we need the 'runnable'
state, even for the other accounting.

> > b) ability to move CFS RQs between CPUs: someone changed the affinity of
> > a cpuset? No problem, just attach the runqueue with all the tasks elsewhere.
> > No need to touch each and every task.

Can't do that, tasks might have individual constraints that are tighter
than the cpuset. Also, changing affinities isn't really a hot path, so
who cares.

> > c) light-weight task groups: don't allocate a runqueue for every CPU in the
> > system, when it is known that tasks in the task group will only ever run
> > on at most two CPUs, or so. (And while there is of course a use case for
> > VMs in this, another class of use cases are auxiliary tasks, see eg, [1-5].)

I have yet to go over your earlier email; but no. The scheduler is very
much per-cpu. And as I mentioned earlier, CFS as is doesn't work right
if you share the runqueue between multiple CPUs (and 'fixing' that is
non trivial).

> > Is this the level of optimizations, you're thinking about? Or do you want
> > to throw away the whole nested CFS RQ experience in the code?
>
> I guess, it would be possible to flatten the task group hierarchy, that is usually
> created when nesting cgroups. That is, enqueue task group SEs always within the
> root task group.
>
> That should take away much of the (runtime-)overhead, no?

Yes, Rik was going to look at trying this. Put all the tasks in the root
rq and adjust the vtime calculations. Facebook is seeing significant
overhead from cpu-cgroup and has to disable it because of that on at
least part of their setup IIUC.

> The calculation of shares would need to be a different kind of complex than it is
> now. But that might be manageable.

That is the hope; indeed. We'll still need to create the hierarchy for
accounting purposes, but it can be a smaller/simpler data structure.

So the weight computation would be the normalized product of the parents
etc.. and since PELT only updates the values on ~1ms scale, we can keep
a cache of the product -- that is, we don't have to recompute that
product and walk the hierarchy all the time either.

> CFS bandwidth control would also need to change significantly as we would now
> have to dequeue/enqueue nested cgroups below a throttled/unthrottled hierarchy.
> Unless *those* task groups don't participate in this flattening.

Right, so the whole bandwidth thing becomes a pain; the simplest
solution is to detect the throttle at task-pick time, dequeue and try
again. But that is indeed quite horrible.

I'm not quite sure how this will play out.

Anyway, if we pull off this flattening feat, then you can no longer use
the hierarchy for this co-scheduling stuff.

Now, let me go read your earlier email and reply to that (in parts).