diff options
author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2010-05-28 10:30:29 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-29 17:21:31 -0400 |
commit | a084c01569bcfe13fd880a0b1e3a9026629a89da (patch) | |
tree | c52640fb3f007637a1914ec6f0b6b92051be73c3 | |
parent | e68debebdc2983600063cd6b04c6a51c4b7ddcc1 (diff) |
Better explanation of jump-to-CFS optimization removal
GSN-EDF and friends rely on being called even if there is currently
no runnable real-time task on the runqueue for (at least) two reasons:
1) To initiate migrations. LITMUS^RT pull tasks for migrations; this requires
plugins to be called even if no task is currently present.
2) To maintain invariants when jobs block.
-rw-r--r-- | kernel/sched.c | 17 | ||||
-rw-r--r-- | litmus/sched_litmus.c | 4 |
2 files changed, 14 insertions, 7 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index 9ad41979c0b2..1701eaebb79c 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -487,6 +487,7 @@ struct rt_rq { | |||
487 | 487 | ||
488 | /* Litmus related fields in a runqueue */ | 488 | /* Litmus related fields in a runqueue */ |
489 | struct litmus_rq { | 489 | struct litmus_rq { |
490 | unsigned long nr_running; | ||
490 | struct task_struct *prev; | 491 | struct task_struct *prev; |
491 | }; | 492 | }; |
492 | 493 | ||
@@ -5420,13 +5421,15 @@ pick_next_task(struct rq *rq) | |||
5420 | /* | 5421 | /* |
5421 | * Optimization: we know that if all tasks are in | 5422 | * Optimization: we know that if all tasks are in |
5422 | * the fair class we can call that function directly: | 5423 | * the fair class we can call that function directly: |
5423 | */ | 5424 | |
5424 | /* | 5425 | * NOT IN LITMUS^RT! |
5425 | * LITMUS_TODO: can we move processes out of fair class? | 5426 | |
5426 | * i.e., create a litmus_rq | 5427 | * This breaks many assumptions in the plugins. |
5427 | */ | 5428 | * Do not uncomment without thinking long and hard |
5428 | /* Don't do this for LITMUS | 5429 | * about how this affects global plugins such as GSN-EDF. |
5429 | if (likely(rq->nr_running == rq->cfs.nr_running)) { | 5430 | |
5431 | if (rq->nr_running == rq->cfs.nr_running) { | ||
5432 | TRACE("taking shortcut in pick_next_task()\n"); | ||
5430 | p = fair_sched_class.pick_next_task(rq); | 5433 | p = fair_sched_class.pick_next_task(rq); |
5431 | if (likely(p)) | 5434 | if (likely(p)) |
5432 | return p; | 5435 | return p; |
diff --git a/litmus/sched_litmus.c b/litmus/sched_litmus.c index 9906e059879a..64ad5db07795 100644 --- a/litmus/sched_litmus.c +++ b/litmus/sched_litmus.c | |||
@@ -156,6 +156,8 @@ static void enqueue_task_litmus(struct rq *rq, struct task_struct *p, | |||
156 | sched_trace_task_resume(p); | 156 | sched_trace_task_resume(p); |
157 | tsk_rt(p)->present = 1; | 157 | tsk_rt(p)->present = 1; |
158 | litmus->task_wake_up(p); | 158 | litmus->task_wake_up(p); |
159 | |||
160 | rq->litmus.nr_running++; | ||
159 | } else | 161 | } else |
160 | TRACE_TASK(p, "ignoring an enqueue, not a wake up.\n"); | 162 | TRACE_TASK(p, "ignoring an enqueue, not a wake up.\n"); |
161 | } | 163 | } |
@@ -166,6 +168,8 @@ static void dequeue_task_litmus(struct rq *rq, struct task_struct *p, int sleep) | |||
166 | litmus->task_block(p); | 168 | litmus->task_block(p); |
167 | tsk_rt(p)->present = 0; | 169 | tsk_rt(p)->present = 0; |
168 | sched_trace_task_block(p); | 170 | sched_trace_task_block(p); |
171 | |||
172 | rq->litmus.nr_running--; | ||
169 | } else | 173 | } else |
170 | TRACE_TASK(p, "ignoring a dequeue, not going to sleep.\n"); | 174 | TRACE_TASK(p, "ignoring a dequeue, not going to sleep.\n"); |
171 | } | 175 | } |