From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756184AbcANRQW (ORCPT ); Thu, 14 Jan 2016 12:16:22 -0500 Received: from casper.infradead.org ([85.118.1.10]:39288 "EHLO casper.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751941AbcANRQV (ORCPT ); Thu, 14 Jan 2016 12:16:21 -0500 Date: Thu, 14 Jan 2016 18:16:19 +0100 From: Peter Zijlstra To: Luca Abeni Cc: linux-kernel@vger.kernel.org, Ingo Molnar , Juri Lelli Subject: Re: [RFC 4/8] Improve the tracking of active utilisation Message-ID: <20160114171619.GZ6357@twins.programming.kicks-ass.net> References: <1452785094-3086-1-git-send-email-luca.abeni@unitn.it> <1452785094-3086-5-git-send-email-luca.abeni@unitn.it> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1452785094-3086-5-git-send-email-luca.abeni@unitn.it> User-Agent: Mutt/1.5.21 (2012-12-30) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Jan 14, 2016 at 04:24:49PM +0100, Luca Abeni wrote: > @@ -65,6 +67,62 @@ static void clear_running_bw(struct sched_dl_entity *dl_se, struct dl_rq *dl_rq) > } > } > > +static void task_go_inactive(struct task_struct *p) > +{ > + struct sched_dl_entity *dl_se = &p->dl; > + struct hrtimer *timer = &dl_se->inactive_timer; > + struct dl_rq *dl_rq = dl_rq_of_se(dl_se); > + struct rq *rq = rq_of_dl_rq(dl_rq); > + ktime_t now, act; > + s64 delta; > + u64 zerolag_time; > + > + WARN_ON(dl_se->dl_runtime == 0); > + > + /* If the inactive timer is already armed, return immediately */ > + if (hrtimer_active(&dl_se->inactive_timer)) > + return; > + > + > + /* > + * We want the timer to fire at the "0 lag time", but considering > + * that it is actually coming from rq->clock and not from > + * hrtimer's time base reading. > + */ > + zerolag_time = dl_se->deadline - div64_long((dl_se->runtime * dl_se->dl_period), dl_se->dl_runtime); whitespace damage > @@ -530,9 +587,20 @@ static void update_dl_entity(struct sched_dl_entity *dl_se, > */ > if (dl_se->dl_new) { > setup_new_dl_entity(dl_se, pi_se); > + add_running_bw(dl_se, dl_rq); > return; > } > > + /* If the "inactive timer" is still active, stop it adn leave > + * the active utilisation unchanged. > + * If it is running, increase the active utilisation > + */ > + if (hrtimer_active(&dl_se->inactive_timer)) { > + hrtimer_try_to_cancel(&dl_se->inactive_timer); what if cancel fails? > + } else { > + add_running_bw(dl_se, dl_rq); > + } > + > if (dl_time_before(dl_se->deadline, rq_clock(rq)) || > dl_entity_overflow(dl_se, pi_se, rq_clock(rq))) { > dl_se->deadline = rq_clock(rq) + pi_se->dl_deadline; > @@ -1248,8 +1370,6 @@ static void task_fork_dl(struct task_struct *p) > static void task_dead_dl(struct task_struct *p) > { > struct dl_bw *dl_b = dl_bw_of(task_cpu(p)); > - struct dl_rq *dl_rq = dl_rq_of_se(&p->dl); > - struct rq *rq = rq_of_dl_rq(dl_rq); > > /* > * Since we are TASK_DEAD we won't slip out of the domain! > @@ -1258,10 +1378,6 @@ static void task_dead_dl(struct task_struct *p) > /* XXX we should retain the bw until 0-lag */ > dl_b->total_bw -= p->dl.dl_bw; > raw_spin_unlock_irq(&dl_b->lock); > - > - if (task_on_rq_queued(p)) { > - clear_running_bw(&p->dl, &rq->dl); > - } what happens if the timer is still active here? then we get the timer storage freed while enqueued? > @@ -1742,12 +1858,12 @@ static void switched_from_dl(struct rq *rq, struct task_struct *p) > * SCHED_DEADLINE until the deadline passes, the timer will reset the > * task. > */ > - if (!start_dl_timer(p)) > + if (task_on_rq_queued(p)) > + task_go_inactive(p); > + if (!hrtimer_active(&p->dl.inactive_timer)) > __dl_clear_params(p); > - > - if (task_on_rq_queued(p)) { > + else if (!hrtimer_callback_running(&p->dl.inactive_timer)) > clear_running_bw(&p->dl, &rq->dl); > - } > > /* > * Since this might be the only -deadline task on the rq, idem, what if the task dies while !dl but with timer pending?