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]