From: Venki Pallipadi <venkatesh.pallipadi@intel.com>
To: Len Brown <lenb@kernel.org>
Cc: Adam Belay <abelay@novell.com>, Len Brown <len.brown@intel.com>,
Thomas Gleixner <tglx@linutronix.de>,
linux-kernel <linux-kernel@vger.kernel.org>,
Andrew Morton <akpm@osdl.org>, Shaohua Li <shaohua.li@intel.com>,
linux-acpi@vger.kernel.org
Subject: [PATCH 5/8] cpuidle: menu governor change the early break condition
Date: Wed, 6 Jun 2007 13:53:53 -0700 [thread overview]
Message-ID: <20070606205353.GE23906@linux-os.sc.intel.com> (raw)
Change the C-state early break out algorithm in menu governor.
We only look at early breakouts that result in wakeups shorter than idle state's
target_residency. If such a breakout is frequent enough, eliminate the
particular idle state upto a timeout period.
Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Index: linux-2.6.22-rc-mm/drivers/cpuidle/governors/menu.c
===================================================================
--- linux-2.6.22-rc-mm.orig/drivers/cpuidle/governors/menu.c 2007-06-05 09:39:27.000000000 -0700
+++ linux-2.6.22-rc-mm/drivers/cpuidle/governors/menu.c 2007-06-05 15:46:34.000000000 -0700
@@ -14,19 +14,20 @@
#include <linux/hrtimer.h>
#include <linux/tick.h>
-#define BM_HOLDOFF 20000 /* 20 ms */
+#define BM_HOLDOFF 20000 /* 20 ms */
+#define DEMOTION_THRESHOLD 5
+#define DEMOTION_TIMEOUT_MULTIPLIER 1000
struct menu_device {
int last_state_idx;
- int deepest_bm_state;
- int break_last_us;
- int break_elapsed_us;
+ int deepest_break_state;
+ struct timespec break_expire_time_ts;
+ int break_last_cnt;
+ int deepest_bm_state;
int bm_elapsed_us;
int bm_holdoff_us;
-
- unsigned long idle_jiffies;
};
static DEFINE_PER_CPU(struct menu_device, menu_devices);
@@ -45,7 +46,6 @@
/* determine the expected residency time */
expected_us = (s32) ktime_to_ns(tick_nohz_get_sleep_length()) / 1000;
- expected_us = min(expected_us, data->break_last_us);
/* determine the maximum state compatible with current BM status */
if (cpuidle_get_bm_activity())
@@ -53,17 +53,33 @@
if (data->bm_elapsed_us <= data->bm_holdoff_us)
max_state = data->deepest_bm_state + 1;
+ /* determine the maximum state compatible with recent idle breaks */
+ if (data->deepest_break_state >= 0) {
+ struct timespec now;
+ ktime_get_ts(&now);
+ if (timespec_compare(&data->break_expire_time_ts, &now) > 0) {
+ max_state = min(max_state,
+ data->deepest_break_state + 1);
+ } else {
+ data->deepest_break_state = -1;
+ }
+ }
+
/* find the deepest idle state that satisfies our constraints */
for (i = 1; i < max_state; i++) {
struct cpuidle_state *s = &dev->states[i];
+
if (s->target_residency > expected_us)
break;
+
if (s->exit_latency > system_latency_constraint())
break;
}
+ if (data->last_state_idx != i - 1)
+ data->break_last_cnt = 0;
+
data->last_state_idx = i - 1;
- data->idle_jiffies = tick_nohz_get_idle_jiffies();
return i - 1;
}
@@ -91,14 +107,27 @@
measured_us = USEC_PER_SEC / HZ;
data->bm_elapsed_us += measured_us;
- data->break_elapsed_us += measured_us;
+
+ if (data->last_state_idx == 0)
+ return;
/*
- * Did something other than the timer interrupt cause the break event?
+ * Did something other than the timer interrupt
+ * cause an early break event?
*/
- if (tick_nohz_get_idle_jiffies() == data->idle_jiffies) {
- data->break_last_us = data->break_elapsed_us;
- data->break_elapsed_us = 0;
+ if (unlikely(measured_us < target->target_residency)) {
+ if (data->break_last_cnt > DEMOTION_THRESHOLD) {
+ data->deepest_break_state = data->last_state_idx - 1;
+ ktime_get_ts(&data->break_expire_time_ts);
+ timespec_add_ns(&data->break_expire_time_ts,
+ target->target_residency *
+ DEMOTION_TIMEOUT_MULTIPLIER);
+ } else {
+ data->break_last_cnt++;
+ }
+ } else {
+ if (data->break_last_cnt > 0)
+ data->break_last_cnt--;
}
}
@@ -112,10 +141,9 @@
int i;
data->last_state_idx = 0;
- data->break_last_us = 0;
- data->break_elapsed_us = 0;
data->bm_elapsed_us = 0;
data->bm_holdoff_us = BM_HOLDOFF;
+ data->deepest_break_state = -1;
for (i = 1; i < dev->state_count; i++)
if (dev->states[i].flags & CPUIDLE_FLAG_CHECK_BM)
reply other threads:[~2007-06-06 20:57 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=20070606205353.GE23906@linux-os.sc.intel.com \
--to=venkatesh.pallipadi@intel.com \
--cc=abelay@novell.com \
--cc=akpm@osdl.org \
--cc=len.brown@intel.com \
--cc=lenb@kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=shaohua.li@intel.com \
--cc=tglx@linutronix.de \
/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.