From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Rafael J. Wysocki" Subject: Re: [PATCH v2] cpuidle: poll_state: Add time limit to poll_idle() Date: Wed, 14 Mar 2018 12:24:32 +0100 Message-ID: <12084659.o4ihbg2AZp@aspire.rjw.lan> References: <4137867.C4jYrWdt8n@aspire.rjw.lan> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7Bit Return-path: In-Reply-To: <4137867.C4jYrWdt8n@aspire.rjw.lan> Sender: linux-kernel-owner@vger.kernel.org To: Linux PM Cc: Peter Zijlstra , Frederic Weisbecker , Thomas Gleixner , Paul McKenney , Thomas Ilsche , Doug Smythies , Rik van Riel , Aubrey Li , Mike Galbraith , LKML List-Id: linux-pm@vger.kernel.org On Monday, March 12, 2018 10:36:27 AM CET Rafael J. Wysocki wrote: > From: Rafael J. Wysocki > > If poll_idle() is allowed to spin until need_resched() returns 'true', > it may actually spin for a much longer time than expected by the idle > governor, since set_tsk_need_resched() is not always called by the > timer interrupt handler. If that happens, the CPU may spend much > more time than anticipated in the "polling" state. > > To prevent that from happening, limit the time of the spinning loop > in poll_idle(). > > Signed-off-by: Rafael J. Wysocki > --- > > -> v2: After additional testing reduce POLL_IDLE_TIME_CHECK_COUNT to 1000. > > --- > drivers/cpuidle/poll_state.c | 17 ++++++++++++++++- > 1 file changed, 16 insertions(+), 1 deletion(-) > > Index: linux-pm/drivers/cpuidle/poll_state.c > =================================================================== > --- linux-pm.orig/drivers/cpuidle/poll_state.c > +++ linux-pm/drivers/cpuidle/poll_state.c > @@ -5,16 +5,31 @@ > */ > > #include > +#include > #include > #include > > +#define POLL_IDLE_TIME_CHECK_COUNT 1000 > +#define POLL_IDLE_TIME_LIMIT (TICK_NSEC / 16) > + > static int __cpuidle poll_idle(struct cpuidle_device *dev, > struct cpuidle_driver *drv, int index) > { > + ktime_t start = ktime_get(); > + > local_irq_enable(); > if (!current_set_polling_and_test()) { > - while (!need_resched()) > + unsigned int time_check_counter = 0; > + > + while (!need_resched()) { > cpu_relax(); > + if (time_check_counter++ < POLL_IDLE_TIME_CHECK_COUNT) > + continue; > + > + time_check_counter = 0; > + if (ktime_sub(ktime_get(), start) > POLL_IDLE_TIME_LIMIT) > + break; > + } > } > current_clr_polling(); > No comments, so I'm assuming no objections or concerns. I've seen reports telling me that this patch alone may reduce the CPU package power by as much as 30% sometimes. Thanks!