Hello,
This message reports about a possible bug in the implementation of sched_yield()
in kernel 2.2.13, which might not have been fixed in later kernels. A patch
is proposed, which should solve the problem.
I did the following experiment on a single-CPU machine with kernel 2.2.13:
1) Open three shells
2) Launch "top" on the first shell
3) Launch the following (endless) "loop" program on the second shell:
void main (void)
{
for (;;);
return;
}
4) Launch the following (endless) "yield_loop" program on the third shell:
#include <asm/unistd.h>
int sched_yield (void)
{
long res;
__asm__ __volatile__ ("int $0x80":"=a"(res):
"0"(__NR_sched_yield)
);
return (int)res;
}
void main (void)
{
for (;;) sched_yield();
return;
}
5) Look at "top" in the first shell. You will see that both "loop" and
"yield_loop" consume about 50% CPU time. According to the semantics of
sched_yield(), however, one would expect 99% CPU time to be consumed by
"loop", and only a negligible fraction of CPU time to be consumed by
"yield_loop". Apparently, the implementation of sched_yield() is flawed.
I could solve the problem by modifying file kernel/sched.c in 2.2.13.
By comparing file kernel/sched.c in 2.2.13 and 2.3.99pre8 kernels, it
appears that the same bug should also occur with the latter, at least with
single-CPU machines. Could anyone confirm? If so, could anybody try applying
the following patch to kernel/sched.c in 2.3.99pre8 and see if it fixes the
bug? Thank you!
Giuseppe
Giuseppe Ciaccio http://www.disi.unige.it/person/CiaccioG/
DISI - Universita' di Genova via Dodecaneso 35 16146 Genova, Italy
phone +39 10 353 6638 fax +39 010 3536699 ciaccio@disi.unige.it
------------------------------------------------------------------------
*** sched.c Fri May 19 12:41:36 2000
--- sched.c.new Fri May 19 12:55:22 2000
***************
*** 10,15 ****
--- 10,17 ----
* 1998-11-19 Implemented schedule_timeout() and related stuff
* by Andrea Arcangeli
* 1998-12-28 Implemented better SMP scheduling by Ingo Molnar
+ * 2000-05-19 Fixed wrong semantics of sched_yield() caused by bugs in
+ * prev_goodness() and goodness(), by Giuseppe Ciaccio
*/
/*
***************
*** 113,118 ****
--- 115,126 ----
{
int weight;
+ /* Goodness of sched_yield()ed processes must be zero. */
+ if (p->policy & SCHED_YIELD) {
+ p->policy &= ~SCHED_YIELD;
+ return 0;
+ }
+
/*
* Realtime process, select the first one on the
* runqueue (taking priorities within processes
***************
*** 150,170 ****
return weight;
}
- /*
- * subtle. We want to discard a yielded process only if it's being
- * considered for a reschedule. Wakeup-time 'queries' of the scheduling
- * state do not count. Another optimization we do: sched_yield()-ed
- * processes are runnable (and thus will be considered for scheduling)
- * right when they are calling schedule(). So the only place we need
- * to care about SCHED_YIELD is when we calculate the previous process'
- * goodness ...
- */
static inline int prev_goodness(struct task_struct * p, int this_cpu, struct mm_struct *this_mm)
{
! if (p->policy & SCHED_YIELD) {
! p->policy &= ~SCHED_YIELD;
return 0;
- }
return goodness(p, this_cpu, this_mm);
}
--- 158,167 ----
return weight;
}
static inline int prev_goodness(struct task_struct * p, int this_cpu, struct mm_struct *this_mm)
{
! if (p->policy & SCHED_YIELD)
return 0;
return goodness(p, this_cpu, this_mm);
}
-
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/
This archive was generated by hypermail 2b29 : Tue May 23 2000 - 21:00:17 EST