rpms/kernel/F-8 linux-2.6-acpi-cpuidle-0-upstream.patch, NONE, 1.1 linux-2.6-acpi-cpuidle-1-fix-C3-for-no-bm-ctrl.patch, NONE, 1.1 linux-2.6-acpi-cpuidle-2-fix-HP-nx6125-regression.patch, NONE, 1.1 kernel.spec, 1.289, 1.290

Chuck Ebbert (cebbert) fedora-extras-commits at redhat.com
Wed Dec 5 22:59:02 UTC 2007


Author: cebbert

Update of /cvs/pkgs/rpms/kernel/F-8
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv9516

Modified Files:
	kernel.spec 
Added Files:
	linux-2.6-acpi-cpuidle-0-upstream.patch 
	linux-2.6-acpi-cpuidle-1-fix-C3-for-no-bm-ctrl.patch 
	linux-2.6-acpi-cpuidle-2-fix-HP-nx6125-regression.patch 
Log Message:
* Wed Dec 05 2007 Chuck Ebbert <cebbert at redhat.com>
- Fix some cpuidle bugs, should fix hangs on startup.


linux-2.6-acpi-cpuidle-0-upstream.patch:

--- NEW FILE linux-2.6-acpi-cpuidle-0-upstream.patch ---
Make our cpuidle code match upstream; what was added upstream by
commit 5062911830a66df0c0ad28c387a8c0623cb0d28c does not exactly
match what we already have.

---
 drivers/acpi/processor_idle.c |   29 ++++++-----------------------
 1 file changed, 6 insertions(+), 23 deletions(-)

--- linux-2.6.23.noarch.orig/drivers/acpi/processor_idle.c
+++ linux-2.6.23.noarch/drivers/acpi/processor_idle.c
@@ -821,7 +821,8 @@ static int acpi_idle_enter_simple(struct
 	struct acpi_processor *pr;
 	struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
 	u32 t1, t2;
-	int sleep_ticks;
+	int sleep_ticks = 0;
+
 	pr = processors[smp_processor_id()];
 
 	if (unlikely(!pr))
@@ -861,8 +862,6 @@ static int acpi_idle_enter_simple(struct
 	/* TSC could halt in idle, so notify users */
 	mark_tsc_unstable("TSC halts in idle");;
 #endif
-
-	/* Compute time (ticks) that we were actually asleep */
 	sleep_ticks = ticks_elapsed(t1, t2);
 
 	/* Tell the scheduler how much we idled: */
@@ -874,10 +873,6 @@ static int acpi_idle_enter_simple(struct
 	cx->usage++;
 
 	acpi_state_timer_broadcast(pr, cx, 0);
-
-	/* Do not account our idle-switching overhead: */
-	sleep_ticks -= cx->latency_ticks + C2_OVERHEAD;
-
 	cx->time += sleep_ticks;
 	return ticks_elapsed_in_us(t1, t2);
 }
@@ -898,7 +893,8 @@ static int acpi_idle_enter_bm(struct cpu
 	struct acpi_processor *pr;
 	struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
 	u32 t1, t2;
-	int sleep_ticks;
+	int sleep_ticks = 0;
+
 	pr = processors[smp_processor_id()];
 
 	if (unlikely(!pr))
@@ -921,6 +917,8 @@ static int acpi_idle_enter_bm(struct cpu
 		return 0;
 	}
 
+	/* Tell the scheduler that we are going deep-idle: */
+	sched_clock_idle_sleep_event();
 	/*
 	 * Must be done before busmaster disable as we might need to
 	 * access HPET !
@@ -933,10 +931,6 @@ static int acpi_idle_enter_bm(struct cpu
 		acpi_idle_update_bm_rld(pr, cx);
 
 		t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
-
-		/* Tell the scheduler that we are going deep-idle: */
-		sched_clock_idle_sleep_event();
-
 		acpi_idle_do_entry(cx);
 		t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
 	} else {
@@ -950,10 +944,6 @@ static int acpi_idle_enter_bm(struct cpu
 		spin_unlock(&c3_lock);
 
 		t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
-
-		/* Tell the scheduler that we are going deep-idle: */
-		sched_clock_idle_sleep_event();
-
 		acpi_idle_do_entry(cx);
 		t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
 
@@ -969,10 +959,7 @@ static int acpi_idle_enter_bm(struct cpu
 	/* TSC could halt in idle, so notify users */
 	mark_tsc_unstable("TSC halts in idle");
 #endif
-
-	/* Compute time (ticks) that we were actually asleep */
 	sleep_ticks = ticks_elapsed(t1, t2);
-
 	/* Tell the scheduler how much we idled: */
 	sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
 
@@ -982,10 +969,6 @@ static int acpi_idle_enter_bm(struct cpu
 	cx->usage++;
 
 	acpi_state_timer_broadcast(pr, cx, 0);
-
-	/* Do not account our idle-switching overhead: */
-	sleep_ticks -= cx->latency_ticks + C3_OVERHEAD;
-
 	cx->time += sleep_ticks;
 	return ticks_elapsed_in_us(t1, t2);
 }

linux-2.6-acpi-cpuidle-1-fix-C3-for-no-bm-ctrl.patch:

--- NEW FILE linux-2.6-acpi-cpuidle-1-fix-C3-for-no-bm-ctrl.patch ---
Gitweb:     http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=c9c860e5349ef62cd9226694b3aa625ef66f504e
Commit:     c9c860e5349ef62cd9226694b3aa625ef66f504e
Parent:     83788c0caed3a425f64fa88fde7c78746b9cdd76
Author:     Venkatesh Pallipadi <venkatesh.pallipadi at intel.com>
AuthorDate: Mon Nov 19 19:48:00 2007 -0500
Committer:  Len Brown <len.brown at intel.com>
CommitDate: Mon Nov 19 21:25:23 2007 -0500

    cpuidle: fix C3 for no bus-master control case
    
    Port 18eab8550397f1f3d4b8b2c5257c88dae25d58ed
    (Enable C3 even when PM2_control is zero) to cpuidle.
    
    Without this patch, some systems will notice a regression
    when enabling CPU_IDLE -- C3 would no longer be available.
    
    Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi at intel.com>
    Signed-off-by: Len Brown <len.brown at intel.com>
---
 drivers/acpi/processor_idle.c |   35 +++++++++++++++++++++++++----------
 1 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 0cad56c..943a880 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -1514,23 +1514,38 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
 	} else {
 		acpi_idle_update_bm_rld(pr, cx);
 
-		spin_lock(&c3_lock);
-		c3_cpu_count++;
-		/* Disable bus master arbitration when all CPUs are in C3 */
-		if (c3_cpu_count == num_online_cpus())
-			acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
-		spin_unlock(&c3_lock);
+		/*
+		 * disable bus master
+		 * bm_check implies we need ARB_DIS
+		 * !bm_check implies we need cache flush
+		 * bm_control implies whether we can do ARB_DIS
+		 *
+		 * That leaves a case where bm_check is set and bm_control is
+		 * not set. In that case we cannot do much, we enter C3
+		 * without doing anything.
+		 */
+		if (pr->flags.bm_check && pr->flags.bm_control) {
+			spin_lock(&c3_lock);
+			c3_cpu_count++;
+			/* Disable bus master arbitration when all CPUs are in C3 */
+			if (c3_cpu_count == num_online_cpus())
+				acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
+			spin_unlock(&c3_lock);
+		} else if (!pr->flags.bm_check) {
+			ACPI_FLUSH_CPU_CACHE();
+		}
 
 		t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
 		acpi_idle_do_entry(cx);
 		t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
 
-		spin_lock(&c3_lock);
 		/* Re-enable bus master arbitration */
-		if (c3_cpu_count == num_online_cpus())
+		if (pr->flags.bm_check && pr->flags.bm_control) {
+			spin_lock(&c3_lock);
 			acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
-		c3_cpu_count--;
-		spin_unlock(&c3_lock);
+			c3_cpu_count--;
+			spin_unlock(&c3_lock);
+		}
 	}
 
 #if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)

linux-2.6-acpi-cpuidle-2-fix-HP-nx6125-regression.patch:

--- NEW FILE linux-2.6-acpi-cpuidle-2-fix-HP-nx6125-regression.patch ---
Gitweb:     http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=ddc081a19585c8ba5aad437779950c2ef215360a
Commit:     ddc081a19585c8ba5aad437779950c2ef215360a
Parent:     5062911830a66df0c0ad28c387a8c0623cb0d28c
Author:     Venkatesh Pallipadi <venkatesh.pallipadi at intel.com>
AuthorDate: Mon Nov 19 21:43:22 2007 -0500
Committer:  Len Brown <len.brown at intel.com>
CommitDate: Mon Nov 19 21:43:22 2007 -0500

    cpuidle: fix HP nx6125 regression
    
    Fix for http://bugzilla.kernel.org/show_bug.cgi?id=9355
    
    cpuidle always used to fallback to C2 if there is some bm activity while
    entering C3. But, presence of C2 is not always guaranteed. Change cpuidle
    algorithm to detect a safe_state to fallback in case of bm_activity and
    use that state instead of C2.
    
    Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi at intel.com>
    Signed-off-by: Len Brown <len.brown at intel.com>
---
 drivers/acpi/processor_idle.c |  125 ++++++++++++++++++-----------------------
 include/acpi/processor.h      |    1 -
 include/linux/cpuidle.h       |    1 +
 3 files changed, 56 insertions(+), 71 deletions(-)

diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 1af0694..8904f5c 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -197,6 +197,19 @@ static inline u32 ticks_elapsed_in_us(u32 t1, u32 t2)
 		return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2);
 }
 
+static void acpi_safe_halt(void)
+{
+	current_thread_info()->status &= ~TS_POLLING;
+	/*
+	 * TS_POLLING-cleared state must be visible before we
+	 * test NEED_RESCHED:
+	 */
+	smp_mb();
+	if (!need_resched())
+		safe_halt();
+	current_thread_info()->status |= TS_POLLING;
+}
+ 
 static inline u32 ticks_elapsed(u32 t1, u32 t2)
 {
 	if (t2 >= t1)
@@ -1385,15 +1385,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
 	if (pr->flags.bm_check)
 		acpi_idle_update_bm_rld(pr, cx);
 
-	current_thread_info()->status &= ~TS_POLLING;
-	/*
-	 * TS_POLLING-cleared state must be visible before we test
-	 * NEED_RESCHED:
-	 */
-	smp_mb();
-	if (!need_resched())
-		safe_halt();
-	current_thread_info()->status |= TS_POLLING;
+	acpi_safe_halt();
 
 	cx->usage++;
 
@@ -1493,6 +1485,15 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
 	if (unlikely(acpi_idle_suspend))
 		return acpi_idle_enter_c1(dev, state);
 
+	if (acpi_idle_bm_check()) {
+		if (dev->safe_state) {
+			return dev->safe_state->enter(dev, dev->safe_state);
+		} else {
+			acpi_safe_halt();
+			return 0;
+		}
+	}
+
 	local_irq_disable();
 	current_thread_info()->status &= ~TS_POLLING;
 	/*
@@ -1515,49 +1516,39 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
 	 */
 	acpi_state_timer_broadcast(pr, cx, 1);
 
-	if (acpi_idle_bm_check()) {
-		cx = pr->power.bm_state;
-
-		acpi_idle_update_bm_rld(pr, cx);
-
-		t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
-		acpi_idle_do_entry(cx);
-		t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
-	} else {
-		acpi_idle_update_bm_rld(pr, cx);
+	acpi_idle_update_bm_rld(pr, cx);
 
-		/*
-		 * disable bus master
-		 * bm_check implies we need ARB_DIS
-		 * !bm_check implies we need cache flush
-		 * bm_control implies whether we can do ARB_DIS
-		 *
-		 * That leaves a case where bm_check is set and bm_control is
-		 * not set. In that case we cannot do much, we enter C3
-		 * without doing anything.
-		 */
-		if (pr->flags.bm_check && pr->flags.bm_control) {
-			spin_lock(&c3_lock);
-			c3_cpu_count++;
-			/* Disable bus master arbitration when all CPUs are in C3 */
-			if (c3_cpu_count == num_online_cpus())
-				acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
-			spin_unlock(&c3_lock);
-		} else if (!pr->flags.bm_check) {
-			ACPI_FLUSH_CPU_CACHE();
-		}
+	/*
+	 * disable bus master
+	 * bm_check implies we need ARB_DIS
+	 * !bm_check implies we need cache flush
+	 * bm_control implies whether we can do ARB_DIS
+	 *
+	 * That leaves a case where bm_check is set and bm_control is
+	 * not set. In that case we cannot do much, we enter C3
+	 * without doing anything.
+	 */
+	if (pr->flags.bm_check && pr->flags.bm_control) {
+		spin_lock(&c3_lock);
+		c3_cpu_count++;
+		/* Disable bus master arbitration when all CPUs are in C3 */
+		if (c3_cpu_count == num_online_cpus())
+			acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
+		spin_unlock(&c3_lock);
+	} else if (!pr->flags.bm_check) {
+		ACPI_FLUSH_CPU_CACHE();
+	}
 
-		t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
-		acpi_idle_do_entry(cx);
-		t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+	t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+	acpi_idle_do_entry(cx);
+	t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
 
-		/* Re-enable bus master arbitration */
-		if (pr->flags.bm_check && pr->flags.bm_control) {
-			spin_lock(&c3_lock);
-			acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
-			c3_cpu_count--;
-			spin_unlock(&c3_lock);
-		}
+	/* Re-enable bus master arbitration */
+	if (pr->flags.bm_check && pr->flags.bm_control) {
+		spin_lock(&c3_lock);
+		acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
+		c3_cpu_count--;
+		spin_unlock(&c3_lock);
 	}
 
 #if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
@@ -1626,12 +1617,14 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
 			case ACPI_STATE_C1:
 			state->flags |= CPUIDLE_FLAG_SHALLOW;
 			state->enter = acpi_idle_enter_c1;
+			dev->safe_state = state;
 			break;
 
 			case ACPI_STATE_C2:
 			state->flags |= CPUIDLE_FLAG_BALANCED;
 			state->flags |= CPUIDLE_FLAG_TIME_VALID;
 			state->enter = acpi_idle_enter_simple;
+			dev->safe_state = state;
 			break;
 
 			case ACPI_STATE_C3:
@@ -1652,14 +1645,6 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
 	if (!count)
 		return -EINVAL;
 
-	/* find the deepest state that can handle active BM */
-	if (pr->flags.bm_check) {
-		for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++)
-			if (pr->power.states[i].type == ACPI_STATE_C3)
-				break;
-		pr->power.bm_state = &pr->power.states[i-1];
-	}
-
 	return 0;
 }
 
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index 26d79f6..76411b1 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -78,7 +78,6 @@ struct acpi_processor_cx {
 struct acpi_processor_power {
 	struct cpuidle_device dev;
 	struct acpi_processor_cx *state;
-	struct acpi_processor_cx *bm_state;
 	unsigned long bm_check_timestamp;
 	u32 default_state;
 	u32 bm_activity;
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index 16a5154..c4e0016 100644
--- a/include/linux/cpuidle.h
+++ b/include/linux/cpuidle.h
@@ -92,6 +92,7 @@ struct cpuidle_device {
 	struct kobject		kobj;
 	struct completion	kobj_unregister;
 	void			*governor_data;
+	struct cpuidle_state	*safe_state;
 };
 
 DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices);


Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-8/kernel.spec,v
retrieving revision 1.289
retrieving revision 1.290
diff -u -r1.289 -r1.290
--- kernel.spec	5 Dec 2007 16:23:14 -0000	1.289
+++ kernel.spec	5 Dec 2007 22:58:25 -0000	1.290
@@ -701,7 +701,10 @@
 #Patch780: linux-2.6-clockevents-fix-resume-logic.patch
 Patch750: linux-2.6-acpi-git-ec-init-fixes.patch
 Patch770: linux-2.6-pmtrace-time-fix.patch
-Patch780: linux-2.6-acpi-button-send-initial-state.patch
+Patch775: linux-2.6-acpi-button-send-initial-state.patch
+Patch780: linux-2.6-acpi-cpuidle-0-upstream.patch
+Patch781: linux-2.6-acpi-cpuidle-1-fix-C3-for-no-bm-ctrl.patch
+Patch782: linux-2.6-acpi-cpuidle-2-fix-HP-nx6125-regression.patch
 Patch800: linux-2.6-wakeups-hdaps.patch
 Patch801: linux-2.6-wakeups.patch
 Patch820: linux-2.6-compile-fixes.patch
@@ -1326,6 +1329,10 @@
 ApplyPatch linux-2.6-pmtrace-time-fix.patch
 # Send button state on create / resume
 ApplyPatch linux-2.6-acpi-button-send-initial-state.patch
+# fix cpuidle regressions
+ApplyPatch linux-2.6-acpi-cpuidle-0-upstream.patch
+ApplyPatch linux-2.6-acpi-cpuidle-1-fix-C3-for-no-bm-ctrl.patch
+ApplyPatch linux-2.6-acpi-cpuidle-2-fix-HP-nx6125-regression.patch
 
 # Fix excessive wakeups
 # Make hdaps timer only tick when in use.
@@ -1995,6 +2002,9 @@
 
 
 %changelog
+* Wed Dec 05 2007 Chuck Ebbert <cebbert at redhat.com>
+- Fix some cpuidle bugs, should fix hangs on startup.
+
 * Wed Dec 05 2007 John W. Linville <linville at redhat.com>
 - Some wireless driver bits headed for 2.6.25
 




More information about the fedora-extras-commits mailing list