diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2010-01-21 00:00:32 +0100 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2010-01-21 00:32:01 +0100 |
commit | 1679c2af7997aae234ebbeb8726800c45777bef3 (patch) | |
tree | a15b910a5bc4abe7a633a386d50e2eac6293db33 | |
parent | 1f10ed61d75f849395fffcb46251510bd287d91d (diff) | |
download | lwn-1679c2af7997aae234ebbeb8726800c45777bef3.tar.gz lwn-1679c2af7997aae234ebbeb8726800c45777bef3.zip |
sched: Hack to make prio ceiling posix compliant
POSIX scheduling semantics for SCHED_FIFO require that a thread whose
priority is changed via pthread_setschedprio() is enqueued to the head
of the new priority list when the thread is running and the new
priority is lower than the old priority. This is required to implement
user space driven priority ceiling.
The sys_sched_setscheduler() and sys_sched_setparam() semantics are
POSIX compliant as they move the thread to the tail of the priority
list.
The lack of the sys_sched_setprio syscall and the resulting usage of
sys_sched_setscheduler() resp. sys_sched_setparam() results in the
following non POSIX compliant scenario:
Task A and B are runnable and in the same priority list X
task A runs and boosts itself for priority ceiling to prio Y
task A unboost itself to its original priority X
-> task A gets dequeued from priority list Y
-> task A gets enqueued at the tail of priority list X
task B runs
Work around that to make prio ceiling work as expected:
Queue task to head when task is running and task is lowering its
priority. This works around the non-availability of a sched_setprio
syscall which was tinkered into the posix spec to make prio ceiling
work correctly.
This workaround violates the posix scheduling semantics of tail
queueing in the case that the priority was changed by anything else
than sched_setprio, but there is no other breakage lurking than some
specification fetishists going berserk on me.
Fixing this in mainline needs more thoughts.
Reported-by: Mathias Weber <mathias.weber.mw1@roche.com>
Reported-by: Carsten Emde <cbe@osadl.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | kernel/sched.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index 1ca987256375..590b9bb06540 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -6653,7 +6653,25 @@ recheck: if (running) p->sched_class->set_curr_task(rq); if (on_rq) { - activate_task(rq, p, 0, false); + /* + * Workaround to make prio ceiling work as expected: + * + * Queue task to head when task is running and task is + * lowering its priority. This works around the non- + * availability of a sched_setprio syscall which was + * tinkered into the posix spec to make prio ceiling + * work correctly. + * + * This workaround violates the posix scheduling + * semantics of tail queueing in the case that the + * priority was changed by anything else than + * sched_setprio, but there is no other breakage + * lurking than some specification fetishists going + * berserk on me. + * + * Fixing this in mainline needs more thoughts. + */ + activate_task(rq, p, 0, running && oldprio < p->prio); check_class_changed(rq, p, prev_class, oldprio, running); } |