aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched_fair.c
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2007-10-15 11:00:05 -0400
committerIngo Molnar <mingo@elte.hu>2007-10-15 11:00:05 -0400
commitaeb73b040399f94698b4f64dd058cae39187e18d (patch)
tree72ffe7e64b414df2157d19073b92406cbf436535 /kernel/sched_fair.c
parent2e09bf556fbe1a4cd8d837a3e6607de55f7cf4fd (diff)
sched: clean up new task placement
clean up new task placement. Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Mike Galbraith <efault@gmx.de>
Diffstat (limited to 'kernel/sched_fair.c')
-rw-r--r--kernel/sched_fair.c57
1 files changed, 42 insertions, 15 deletions
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
index a60b1dac598a..cc447fbff51c 100644
--- a/kernel/sched_fair.c
+++ b/kernel/sched_fair.c
@@ -199,6 +199,21 @@ static struct sched_entity *__pick_next_entity(struct cfs_rq *cfs_rq)
199 return rb_entry(first_fair(cfs_rq), struct sched_entity, run_node); 199 return rb_entry(first_fair(cfs_rq), struct sched_entity, run_node);
200} 200}
201 201
202static inline struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq)
203{
204 struct rb_node **link = &cfs_rq->tasks_timeline.rb_node;
205 struct sched_entity *se = NULL;
206 struct rb_node *parent;
207
208 while (*link) {
209 parent = *link;
210 se = rb_entry(parent, struct sched_entity, run_node);
211 link = &parent->rb_right;
212 }
213
214 return se;
215}
216
202/************************************************************** 217/**************************************************************
203 * Scheduling class statistics methods: 218 * Scheduling class statistics methods:
204 */ 219 */
@@ -530,6 +545,31 @@ static void enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se)
530} 545}
531 546
532static void 547static void
548place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
549{
550 struct sched_entity *last = __pick_last_entity(cfs_rq);
551 u64 min_runtime, latency;
552
553 min_runtime = cfs_rq->min_vruntime;
554 if (last) {
555 min_runtime += last->vruntime;
556 min_runtime >>= 1;
557 if (initial && sched_feat(START_DEBIT))
558 min_runtime += sysctl_sched_latency/2;
559 }
560
561 if (!initial && sched_feat(NEW_FAIR_SLEEPERS)) {
562 latency = sysctl_sched_latency;
563 if (min_runtime > latency)
564 min_runtime -= latency;
565 else
566 min_runtime = 0;
567 }
568
569 se->vruntime = max(se->vruntime, min_runtime);
570}
571
572static void
533enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int wakeup) 573enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int wakeup)
534{ 574{
535 /* 575 /*
@@ -538,19 +578,7 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int wakeup)
538 update_curr(cfs_rq); 578 update_curr(cfs_rq);
539 579
540 if (wakeup) { 580 if (wakeup) {
541 u64 min_runtime, latency; 581 place_entity(cfs_rq, se, 0);
542
543 min_runtime = cfs_rq->min_vruntime;
544 min_runtime += sysctl_sched_latency/2;
545
546 if (sched_feat(NEW_FAIR_SLEEPERS)) {
547 latency = calc_weighted(sysctl_sched_latency, se);
548 if (min_runtime > latency)
549 min_runtime -= latency;
550 }
551
552 se->vruntime = max(se->vruntime, min_runtime);
553
554 enqueue_sleeper(cfs_rq, se); 582 enqueue_sleeper(cfs_rq, se);
555 } 583 }
556 584
@@ -1033,8 +1061,7 @@ static void task_new_fair(struct rq *rq, struct task_struct *p)
1033 sched_info_queued(p); 1061 sched_info_queued(p);
1034 1062
1035 update_curr(cfs_rq); 1063 update_curr(cfs_rq);
1036 se->vruntime = cfs_rq->min_vruntime; 1064 place_entity(cfs_rq, se, 1);
1037 update_stats_enqueue(cfs_rq, se);
1038 1065
1039 /* 1066 /*
1040 * The first wait is dominated by the child-runs-first logic, 1067 * The first wait is dominated by the child-runs-first logic,