The patch titled
ppc64: pSeries idle fixups
has been added to the -mm tree. Its filename is
ppc64-pseries-idle-fixups.patch
Patches currently in -mm which might be from [EMAIL PROTECTED] are
ppc64-use-c99-initialisers-in-cputable-code.patch
ppc64-fix-runlatch-code-to-work-on-pseries-machines.patch
ppc64-turn-runlatch-on-in-exception-entry.patch
move-ioprio-syscalls-into-syscallsh.patch
ppc64-sys_ppc32c-cleanups.patch
ppc64-add-ioprio-syscalls.patch
ppc64-remove-duplicate-syscall-reservation.patch
hvc_console-rearrange-code.patch
hvc_console-match-vio-and-console-devices-using-vterm-numbers.patch
hvc_console-dont-always-kick-the-poll-thread-in-interrupt.patch
hvc_console-magic_sysrq-should-only-be-on-console-channel.patch
hvc_console-unregister-the-console-in-the-exit-routine.patch
hvc_console-add-missing-include.patch
hvc_console-remove-num_vterms-and-some-dead-code.patch
hvc_console-statically-initialize-the-vtermnos-array.patch
hvc_console-add-some-sanity-checks.patch
hvc_console-separate-hvc_console-and-vio-code.patch
hvc_console-separate-hvc_console-and-vio-code-2.patch
hvc_console-register-ops-when-setting-up-hvc_console.patch
hvc_console-separate-the-nul-character-filtering-from-get_hvc_chars.patch
hvc_console-use-hvc_get_chars-in-hvsi-code.patch
ppc64-make-idle_loop-a-ppc_md-function.patch
ppc64-move-iseries_idle-into-iseries_setupc.patch
ppc64-move-pseries-idle-functions-into-pseries_setupc.patch
ppc64-fixup-platforms-for-new-ppc_mdidle.patch
ppc64-remove-obsolete-idle_setup.patch
ppc64-iseries-idle-fixups.patch
ppc64-pseries-idle-fixups.patch
ppc64-idle-fixups.patch
ppc64-fix-compile-warning.patch
ppc64-be-consistent-about-printing-which-idle-loop-were-using.patch
From: Anton Blanchard <[EMAIL PROTECTED]>
- separate out sleep logic in dedicated_idle, it was so far indented
that it got squashed against the right side of the screen.
- add runlatch support, looping on runlatch disable.
Signed-off-by: Anton Blanchard <[EMAIL PROTECTED]>
Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
---
arch/ppc64/kernel/pSeries_setup.c | 113 ++++++++++++++++++++------------------
1 files changed, 62 insertions(+), 51 deletions(-)
diff -puN arch/ppc64/kernel/pSeries_setup.c~ppc64-pseries-idle-fixups
arch/ppc64/kernel/pSeries_setup.c
--- 25/arch/ppc64/kernel/pSeries_setup.c~ppc64-pseries-idle-fixups Wed Jul
6 14:10:18 2005
+++ 25-akpm/arch/ppc64/kernel/pSeries_setup.c Wed Jul 6 14:10:18 2005
@@ -83,8 +83,8 @@ int fwnmi_active; /* TRUE if an FWNMI h
extern void pSeries_system_reset_exception(struct pt_regs *regs);
extern int pSeries_machine_check_exception(struct pt_regs *regs);
-static int shared_idle(void);
-static int dedicated_idle(void);
+static int pseries_shared_idle(void);
+static int pseries_dedicated_idle(void);
static volatile void __iomem * chrp_int_ack_special;
struct mpic *pSeries_mpic;
@@ -238,10 +238,10 @@ static void __init pSeries_setup_arch(vo
if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) {
if (get_paca()->lppaca.shared_proc) {
printk(KERN_INFO "Using shared processor idle loop\n");
- ppc_md.idle_loop = shared_idle;
+ ppc_md.idle_loop = pseries_shared_idle;
} else {
printk(KERN_INFO "Using dedicated idle loop\n");
- ppc_md.idle_loop = dedicated_idle;
+ ppc_md.idle_loop = pseries_dedicated_idle;
}
} else {
printk(KERN_INFO "Using default idle loop\n");
@@ -438,15 +438,47 @@ static int __init pSeries_probe(int plat
DECLARE_PER_CPU(unsigned long, smt_snooze_delay);
-int dedicated_idle(void)
+static inline void dedicated_idle_sleep(unsigned int cpu)
+{
+ struct paca_struct *ppaca = &paca[cpu ^ 1];
+
+ /* Only sleep if the other thread is not idle */
+ if (!(ppaca->lppaca.idle)) {
+ local_irq_disable();
+
+ /*
+ * We are about to sleep the thread and so wont be polling any
+ * more.
+ */
+ clear_thread_flag(TIF_POLLING_NRFLAG);
+
+ /*
+ * SMT dynamic mode. Cede will result in this thread going
+ * dormant, if the partner thread is still doing work. Thread
+ * wakes up if partner goes idle, an interrupt is presented, or
+ * a prod occurs. Returning from the cede enables external
+ * interrupts.
+ */
+ if (!need_resched())
+ cede_processor();
+ else
+ local_irq_enable();
+ } else {
+ /*
+ * Give the HV an opportunity at the processor, since we are
+ * not doing any work.
+ */
+ poll_pending();
+ }
+}
+
+static int pseries_dedicated_idle(void)
{
long oldval;
- struct paca_struct *lpaca = get_paca(), *ppaca;
+ struct paca_struct *lpaca = get_paca();
+ unsigned int cpu = smp_processor_id();
unsigned long start_snooze;
unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay);
- unsigned int cpu = smp_processor_id();
-
- ppaca = &paca[cpu ^ 1];
while (1) {
/*
@@ -458,9 +490,13 @@ int dedicated_idle(void)
oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
if (!oldval) {
set_thread_flag(TIF_POLLING_NRFLAG);
+
start_snooze = __get_tb() +
*smt_snooze_delay * tb_ticks_per_usec;
+
while (!need_resched() && !cpu_is_offline(cpu)) {
+ ppc64_runlatch_off();
+
/*
* Go into low thread priority and possibly
* low power mode.
@@ -468,60 +504,31 @@ int dedicated_idle(void)
HMT_low();
HMT_very_low();
- if (*smt_snooze_delay == 0 ||
- __get_tb() < start_snooze)
- continue;
-
- HMT_medium();
-
- if (!(ppaca->lppaca.idle)) {
- local_irq_disable();
-
- /*
- * We are about to sleep the thread
- * and so wont be polling any
- * more.
- */
- clear_thread_flag(TIF_POLLING_NRFLAG);
-
- /*
- * SMT dynamic mode. Cede will result
- * in this thread going dormant, if the
- * partner thread is still doing work.
- * Thread wakes up if partner goes idle,
- * an interrupt is presented, or a prod
- * occurs. Returning from the cede
- * enables external interrupts.
- */
- if (!need_resched())
- cede_processor();
- else
- local_irq_enable();
- } else {
- /*
- * Give the HV an opportunity at the
- * processor, since we are not doing
- * any work.
- */
- poll_pending();
+ if (*smt_snooze_delay != 0 &&
+ __get_tb() > start_snooze) {
+ HMT_medium();
+ dedicated_idle_sleep(cpu);
}
+
}
+ HMT_medium();
clear_thread_flag(TIF_POLLING_NRFLAG);
} else {
set_need_resched();
}
- HMT_medium();
lpaca->lppaca.idle = 0;
+ ppc64_runlatch_on();
+
schedule();
+
if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
cpu_die();
}
- return 0;
}
-static int shared_idle(void)
+static int pseries_shared_idle(void)
{
struct paca_struct *lpaca = get_paca();
unsigned int cpu = smp_processor_id();
@@ -535,6 +542,7 @@ static int shared_idle(void)
while (!need_resched() && !cpu_is_offline(cpu)) {
local_irq_disable();
+ ppc64_runlatch_off();
/*
* Yield the processor to the hypervisor. We return if
@@ -550,13 +558,16 @@ static int shared_idle(void)
cede_processor();
else
local_irq_enable();
+
+ HMT_medium();
}
- HMT_medium();
lpaca->lppaca.idle = 0;
+ ppc64_runlatch_on();
+
schedule();
- if (cpu_is_offline(smp_processor_id()) &&
- system_state == SYSTEM_RUNNING)
+
+ if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
cpu_die();
}
_
-
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html