From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750958AbaDMVvI (ORCPT ); Sun, 13 Apr 2014 17:51:08 -0400 Received: from mail-qa0-f53.google.com ([209.85.216.53]:50780 "EHLO mail-qa0-f53.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750714AbaDMVvG (ORCPT ); Sun, 13 Apr 2014 17:51:06 -0400 Date: Sun, 13 Apr 2014 17:51:03 -0400 (EDT) From: Nicolas Pitre To: Peter Zijlstra cc: mingo@kernel.org, tglx@linutronix.de, luto@amacapital.net, daniel.lezcano@linaro.org, umgwanakikbuti@gmail.com, linux-kernel@vger.kernel.org Subject: Re: [RFC][PATCH 7/8] sched,idle: Delay clearing the polling bit In-Reply-To: <20140411135218.546673774@infradead.org> Message-ID: References: <20140411134243.160989490@infradead.org> <20140411135218.546673774@infradead.org> User-Agent: Alpine 2.11 (LFD 23 2013-08-11) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, 11 Apr 2014, Peter Zijlstra wrote: > With the generic idle functions assuming !polling we should only clear > the polling bit at the very last opportunity in order to avoid > spurious IPIs. > > Ideally we'd flip the default to polling, but that means auditing all > arch idle functions. > > Cc: Nicolas Pitre > Cc: Daniel Lezcano > Cc: Thomas Gleixner > Signed-off-by: Peter Zijlstra Acked-by: Nicolas Pitre > --- > kernel/sched/idle.c | 17 ++++++++++------- > 1 file changed, 10 insertions(+), 7 deletions(-) > > --- a/kernel/sched/idle.c > +++ b/kernel/sched/idle.c > @@ -78,12 +78,10 @@ static int cpuidle_idle_call(void) > > /* > * Check if the idle task must be rescheduled. If it is the > - * case, exit the function after re-enabling the local irq and > - * set again the polling flag > + * case, exit the function after re-enabling the local irq. > */ > - if (current_clr_polling_and_test()) { > + if (need_resched()) { > local_irq_enable(); > - __current_set_polling(); > return 0; > } > > @@ -127,7 +125,7 @@ static int cpuidle_idle_call(void) > broadcast = !!(drv->states[next_state].flags & > CPUIDLE_FLAG_TIMER_STOP); > > - if (broadcast) > + if (broadcast) { > /* > * Tell the time framework to switch > * to a broadcast timer because our > @@ -139,6 +137,7 @@ static int cpuidle_idle_call(void) > ret = clockevents_notify( > CLOCK_EVT_NOTIFY_BROADCAST_ENTER, > &dev->cpu); > + } > > if (!ret) { > trace_cpu_idle_rcuidle(next_state, dev->cpu); > @@ -175,8 +174,12 @@ static int cpuidle_idle_call(void) > * We can't use the cpuidle framework, let's use the default > * idle routine > */ > - if (ret) > - arch_cpu_idle(); > + if (ret) { > + if (!current_clr_polling_and_test()) > + arch_cpu_idle(); > + else > + local_irq_enable(); > + } > > __current_set_polling(); > > >