summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorCon Kolivas <kernel@kolivas.org>2016-10-17 08:52:51 +1100
committerCon Kolivas <kernel@kolivas.org>2016-10-17 08:56:17 +1100
commit2ce037a2f25ef96cdde06912f71cf3652abea0c8 (patch)
tree3ea5b91123988ab2e15b338333eecf3b8cc3e739 /kernel
parent755fcbd33b7c03d1c7268a63dcf29d94b6a05b49 (diff)
Yielding repeatedly without resetting timeslice and deadline can lead to tasks bouncing to another CPU immediately instead of yielding leading to infinitely bouncing between CPUs. Improve behaviour by positively calling timeslice_expired.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/sched/MuQSS.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/kernel/sched/MuQSS.c b/kernel/sched/MuQSS.c
index 7d48f697e564..525505f9212b 100644
--- a/kernel/sched/MuQSS.c
+++ b/kernel/sched/MuQSS.c
@@ -5074,6 +5074,7 @@ SYSCALL_DEFINE0(sched_yield)
p = current;
rq = this_rq_lock();
+ time_slice_expired(p, rq);
schedstat_inc(task_rq(p), yld_count);
/*
@@ -5208,19 +5209,19 @@ again:
}
double_rq_lock(rq, p_rq);
- if (task_rq(p) != p_rq) {
+ if (unlikely(task_rq(p) != p_rq)) {
double_rq_unlock(rq, p_rq);
goto again;
}
yielded = 1;
- if (p->deadline > rq->rq_deadline)
- p->deadline = rq->rq_deadline;
rq_p = rq->curr;
+ if (p->deadline > rq_p->deadline)
+ p->deadline = rq_p->deadline;
p->time_slice += rq_p->time_slice;
- rq_p->time_slice = 0;
if (p->time_slice > timeslice())
p->time_slice = timeslice();
+ time_slice_expired(rq_p, rq);
if (preempt && rq != p_rq)
resched_task(p_rq->curr);
double_rq_unlock(rq, p_rq);