Re: [patch] idle_task was wasting a lot of CPU

Andrea Arcangeli (andrea@e-mind.com)
Fri, 27 Nov 1998 20:41:45 +0100 (CET)


On Fri, 27 Nov 1998, Linus Torvalds wrote:

>Hmm.. The idle tasks _should_ have a negative counter value all the time,

I' ve fixed some things you pointed out in the last emails (it includes
also a wrap fix for cpu_idle() UP and the little SMP change around
switch_to()).

Index: linux/arch/i386/kernel/process.c
diff -u linux/arch/i386/kernel/process.c:1.1.1.2 linux/arch/i386/kernel/process.c:1.1.1.1.2.4
--- linux/arch/i386/kernel/process.c:1.1.1.2 Fri Nov 27 11:15:16 1998
+++ linux/arch/i386/kernel/process.c Fri Nov 27 20:37:33 1998
@@ -106,26 +106,28 @@

asmlinkage int sys_idle(void)
{
- unsigned long start_idle = 0;
- int ret = -EPERM;
+ unsigned long start_time = 0;
+ int ret = -EPERM, started = 0;

lock_kernel();
if (current->pid != 0)
goto out;
/* endless idle loop with no priority at all */
current->priority = 0;
- current->counter = 0;
+ /* counter must be -4, see reschedule_idle() in sched.c */
+ current->counter = -4;
for (;;) {
/*
* We are locked at this point. So we can safely call
* the APM bios knowing only one CPU at a time will do
* so.
*/
- if (!start_idle) {
+ if (!started) {
+ started = 1;
check_pgt_cache();
- start_idle = jiffies;
+ start_time = jiffies;
}
- if (jiffies - start_idle > HARD_IDLE_TIMEOUT)
+ if (started && jiffies - start_time > HARD_IDLE_TIMEOUT)
hard_idle();
else {
if (boot_cpu_data.hlt_works_ok && !hlt_counter && !current->need_resched)
@@ -133,7 +135,7 @@
}
run_task_queue(&tq_scheduler);
if (current->need_resched)
- start_idle = 0;
+ started = 0;
schedule();
}
ret = 0;
@@ -150,7 +152,10 @@

int cpu_idle(void *unused)
{
+ /* endless idle loop with no priority at all */
current->priority = 0;
+ /* counter must be -4, see reschedule_idle() in sched.c */
+ current->counter = -4;
while(1)
{
if(current_cpu_data.hlt_works_ok &&
@@ -159,8 +164,6 @@
check_pgt_cache();
run_task_queue(&tq_scheduler);

- /* endless idle loop with no priority at all */
- current->counter = 0;
schedule();
}
}
Index: linux/kernel/sched.c
diff -u linux/kernel/sched.c:1.1.1.2 linux/kernel/sched.c:1.1.1.1.2.19
--- linux/kernel/sched.c:1.1.1.2 Fri Nov 27 11:19:09 1998
+++ linux/kernel/sched.c Fri Nov 27 21:14:24 1998
@@ -7,6 +7,8 @@
* 1996-12-23 Modified by Dave Grothe to fix bugs in semaphores and
* make semaphores SMP safe
* 1997-01-28 Modified by Finn Arne Gangstad to make timers scale better.
+ * 1998-11-19 Implemented schedule_timeout() and related stuff
+ * by Andrea Arcangeli
*/

/*
@@ -130,8 +133,8 @@
}
#endif
#endif
- if (p->policy != SCHED_OTHER || p->counter > current->counter + 3)
- current->need_resched = 1;
+ if (p->counter > current->counter + 3 || p->policy != SCHED_OTHER)
+ current->need_resched = 1;
}

/*
@@ -437,23 +444,6 @@
struct timer_list timer;
unsigned long expire;

- /*
- * PARANOID.
- */
- if (current->state == TASK_UNINTERRUPTIBLE)
- {
- printk(KERN_WARNING "schedule_timeout: task not interrutible "
- "from %p\n", __builtin_return_address(0));
- /*
- * We don' t want to interrupt a not interruptible task
- * risking to cause corruption. Better a a deadlock ;-).
- */
- timeout = MAX_SCHEDULE_TIMEOUT;
- }
-
- /*
- * Here we start for real.
- */
switch (timeout)
{
case MAX_SCHEDULE_TIMEOUT:
@@ -594,10 +584,12 @@

#ifdef __SMP__
next->has_cpu = 1;
- next->processor = this_cpu;
#endif

if (prev != next) {
+#ifdef __SMP__
+ next->processor = this_cpu;
+#endif
kstat.context_swtch++;
get_mmu_context(next);
switch_to(prev,next);
Andrea Arcangeli

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/