aboutsummaryrefslogtreecommitdiff
path: root/arch/ppc64/kernel
diff options
context:
space:
mode:
authorAnton Blanchard2005-07-07 17:56:32 -0700
committerLinus Torvalds2005-07-07 18:23:41 -0700
commit3c57bb9f454e8fc7b3d815b991b0dec43c766641 (patch)
treef9bfb5f481a3967eee66603107065fa728602448 /arch/ppc64/kernel
parent08d5e3eb4b2141e1031835c89a62ee3ddf896641 (diff)
[PATCH] ppc64: iSeries idle fixups
- remove min/max yield time, we dont use the values anywhere - separate shared and dedicated idle loops - check need_resched again with irqs off to avoid sleeping with pending work - continually set runlatch off in idle loop, this means we dont need to turn the runlatch off on exception exit and suffer that associated cost for all exceptions. (A future patch will turn the runlatch on at exception entry) Signed-off-by: Anton Blanchard <anton@samba.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/ppc64/kernel')
-rw-r--r--arch/ppc64/kernel/iSeries_setup.c84
1 files changed, 47 insertions, 37 deletions
diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c
index fae215ea54b4..b4c919e18fa7 100644
--- a/arch/ppc64/kernel/iSeries_setup.c
+++ b/arch/ppc64/kernel/iSeries_setup.c
@@ -834,9 +834,6 @@ static int __init iSeries_src_init(void)
late_initcall(iSeries_src_init);
-static unsigned long maxYieldTime = 0;
-static unsigned long minYieldTime = 0xffffffffffffffffUL;
-
static inline void process_iSeries_events(void)
{
asm volatile ("li 0,0x5555; sc" : : : "r0", "r3");
@@ -845,7 +842,6 @@ static inline void process_iSeries_events(void)
static void yield_shared_processor(void)
{
unsigned long tb;
- unsigned long yieldTime;
HvCall_setEnabledInterrupts(HvCall_MaskIPI |
HvCall_MaskLpEvent |
@@ -856,13 +852,6 @@ static void yield_shared_processor(void)
/* Compute future tb value when yield should expire */
HvCall_yieldProcessor(HvCall_YieldTimed, tb+tb_ticks_per_jiffy);
- yieldTime = get_tb() - tb;
- if (yieldTime > maxYieldTime)
- maxYieldTime = yieldTime;
-
- if (yieldTime < minYieldTime)
- minYieldTime = yieldTime;
-
/*
* The decrementer stops during the yield. Force a fake decrementer
* here and let the timer_interrupt code sort out the actual time.
@@ -871,45 +860,62 @@ static void yield_shared_processor(void)
process_iSeries_events();
}
-static int iSeries_idle(void)
+static int iseries_shared_idle(void)
{
- struct paca_struct *lpaca;
- long oldval;
+ while (1) {
+ while (!need_resched() && !hvlpevent_is_pending()) {
+ local_irq_disable();
+ ppc64_runlatch_off();
+
+ /* Recheck with irqs off */
+ if (!need_resched() && !hvlpevent_is_pending())
+ yield_shared_processor();
- /* ensure iSeries run light will be out when idle */
- ppc64_runlatch_off();
+ HMT_medium();
+ local_irq_enable();
+ }
+
+ ppc64_runlatch_on();
- lpaca = get_paca();
+ if (hvlpevent_is_pending())
+ process_iSeries_events();
+
+ schedule();
+ }
+
+ return 0;
+}
+
+static int iseries_dedicated_idle(void)
+{
+ struct paca_struct *lpaca = get_paca();
+ long oldval;
while (1) {
- if (lpaca->lppaca.shared_proc) {
- if (hvlpevent_is_pending())
- process_iSeries_events();
- if (!need_resched())
- yield_shared_processor();
- } else {
- oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
+ oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
- if (!oldval) {
- set_thread_flag(TIF_POLLING_NRFLAG);
+ if (!oldval) {
+ set_thread_flag(TIF_POLLING_NRFLAG);
- while (!need_resched()) {
+ while (!need_resched()) {
+ ppc64_runlatch_off();
+ HMT_low();
+
+ if (hvlpevent_is_pending()) {
HMT_medium();
- if (hvlpevent_is_pending())
- process_iSeries_events();
- HMT_low();
+ ppc64_runlatch_on();
+ process_iSeries_events();
}
-
- HMT_medium();
- clear_thread_flag(TIF_POLLING_NRFLAG);
- } else {
- set_need_resched();
}
+
+ HMT_medium();
+ clear_thread_flag(TIF_POLLING_NRFLAG);
+ } else {
+ set_need_resched();
}
ppc64_runlatch_on();
schedule();
- ppc64_runlatch_off();
}
return 0;
@@ -940,6 +946,10 @@ void __init iSeries_early_setup(void)
ppc_md.get_rtc_time = iSeries_get_rtc_time;
ppc_md.calibrate_decr = iSeries_calibrate_decr;
ppc_md.progress = iSeries_progress;
- ppc_md.idle_loop = iSeries_idle;
+
+ if (get_paca()->lppaca.shared_proc)
+ ppc_md.idle_loop = iseries_shared_idle;
+ else
+ ppc_md.idle_loop = iseries_dedicated_idle;
}