From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932666AbcFARmo (ORCPT ); Wed, 1 Jun 2016 13:42:44 -0400 Received: from mail-pf0-f182.google.com ([209.85.192.182]:35204 "EHLO mail-pf0-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932138AbcFARmn (ORCPT ); Wed, 1 Jun 2016 13:42:43 -0400 From: bsegall@google.com To: Peter Zijlstra Cc: Vincent Guittot , mingo@kernel.org, linux-kernel@vger.kernel.org, pjt@google.com, yuyang.du@intel.com, dietmar.eggemann@arm.com Subject: Re: [RFC PATCH] sched: fix hierarchical order in rq->leaf_cfs_rq_list References: <1464080135-17112-1-git-send-email-vincent.guittot@linaro.org> <1464083710-4370-1-git-send-email-vincent.guittot@linaro.org> <20160601123140.GW3192@twins.programming.kicks-ass.net> Date: Wed, 01 Jun 2016 10:42:34 -0700 In-Reply-To: <20160601123140.GW3192@twins.programming.kicks-ass.net> (Peter Zijlstra's message of "Wed, 1 Jun 2016 14:31:40 +0200") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Peter Zijlstra writes: > On Tue, May 24, 2016 at 11:55:10AM +0200, Vincent Guittot wrote: >> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c >> index 218f8e8..6d3fbf2 100644 >> --- a/kernel/sched/fair.c >> +++ b/kernel/sched/fair.c >> @@ -290,15 +290,31 @@ static inline void list_add_leaf_cfs_rq(struct cfs_rq *cfs_rq) >> * Ensure we either appear before our parent (if already >> * enqueued) or force our parent to appear after us when it is >> * enqueued. The fact that we always enqueue bottom-up >> + * reduces this to two cases and a specila case for the root > > 'special' > >> + * cfs_rq. >> */ >> if (cfs_rq->tg->parent && >> cfs_rq->tg->parent->cfs_rq[cpu_of(rq_of(cfs_rq))]->on_list) { >> + /* Add the child just before its parent */ >> + list_add_tail_rcu(&cfs_rq->leaf_cfs_rq_list, >> + &(cfs_rq->tg->parent->cfs_rq[cpu_of(rq_of(cfs_rq))]->leaf_cfs_rq_list)); >> + rq_of(cfs_rq)->leaf_alone = &rq_of(cfs_rq)->leaf_cfs_rq_list; >> + } else if (!cfs_rq->tg->parent) { >> + /* >> + * cfs_rq without parent should be >> + * at the end of the list >> + */ >> list_add_tail_rcu(&cfs_rq->leaf_cfs_rq_list, >> &rq_of(cfs_rq)->leaf_cfs_rq_list); >> + rq_of(cfs_rq)->leaf_alone = &rq_of(cfs_rq)->leaf_cfs_rq_list; >> + } else { >> + /* >> + * Our parent has not already been added so make sure >> + * that it will be put after us >> + */ >> + list_add_rcu(&cfs_rq->leaf_cfs_rq_list, >> + rq_of(cfs_rq)->leaf_alone); >> + rq_of(cfs_rq)->leaf_alone = &cfs_rq->leaf_cfs_rq_list; >> } >> >> cfs_rq->on_list = 1; > > Paul, Ben ? > > This used to be critical for update_shares() (now > update_blocked_averages), but IIRC is not critical for that since > PELT. Yeah, given that we no longer update_cfs_shares in that path, it shouldn't be as important (unless new code is being added that it will be useful for). That said, I honestly don't remember why we don't update_cfs_shares, as it could affect the load.weight being used in a parent's computation. Paul, do you remember? Was it just too expensive and less necessary given the other improvements? > > I find its more readable with like so.. > > > Also; I feel the comments can use more love; my head hurts ;-) Yeah leaf_alone here is basically a temporary for the duration of an enqueue_task_fair call, yes? A name suggesting that might be useful, or else a comment mentioning that one of the first two cases will always clear the otherwise unsafe reference before it can be a problem. I think this also only barely works with throttling: even if the tg as a whole is out of runtime, an individual cfs_rq can't be throttled until just one line after list_add_cfs_rq, and we never list_del until cgroup destruction. A throttled !on_list cfs_rq would cause us to never reset leaf_alone, but I don't think that can quite happen. > > --- > --- a/kernel/sched/fair.c > +++ b/kernel/sched/fair.c > @@ -286,35 +286,38 @@ static inline struct cfs_rq *group_cfs_r > static inline void list_add_leaf_cfs_rq(struct cfs_rq *cfs_rq) > { > if (!cfs_rq->on_list) { > + struct rq *rq = rq_of(cfs_rq); > + int cpu = cpu_of(rq); > + > /* > * Ensure we either appear before our parent (if already > * enqueued) or force our parent to appear after us when it is > * enqueued. The fact that we always enqueue bottom-up > - * reduces this to two cases and a specila case for the root > + * reduces this to two cases and a special case for the root > * cfs_rq. > */ > if (cfs_rq->tg->parent && > - cfs_rq->tg->parent->cfs_rq[cpu_of(rq_of(cfs_rq))]->on_list) { > + cfs_rq->tg->parent->cfs_rq[cpu]->on_list) { > /* Add the child just before its parent */ > list_add_tail_rcu(&cfs_rq->leaf_cfs_rq_list, > - &(cfs_rq->tg->parent->cfs_rq[cpu_of(rq_of(cfs_rq))]->leaf_cfs_rq_list)); > - rq_of(cfs_rq)->leaf_alone = &rq_of(cfs_rq)->leaf_cfs_rq_list; > + &(cfs_rq->tg->parent->cfs_rq[cpu]->leaf_cfs_rq_list)); > + rq->leaf_alone = &rq->leaf_cfs_rq_list; > } else if (!cfs_rq->tg->parent) { > /* > * cfs_rq without parent should be > * at the end of the list > */ > list_add_tail_rcu(&cfs_rq->leaf_cfs_rq_list, > - &rq_of(cfs_rq)->leaf_cfs_rq_list); > - rq_of(cfs_rq)->leaf_alone = &rq_of(cfs_rq)->leaf_cfs_rq_list; > + &rq->leaf_cfs_rq_list); > + rq->leaf_alone = &rq->leaf_cfs_rq_list; > } else { > /* > * Our parent has not already been added so make sure > * that it will be put after us > */ > list_add_rcu(&cfs_rq->leaf_cfs_rq_list, > - rq_of(cfs_rq)->leaf_alone); > - rq_of(cfs_rq)->leaf_alone = &cfs_rq->leaf_cfs_rq_list; > + rq->leaf_alone); > + rq->leaf_alone = &cfs_rq->leaf_cfs_rq_list; > } > > cfs_rq->on_list = 1;