Messages in this thread | | | Subject | Re: [patch 1/2] sched: use resched IPI to kick off the nohz idle balance | From | Peter Zijlstra <> | Date | Mon, 03 Oct 2011 21:36:30 +0200 |
| |
On Thu, 2011-09-29 at 15:30 -0700, Suresh Siddha wrote:
> --- > kernel/sched.c | 14 +++++++++++--- > kernel/sched_fair.c | 27 +++++++-------------------- > 2 files changed, 18 insertions(+), 23 deletions(-) > > Index: linux-2.6-tip/kernel/sched.c > =================================================================== > --- linux-2.6-tip.orig/kernel/sched.c > +++ linux-2.6-tip/kernel/sched.c > @@ -2733,7 +2733,7 @@ void scheduler_ipi(void) > struct rq *rq = this_rq(); > struct task_struct *list = xchg(&rq->wake_list, NULL); > > - if (!list) > + if (!list && !idle_cpu(cpu_of(rq))) > return;
Why not make that !rq->nohz_balance_kick? (wrapped in a helper for ! CONFIG_NO_HZ)
> /* > @@ -2750,7 +2750,16 @@ void scheduler_ipi(void) > * somewhat pessimize the simple resched case. > */ > irq_enter(); > - sched_ttwu_do_pending(list); > + > + if (list) > + sched_ttwu_do_pending(list); > + > + /* > + * Check if someone kicked us for doing the nohz idle load balance. > + */ > + if (unlikely((rq->idle == current) && rq->nohz_balance_kick && > + !need_resched())) > + raise_softirq_irqoff(SCHED_SOFTIRQ);
And make that: idle_cpu() && rq->nohz_balance_kick && !need_resched()
All wrapped in #ifdef CONFIG_NO_HZ goo? > tself as idle load_balancer, while > @@ -4450,11 +4434,14 @@ static void nohz_balancer_kick(int cpu) > } > > if (!cpu_rq(ilb_cpu)->nohz_balance_kick) { > - struct call_single_data *cp; > - > cpu_rq(ilb_cpu)->nohz_balance_kick = 1; > - cp = &per_cpu(remote_sched_softirq_cb, cpu); > - __smp_call_function_single(ilb_cpu, cp, 0); > + /* > + * Use kick_process instead of resched_cpu. > + * This way we generate a sched IPI on the target cpu which > + * is idle. And the softirq performing nohz idle load balance > + * will be run before returning from the IPI. > + */
Shouldn't we have a memory barrier of sorts before sending the IPI?
> + kick_process(idle_task(ilb_cpu)); > } > return; > } > >
| |