lkml.org 
[lkml]   [2001]   [May]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
SubjectRe: [patch] sched_yield in 2.2.x - version 2
Date
Hello,

please CC: replies to me as I am not subscribed to the list.

> The real problem with this patch is that if a real time task yields, the
> patch will cause the scheduler to pick a lower priority task or a
> SCHED_OTHER task. This one is not so easy to solve. You want to scan
> the run_list in the proper order so that the real time task will be the
> last pick at its priority. Problem is, the pre load with the prev task
> is out of order. You might try: http://rtsched.sourceforge.net/

No it's not a problem at all, since RR tasks will just be moved to the end of
the queue and no SCHED_YIELD flag is set for them => no lower-priority task may
be scheduled.

However, I found a bug in my own patch :-)
The problem is that when a process yields and no process has a timeslice left,
recalc is called. But then we lose YIELD flag once again. So the simple
solution (and hopefully this time right :-) was to NOT clear YIELD flag at all
before exit from schedule() and move test for this flag from goodness_prev() to
goodness() function (getting rid of goodness_prev() altogether).

However, one of my tests still show strange behavior, so maybe you will get 3rd
version of the patch :-) Anyway, I got good 30% performance boost for
high-contention case in user-space spinlocks when sched_yield() is working
right.

Another function that would be very interesting is possibility to give up our
timeslice to specific other process. This way I could transfer control to other
process/thread that owns the lock directly so that process/thread may finish
working with the lock. This can again speed up everything. When I have now 4
processes contending for a lock, I get performance 1x. However, when there are
20 processes contending, performance is only 0.7x. I suppose this is due to
excessive context switches. I will try to implement something like
"sched_switchto" to switch to specific pid (from user space) and see if that
helps. Or is there such a function already?

Ivan Schreter
is@zapwerk.com
--- kernel/sched.c.orig Wed May 30 01:17:24 2001
+++ kernel/sched.c Wed May 30 12:30:03 2001
@@ -145,6 +145,11 @@
{
int weight;

+ if (p->policy & SCHED_YIELD) {
+ /* do not schedule yielded process now */
+ return -1;
+ }
+
/*
* Realtime process, select the first one on the
* runqueue (taking priorities within processes
@@ -183,25 +188,6 @@
}

/*
- * 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 * prev,
- struct task_struct * p, int this_cpu)
-{
- if (p->policy & SCHED_YIELD) {
- p->policy &= ~SCHED_YIELD;
- return 0;
- }
- return goodness(prev, p, this_cpu);
-}
-
-/*
* the 'goodness value' of replacing a process on a given CPU.
* positive value means 'replace', zero or negative means 'dont'.
*/
@@ -740,6 +726,10 @@
/* Do we need to re-calculate counters? */
if (!c)
goto recalculate;
+
+ /* clean up potential SCHED_YIELD bit */
+ prev->policy &= ~SCHED_YIELD;
+
/*
* from this point on nothing can prevent us from
* switching to the next task, save this fact in
@@ -809,7 +799,7 @@
}

still_running:
- c = prev_goodness(prev, prev, this_cpu);
+ c = goodness(prev, prev, this_cpu);
next = prev;
goto still_running_back;
\
 
 \ /
  Last update: 2005-03-22 12:54    [W:0.045 / U:0.344 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site