Messages in this thread Patch in this message | | | Date | Wed, 12 Jun 2002 10:19:51 -0600 (MDT) | From | "Bhavesh P. Davda" <> | Subject | [PATCH] SCHED_FIFO and SCHED_RR scheduler fix, kernel 2.4.18 |
| |
The 2.4.18 kernel was behaving incorrectly for SCHED_FIFO and SCHED_RR scheduling.
The correct behaviour for SCHED_FIFO is priority preemption: run to completion, or system call, or preemption by higher priority process. The correct behaviour for SCHED_RR is the same as SCHED_FIFO for the preemption case, or run for a time slice, and go to the back of the run queue for that priority.
More details can be found at:
http://www.opengroup.org/onlinepubs/7908799/xsh/realtime.html
As a side note, SCHED_RR is completely broken in the 2.2 series kernels.
This is a small patch, but fixes the behaviour for SCHED_FIFO and SCHED_RR scheduling in the 2.4.18 kernel. It also improves the efficiency of the kernel by NOT calling schedule() for every tick for a SCHED_FIFO process.
-- Bhavesh P. Davda Avaya Inc bhavesh@avaya.com diff -Naur linux-2.4.18/kernel/sched.c linux-2.4.18-bpd/kernel/sched.c --- linux-2.4.18/kernel/sched.c Fri Dec 21 10:42:04 2001 +++ linux-2.4.18-bpd/kernel/sched.c Wed Jun 12 09:12:12 2002 @@ -318,13 +318,17 @@ /* * Careful! * - * This has to add the process to the _beginning_ of the - * run-queue, not the end. See the comment about "This is - * subtle" in the scheduler proper.. + * This has to add the process to the _end_ of the + * run-queue, not the beginning. The goodness value will + * determine whether this process will run next. This is + * important to get SCHED_FIFO and SCHED_RR right, where + * a process that is either pre-empted or its time slice + * has expired, should be moved to the tail of the run + * queue for its priority - Bhavesh Davda */ static inline void add_to_runqueue(struct task_struct * p) { - list_add(&p->run_list, &runqueue_head); + list_add_tail(&p->run_list, &runqueue_head); nr_running++; } @@ -334,12 +338,6 @@ list_add_tail(&p->run_list, &runqueue_head); } -static inline void move_first_runqueue(struct task_struct * p) -{ - list_del(&p->run_list); - list_add(&p->run_list, &runqueue_head); -} - /* * Wake up a process. Put it on the run-queue if it's not * already there. The "current" process is always on the @@ -955,8 +953,6 @@ retval = 0; p->policy = policy; p->rt_priority = lp.sched_priority; - if (task_on_runqueue(p)) - move_first_runqueue(p); current->need_resched = 1; diff -Naur linux-2.4.18/kernel/timer.c linux-2.4.18-bpd/kernel/timer.c --- linux-2.4.18/kernel/timer.c Mon Oct 8 11:41:41 2001 +++ linux-2.4.18-bpd/kernel/timer.c Wed Jun 12 09:13:43 2002 @@ -585,7 +585,14 @@ if (p->pid) { if (--p->counter <= 0) { p->counter = 0; - p->need_resched = 1; + /* + * SCHED_FIFO is priority preemption, so this is + * not the place to decide whether to reschedule a + * SCHED_FIFO task or not - Bhavesh Davda + */ + if (p->policy != SCHED_FIFO) { + p->need_resched = 1; + } } if (p->nice > 0) kstat.per_cpu_nice[cpu] += user_tick;
| |