From: Frederic Weisbecker <fweisbec@gmail.com>
To: Peter Zijlstra <peterz@infradead.org>
Cc: Vincent Guittot <vincent.guittot@linaro.org>,
linux-kernel <linux-kernel@vger.kernel.org>,
"linaro-kernel@lists.linaro.org" <linaro-kernel@lists.linaro.org>,
Ingo Molnar <mingo@kernel.org>
Subject: Re: [PATCH] sched: fix clear NOHZ_BALANCE_KICK
Date: Tue, 4 Jun 2013 12:26:22 +0200 [thread overview]
Message-ID: <20130604102620.GB14012@somewhere> (raw)
In-Reply-To: <20130604093611.GJ8923@twins.programming.kicks-ass.net>
On Tue, Jun 04, 2013 at 11:36:11AM +0200, Peter Zijlstra wrote:
>
> The best I can seem to come up with is something like the below; but I think
> its ghastly. Surely we can do something saner with that bit.
>
> Having to clear it at 3 different places is just wrong.
We could clear the flag early in scheduler_ipi() and set some
specific value in rq->idle_balance that tells we want nohz idle
balancing from the softirq, something like this untested:
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 58453b8..330136b 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -630,15 +630,14 @@ void wake_up_nohz_cpu(int cpu)
wake_up_idle_cpu(cpu);
}
-static inline bool got_nohz_idle_kick(void)
+static inline bool got_nohz_idle_kick(int cpu)
{
- int cpu = smp_processor_id();
- return idle_cpu(cpu) && test_bit(NOHZ_BALANCE_KICK, nohz_flags(cpu));
+ return test_and_clear_bit(NOHZ_BALANCE_KICK, nohz_flags(cpu));
}
#else /* CONFIG_NO_HZ_COMMON */
-static inline bool got_nohz_idle_kick(void)
+static inline bool got_nohz_idle_kick(int cpu)
{
return false;
}
@@ -1393,8 +1392,12 @@ static void sched_ttwu_pending(void)
void scheduler_ipi(void)
{
- if (llist_empty(&this_rq()->wake_list) && !got_nohz_idle_kick()
- && !tick_nohz_full_cpu(smp_processor_id()))
+ int cpu = smp_processor_id();
+ bool idle_kick = got_nohz_idle_kick(cpu);
+
+ if (!(idle_kick && idle_cpu(cpu))
+ && llist_empty(&this_rq()->wake_list)
+ && !tick_nohz_full_cpu(cpu)
return;
/*
@@ -1417,8 +1420,8 @@ void scheduler_ipi(void)
/*
* Check if someone kicked us for doing the nohz idle load balance.
*/
- if (unlikely(got_nohz_idle_kick() && !need_resched())) {
- this_rq()->idle_balance = 1;
+ if (unlikely(idle_kick && idle_cpu(cpu) && !need_resched())) {
+ this_rq()->idle_balance = IDLE_NOHZ_BALANCE;
raise_softirq_irqoff(SCHED_SOFTIRQ);
}
irq_exit();
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index c61a614..816e7b0 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -5577,15 +5577,14 @@ out:
* 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 void nohz_idle_balance(int this_cpu, enum cpu_idle_type idle)
+static void nohz_idle_balance(int this_cpu)
{
struct rq *this_rq = cpu_rq(this_cpu);
struct rq *rq;
int balance_cpu;
- if (idle != CPU_IDLE ||
- !test_bit(NOHZ_BALANCE_KICK, nohz_flags(this_cpu)))
- goto end;
+ if (this_rq->idle_balance != IDLE_NOHZ_BALANCE)
+ return;
for_each_cpu(balance_cpu, nohz.idle_cpus_mask) {
if (balance_cpu == this_cpu || !idle_cpu(balance_cpu))
@@ -5612,8 +5611,12 @@ static void nohz_idle_balance(int this_cpu, enum cpu_idle_type idle)
this_rq->next_balance = rq->next_balance;
}
nohz.next_balance = this_rq->next_balance;
-end:
- clear_bit(NOHZ_BALANCE_KICK, nohz_flags(this_cpu));
+
+ /* There could be concurrent updates from irqs but we don't care */
+ if (idle_cpu(this_cpu))
+ this_rq->idle_balance = IDLE_BALANCE;
+ else
+ this_rq->idle_balance = 0;
}
/*
@@ -5679,7 +5682,7 @@ need_kick:
return 1;
}
#else
-static void nohz_idle_balance(int this_cpu, enum cpu_idle_type idle) { }
+static void nohz_idle_balance(int this_cpu) { }
#endif
/*
@@ -5700,7 +5703,7 @@ static void run_rebalance_domains(struct softirq_action *h)
* balancing on behalf of the other idle cpus whose ticks are
* stopped.
*/
- nohz_idle_balance(this_cpu, idle);
+ nohz_idle_balance(this_cpu);
}
static inline int on_null_domain(int cpu)
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index ce39224..e9de976 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -387,6 +387,11 @@ extern struct root_domain def_root_domain;
#endif /* CONFIG_SMP */
+enum idle_balance_type {
+ IDLE_BALANCE = 1,
+ IDLE_NOHZ_BALANCE = 2,
+};
+
/*
* This is the main, per-CPU runqueue data structure.
*
@@ -458,7 +463,7 @@ struct rq {
unsigned long cpu_power;
- unsigned char idle_balance;
+ enum idle_balance_type idle_balance;
/* For active balancing */
int post_schedule;
int active_balance;
next prev parent reply other threads:[~2013-06-04 10:26 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-05-30 15:23 [PATCH] sched: fix clear NOHZ_BALANCE_KICK Vincent Guittot
2013-06-03 22:48 ` Frederic Weisbecker
2013-06-04 8:21 ` Vincent Guittot
2013-06-04 9:36 ` Peter Zijlstra
2013-06-04 10:26 ` Frederic Weisbecker [this message]
2013-06-04 11:11 ` Vincent Guittot
2013-06-04 11:19 ` Frederic Weisbecker
2013-06-04 11:48 ` Vincent Guittot
2013-06-04 14:44 ` Frederic Weisbecker
2013-06-04 15:29 ` Vincent Guittot
2013-06-05 13:31 ` Frederic Weisbecker
2013-06-04 11:15 ` Peter Zijlstra
2013-06-04 11:53 ` Frederic Weisbecker
2013-06-04 9:56 ` Frederic Weisbecker
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=20130604102620.GB14012@somewhere \
--to=fweisbec@gmail.com \
--cc=linaro-kernel@lists.linaro.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.