mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Valentin Schneider <valentin.schneider@arm.com>
To: Vincent Guittot <vincent.guittot@linaro.org>,
	peterz@infradead.org, mingo@kernel.org,
	linux-kernel@vger.kernel.org
Cc: morten.rasmussen@foss.arm.com, brendan.jackman@arm.com,
	dietmar.eggemann@arm.com
Subject: Re: [PATCH 3/3] sched: update blocked load when newly idle
Date: Tue, 6 Feb 2018 14:32:27 +0000	[thread overview]
Message-ID: <2e84ae36-9fb7-2fc5-3acd-45b362b6fb94@arm.com> (raw)
In-Reply-To: <1517905943-24528-3-git-send-email-vincent.guittot@linaro.org>

Hi Vincent,

On 02/06/2018 08:32 AM, Vincent Guittot wrote:
> When NEWLY_IDLE load balance is not triggered, we might need to update the
> blocked load anyway. We can kick an ilb so an idle CPU will take care of
> updating blocked load or we can try to update them locally before entering
> idle. In the latter case, we reuse part of the nohz_idle_balance.
> 
> Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
> ---
>  kernel/sched/fair.c | 102 ++++++++++++++++++++++++++++++++++++++++++----------
>  1 file changed, 84 insertions(+), 18 deletions(-)
> 
> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> index 6998528..256defe 100644
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c
> @@ -8829,6 +8829,9 @@ update_next_balance(struct sched_domain *sd, unsigned long *next_balance)
>  		*next_balance = next;
>  }
>  
> +static bool _nohz_idle_balance(struct rq *this_rq, unsigned int flags, enum cpu_idle_type idle);
> +static void kick_ilb(unsigned int flags);
> +
>  /*
>   * idle_balance is called by schedule() if this_cpu is about to become
>   * idle. Attempts to pull tasks from other CPUs.
> @@ -8863,12 +8866,26 @@ static int idle_balance(struct rq *this_rq, struct rq_flags *rf)
>  
>  	if (this_rq->avg_idle < sysctl_sched_migration_cost ||
>  	    !this_rq->rd->overload) {
> +		unsigned long has_blocked = READ_ONCE(nohz.has_blocked);
> +		unsigned long next = READ_ONCE(nohz.next_blocked);

Ditto on 'next' - there's next_balance referenced in here so it'd be nice to make clear which is which.

> +
>  		rcu_read_lock();
>  		sd = rcu_dereference_check_sched_domain(this_rq->sd);
>  		if (sd)
>  			update_next_balance(sd, &next_balance);
>  		rcu_read_unlock();
>  
> +		/*
> +		 * Update blocked idle load if it has not been done for a
> +		 * while. Try to do it locally before entering idle but kick a
> +		 * ilb if it takes too much time and/or might delay next local
> +		 * wake up
> +		 */
> +		if (has_blocked && time_after_eq(jiffies, next) &&
> +				(this_rq->avg_idle < sysctl_sched_migration_cost ||
> +				!_nohz_idle_balance(this_rq, NOHZ_STATS_KICK, CPU_NEWLY_IDLE)))

"this_rq->avg_idle < sysctl_sched_migration_cost" is used twice now, how about storing it in an "idle_too_short" variable ?

> +			kick_ilb(NOHZ_STATS_KICK);
> +
>  		goto out;
>  	}
>  
> @@ -9393,30 +9410,24 @@ static void rebalance_domains(struct rq *rq, enum cpu_idle_type idle)
>  
>  #ifdef CONFIG_NO_HZ_COMMON
>  /*
> - * In CONFIG_NO_HZ_COMMON case, the idle balance kickee will do the
> - * rebalancing for all the cpus for whom scheduler ticks are stopped.
> + * Internal function that runs load balance for all idle cpus. The load balance
> + * can be a simple update of blocked load or a complete load balance with
> + * tasks movement depending of flags.
> + * For newly idle mode, we abort the loop if it takes too much time and return
> + * false to notify that the loop has not be completed and a ilb should be kick.
>   */
> -static bool nohz_idle_balance(struct rq *this_rq, enum cpu_idle_type idle)
> +static bool _nohz_idle_balance(struct rq *this_rq, unsigned int flags, enum cpu_idle_type idle)
>  {
>  	/* Earliest time when we have to do rebalance again */
>  	unsigned long now = jiffies;
>  	unsigned long next_balance = now + 60*HZ;
> -	unsigned long next_stats = now + msecs_to_jiffies(LOAD_AVG_PERIOD);
> +	bool has_blocked_load = false;
>  	int update_next_balance = 0;
>  	int this_cpu = this_rq->cpu;
> -	unsigned int flags;
>  	int balance_cpu;
> +	int ret = false;
>  	struct rq *rq;
> -
> -	if (!(atomic_read(nohz_flags(this_cpu)) & NOHZ_KICK_MASK))
> -		return false;
> -
> -	if (idle != CPU_IDLE) {
> -		atomic_andnot(NOHZ_KICK_MASK, nohz_flags(this_cpu));
> -		return false;
> -	}
> -
> -	flags = atomic_fetch_andnot(NOHZ_KICK_MASK, nohz_flags(this_cpu));
> +	u64 curr_cost = 0;
>  
>  	SCHED_WARN_ON((flags & NOHZ_KICK_MASK) == NOHZ_BALANCE_KICK);
>  
> @@ -9431,6 +9442,10 @@ static bool nohz_idle_balance(struct rq *this_rq, enum cpu_idle_type idle)
>  	WRITE_ONCE(nohz.has_blocked, 0);
>  
>  	for_each_cpu(balance_cpu, nohz.idle_cpus_mask) {
> +		u64 t0, domain_cost;
> +
> +		t0 = sched_clock_cpu(this_cpu);
> +
>  		if (balance_cpu == this_cpu || !idle_cpu(balance_cpu))
>  			continue;
>  
> @@ -9444,6 +9459,16 @@ static bool nohz_idle_balance(struct rq *this_rq, enum cpu_idle_type idle)
>  			goto abort;
>  		}
>  
> +		/*
> +		 * If the update is done while CPU becomes idle, we abort
> +		 * the update when its cost is higher than the average idle
> +		 * time in orde to not delay a possible wake up.
> +		 */
> +		if (idle == CPU_NEWLY_IDLE && this_rq->avg_idle < curr_cost) {
> +			has_blocked_load = true;
> +			goto abort;
> +		}
> +
>  		rq = cpu_rq(balance_cpu);
>  
>  		update_blocked_averages(rq->cpu);
> @@ -9456,10 +9481,10 @@ static bool nohz_idle_balance(struct rq *this_rq, enum cpu_idle_type idle)
>  		if (time_after_eq(jiffies, rq->next_balance)) {
>  			struct rq_flags rf;
>  
> -			rq_lock_irq(rq, &rf);
> +			rq_lock_irqsave(rq, &rf);
>  			update_rq_clock(rq);
>  			cpu_load_update_idle(rq);
> -			rq_unlock_irq(rq, &rf);
> +			rq_unlock_irqrestore(rq, &rf);
>  
>  			if (flags & NOHZ_BALANCE_KICK)
>  				rebalance_domains(rq, CPU_IDLE);
> @@ -9469,15 +9494,27 @@ static bool nohz_idle_balance(struct rq *this_rq, enum cpu_idle_type idle)
>  			next_balance = rq->next_balance;
>  			update_next_balance = 1;
>  		}
> +
> +		domain_cost = sched_clock_cpu(this_cpu) - t0;
> +		curr_cost += domain_cost;
> +
> +	}
> +
> +	/* Newly idle CPU doesn't need an update */
> +	if (idle != CPU_NEWLY_IDLE) {
> +		update_blocked_averages(this_cpu);
> +		has_blocked_load |= this_rq->has_blocked_load;
>  	}
>  
> -	update_blocked_averages(this_cpu);
>  	if (flags & NOHZ_BALANCE_KICK)
>  		rebalance_domains(this_rq, CPU_IDLE);
>  
>  	WRITE_ONCE(nohz.next_blocked,
>  		now + msecs_to_jiffies(LOAD_AVG_PERIOD));
>  
> +	/* The full idle balance loop has been done */
> +	ret = true;
> +
>  abort:
>  	/* There is still blocked load, enable periodic update */
>  	if (has_blocked_load)
> @@ -9491,6 +9528,35 @@ static bool nohz_idle_balance(struct rq *this_rq, enum cpu_idle_type idle)
>  	if (likely(update_next_balance))
>  		nohz.next_balance = next_balance;
>  
> +	return ret;
> +}
> +
> +/*
> + * In CONFIG_NO_HZ_COMMON case, the idle balance kickee will do the
> + * rebalancing for all the cpus for whom scheduler ticks are stopped.
> + */
> +static bool nohz_idle_balance(struct rq *this_rq, enum cpu_idle_type idle)
> +{
> +	int this_cpu = this_rq->cpu;
> +	unsigned int flags;
> +
> +	if (!(atomic_read(nohz_flags(this_cpu)) & NOHZ_KICK_MASK))
> +		return false;
> +
> +	if (idle != CPU_IDLE) {
> +		atomic_andnot(NOHZ_KICK_MASK, nohz_flags(this_cpu));
> +		return false;
> +	}
> +
> +	/*
> +	 * barrier, pairs with nohz_balance_enter_idle(), ensures ...
> +	 */
> +	flags = atomic_fetch_andnot(NOHZ_KICK_MASK, nohz_flags(this_cpu));
> +	if (!(flags & NOHZ_KICK_MASK))
> +		return false;
> +
> +	_nohz_idle_balance(this_rq, flags, idle);
> +
>  	return true;
>  }
>  #else
> 

  reply	other threads:[~2018-02-06 14:32 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-12-21 10:21 [RFC PATCH 0/5] sched: On remote stats updates Peter Zijlstra
2017-12-21 10:21 ` [RFC PATCH 1/5] sched: Convert nohz_flags to atomic_t Peter Zijlstra
2017-12-21 10:21 ` [RFC PATCH 2/5] sched: Add NOHZ_STATS_KICK Peter Zijlstra
2017-12-21 16:23   ` Vincent Guittot
2017-12-21 16:56     ` Vincent Guittot
2017-12-22  7:59       ` Peter Zijlstra
2017-12-22  8:05         ` Vincent Guittot
2017-12-22  8:29           ` Peter Zijlstra
2017-12-22  9:12             ` Peter Zijlstra
2017-12-22 14:31               ` Peter Zijlstra
2017-12-22 14:34                 ` Vincent Guittot
2017-12-22 14:32               ` Vincent Guittot
2017-12-22 18:56                 ` Peter Zijlstra
2017-12-22 20:42                   ` Peter Zijlstra
2018-01-02 15:44                     ` Morten Rasmussen
2018-01-15  9:43                       ` Peter Zijlstra
2018-01-18 10:32                         ` Morten Rasmussen
2018-01-03  9:16                     ` Vincent Guittot
2018-01-15  8:26                       ` Vincent Guittot
2018-01-18 10:38                         ` Morten Rasmussen
2018-01-24  8:25                           ` Vincent Guittot
2018-01-29 18:43                             ` Dietmar Eggemann
2018-01-30  8:00                               ` Vincent Guittot
2018-01-29 19:31                             ` Valentin Schneider
2018-01-30  8:32                               ` Vincent Guittot
2018-01-30 11:41                                 ` Valentin Schneider
2018-01-30 13:05                                   ` Vincent Guittot
2018-02-05 22:18                                   ` Valentin Schneider
2018-02-06  9:22                                     ` Vincent Guittot
2018-02-01 18:16                               ` Peter Zijlstra
2018-02-01 16:57                             ` Peter Zijlstra
2018-02-01 17:26                               ` Vincent Guittot
2018-02-01 18:10                             ` Peter Zijlstra
2018-02-01 19:11                               ` Vincent Guittot
2018-02-06  8:32                               ` [PATCH 1/3] sched: Stop nohz stats when decayed Vincent Guittot
2018-02-06  8:32                                 ` [PATCH 2/3] sched: reduce the periodic update duration Vincent Guittot
2018-02-06  8:32                                 ` [PATCH 3/3] sched: update blocked load when newly idle Vincent Guittot
2018-02-06 14:32                                   ` Valentin Schneider [this message]
2018-02-06 16:17                                     ` Vincent Guittot
2018-02-06 16:32                                       ` Valentin Schneider
2018-02-06  8:55                                 ` [PATCH 1/3] sched: Stop nohz stats when decayed Vincent Guittot
2018-02-06 14:16                                 ` Valentin Schneider
2018-02-06 14:31                                   ` Vincent Guittot
2018-02-01 16:55                           ` [RFC PATCH 2/5] sched: Add NOHZ_STATS_KICK Peter Zijlstra
2018-01-22  9:40                         ` Dietmar Eggemann
2018-01-22 10:23                           ` Vincent Guittot
2018-02-01 16:52                         ` Peter Zijlstra
2018-02-01 17:25                           ` Vincent Guittot
2017-12-22  7:56     ` Peter Zijlstra
2017-12-22  8:04       ` Vincent Guittot
2017-12-21 10:21 ` [RFC PATCH 3/5] sched: Restructure nohz_balance_kick Peter Zijlstra
2017-12-21 10:21 ` [RFC PATCH 4/5] sched: Add nohz stats balancing Peter Zijlstra
2017-12-21 10:21 ` [RFC PATCH 5/5] sched: Update blocked load from NEWIDLE Peter Zijlstra
2018-02-13 10:31 [PATCH v4 0/3] sched: Update blocked load Vincent Guittot
2018-02-13 10:31 ` [PATCH 3/3] sched: update blocked load when newly idle Vincent Guittot
2018-02-14 14:40   ` Valentin Schneider
2018-02-14 14:43     ` Vincent Guittot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2e84ae36-9fb7-2fc5-3acd-45b362b6fb94@arm.com \
    --to=valentin.schneider@arm.com \
    --cc=brendan.jackman@arm.com \
    --cc=dietmar.eggemann@arm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=morten.rasmussen@foss.arm.com \
    --cc=peterz@infradead.org \
    --cc=vincent.guittot@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome