All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 5/8] cpuidle: menu governor change the early break condition
@ 2007-06-06 20:53 Venki Pallipadi
  0 siblings, 0 replies; only message in thread
From: Venki Pallipadi @ 2007-06-06 20:53 UTC (permalink / raw)
  To: Len Brown
  Cc: Adam Belay, Len Brown, Thomas Gleixner, linux-kernel,
	Andrew Morton, Shaohua Li, linux-acpi



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)

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2007-06-06 20:57 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-06-06 20:53 [PATCH 5/8] cpuidle: menu governor change the early break condition Venki Pallipadi

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.