C-State policy and dynticks [Was: [PATCH] i386 no idle HZ aka Dynticks 051203]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Make the ACPI C-States policy smarter when dynticks are enabled:

- reprogram the timer if bus mastering activity is present, so that we don't
  sleep too long in C2, but hopefully can switch to C3 then.
- promote to a higher C-State more easily: if we slept for more than 2
  jiffies the last time, and we're intended to sleep for more than 2
  jiffies now, promote. This is justified as the current policy looks at
  whether we slept longer than a certain threshold for the last 4 or 10
  times; but we usually sleep much longer when dynticks are enabled.

Signed-off-by: Dominik Brodowski <[email protected]>

Index: working-tree/drivers/acpi/processor_idle.c
===================================================================
--- working-tree.orig/drivers/acpi/processor_idle.c
+++ working-tree/drivers/acpi/processor_idle.c
@@ -38,6 +38,7 @@
 #include <linux/dmi.h>
 #include <linux/moduleparam.h>
 #include <linux/sched.h>	/* need_resched() */
+#include <linux/dyn-tick.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -60,6 +61,8 @@ module_param(max_cstate, uint, 0644);
 static unsigned int nocst = 0;
 module_param(nocst, uint, 0000);
 
+#define BM_JIFFIES	(HZ >= 800 ? 4 : 2)
+
 /*
  * bm_history -- bit-mask with a bit per jiffy of bus-master activity
  * 1000 HZ: 0xFFFFFFFF: 32 jiffies = 32ms
@@ -177,6 +180,7 @@ static void acpi_safe_halt(void)
 }
 
 static atomic_t c3_cpu_count;
+static int last_sleep = 0;
 
 static void acpi_processor_idle(void)
 {
@@ -259,7 +263,7 @@ static void acpi_processor_idle(void)
 		 * If bus mastering is active, automatically demote
 		 * to avoid a faulty transition.  Note that the processor
 		 * won't enter a low-power state during this call (to this
-		 * funciton) but should upon the next.
+		 * function) but should upon the next.
 		 *
 		 * TBD: A better policy might be to fallback to the demotion
 		 *      state (use it for this quantum only) istead of
@@ -270,10 +274,31 @@ static void acpi_processor_idle(void)
 		if (bm_status && cx->demotion.threshold.bm) {
 			local_irq_enable();
 			next_state = cx->demotion.state;
+			if (dyn_tick_enabled())
+				dyn_early_reprogram(BM_JIFFIES);
+			last_sleep = 0; /* do not promote in fast-path */
+			goto end;
+		}
+	}
+
+	/*
+	 * Fast-path promotion: if we slept for more than 2 jiffies the last
+	 * time, and we're intended to sleep for more than 2 jiffies now,
+	 * promote. Note that the processor won't enter a low-power state
+	 * during this call (to this funciton) but should upon the next.
+	 */
+	if (dyn_tick_enabled()) {
+		if (cx->promotion.state && cx->promotion.count &&
+		    (last_sleep > BM_JIFFIES) &&
+		    (dyn_tick->skip > BM_JIFFIES)) {
+			local_irq_enable();
+			next_state = cx->promotion.state;
 			goto end;
 		}
 	}
 
+	last_sleep = 0;
+
 #ifdef CONFIG_HOTPLUG_CPU
 	/*
 	 * Check for P_LVL2_UP flag before entering C2 and above on
@@ -391,9 +416,10 @@ static void acpi_processor_idle(void)
 		cx->time += (PM_TIMER_FREQUENCY / (2 * HZ));
 	}
 
+	last_sleep = sleep_ticks / (PM_TIMER_FREQUENCY / HZ);
+
 	if (pr->flags.bm_check)
-		pr->power.bm_check_timestamp += sleep_ticks /
-			(PM_TIMER_FREQUENCY / HZ);
+		pr->power.bm_check_timestamp += last_sleep;
 
 	next_state = pr->power.state;
 
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux