[PATCH] sched_yield() flawed since 2.2.13?

From: Giuseppe Ciaccio (ciaccio@disi.unige.it)
Date: Fri May 19 2000 - 10:24:52 EST


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