diff options
author | Jeremy Erickson <jerickso@cs.unc.edu> | 2011-01-28 14:34:58 -0500 |
---|---|---|
committer | Jeremy Erickson <jerickso@cs.unc.edu> | 2011-01-28 14:34:58 -0500 |
commit | 9fe6c14c2ff307ea406801cddbd5ad083c684d87 (patch) | |
tree | cbfb71ff4420c308820f7ae72cca147f4f899aa5 | |
parent | 43fb6b9afdf23c19ae5f2d35303da1fe71876497 (diff) |
Fix double requeueing problems
-rw-r--r-- | litmus/sched_mc.c | 49 |
1 files changed, 29 insertions, 20 deletions
diff --git a/litmus/sched_mc.c b/litmus/sched_mc.c index 0f11683cdd9f..9fc7abaeaed4 100644 --- a/litmus/sched_mc.c +++ b/litmus/sched_mc.c | |||
@@ -346,9 +346,13 @@ static void update_ghost_time(struct task_struct *p) | |||
346 | TRACE_TASK(p, "WARNING: negative time delta.\n"); | 346 | TRACE_TASK(p, "WARNING: negative time delta.\n"); |
347 | } | 347 | } |
348 | if (p->rt_param.job_params.ghost_budget <= delta) { | 348 | if (p->rt_param.job_params.ghost_budget <= delta) { |
349 | TRACE_TASK(p, "Ghost job ended in update_ghost_time\n"); | 349 | /*Currently will just set ghost budget to zero since |
350 | * task has already been queued. Could probably do | ||
351 | * more efficiently with significant reworking. | ||
352 | */ | ||
353 | TRACE_TASK(p, "Ghost job could have ended\n"); | ||
350 | p->rt_param.job_params.ghost_budget = 0; | 354 | p->rt_param.job_params.ghost_budget = 0; |
351 | job_completion(p, 0); | 355 | p->se.exec_start = clock; |
352 | } | 356 | } |
353 | else{ | 357 | else{ |
354 | TRACE_TASK(p, "Ghost jub updated, but didn't finish\n"); | 358 | TRACE_TASK(p, "Ghost jub updated, but didn't finish\n"); |
@@ -370,8 +374,16 @@ static void cancel_watchdog_timer(struct watchdog_timer* wt) | |||
370 | ret = hrtimer_try_to_cancel(&wt->timer); | 374 | ret = hrtimer_try_to_cancel(&wt->timer); |
371 | /*Should never be inactive.*/ | 375 | /*Should never be inactive.*/ |
372 | BUG_ON(ret == 0); | 376 | BUG_ON(ret == 0); |
373 | /*Should never be running concurrently. */ | 377 | /*Running concurrently is an unusual situation - log it. */ |
374 | BUG_ON(ret == -1); | 378 | /*TODO: is there a way to prevent this? This probably means |
379 | * the timer task is waiting to acquire the lock while the | ||
380 | * cancellation attempt is happening. | ||
381 | * | ||
382 | * And are we even in a correct state when this happens? | ||
383 | */ | ||
384 | if (ret == -1) | ||
385 | TRACE_TASK(wt->task, "Timer cancellation " | ||
386 | "attempted while task completing\n"); | ||
375 | 387 | ||
376 | wt->task = NULL; | 388 | wt->task = NULL; |
377 | } | 389 | } |
@@ -543,21 +555,17 @@ static noinline void unlink(struct task_struct* t) | |||
543 | if (t->rt_param.job_params.ghost_budget > 0){ | 555 | if (t->rt_param.job_params.ghost_budget > 0){ |
544 | /* Job isn't finished, so do accounting. */ | 556 | /* Job isn't finished, so do accounting. */ |
545 | update_ghost_time(t); | 557 | update_ghost_time(t); |
546 | /* Need to check again since accounting might | 558 | /* Just remove from CPU, even in the rare case |
547 | * change value. | 559 | * of zero time left - it will be scheduled |
560 | * with an immediate timer fire. | ||
548 | */ | 561 | */ |
549 | if (t->rt_param.job_params.ghost_budget > 0) { | 562 | entry->ghost_tasks[ |
550 | /* Still have budget, so just remove | 563 | t->rt_param.task_params.crit] |
551 | * from CPU | 564 | = NULL; |
552 | */ | 565 | /*TODO: maybe make more efficient by |
553 | entry->ghost_tasks[ | 566 | * only updating on C/D completion? |
554 | t->rt_param.task_params.crit] | 567 | */ |
555 | = NULL; | 568 | update_cpu_position(entry); |
556 | /*TODO: maybe make more efficient by | ||
557 | * only updating on C/D completion? | ||
558 | */ | ||
559 | update_cpu_position(entry); | ||
560 | } | ||
561 | } | 569 | } |
562 | else{ | 570 | else{ |
563 | /* Job finished, so just remove */ | 571 | /* Job finished, so just remove */ |
@@ -740,7 +748,6 @@ static void mc_release_jobs(rt_domain_t* rt, struct bheap* tasks) | |||
740 | static noinline void job_completion(struct task_struct *t, int forced) | 748 | static noinline void job_completion(struct task_struct *t, int forced) |
741 | { | 749 | { |
742 | cpu_entry_t *cpu; | 750 | cpu_entry_t *cpu; |
743 | int already_unlinked = 0; | ||
744 | BUG_ON(!t); | 751 | BUG_ON(!t); |
745 | 752 | ||
746 | sched_trace_task_completion(t, forced); | 753 | sched_trace_task_completion(t, forced); |
@@ -1135,7 +1142,9 @@ static void mc_task_wake_up(struct task_struct *task) | |||
1135 | } | 1142 | } |
1136 | } | 1143 | } |
1137 | } | 1144 | } |
1138 | mc_job_arrival(task); | 1145 | /*Delay job arrival if we still have an active ghost job*/ |
1146 | if (!is_ghost(task)) | ||
1147 | mc_job_arrival(task); | ||
1139 | raw_spin_unlock_irqrestore(&global_lock, flags); | 1148 | raw_spin_unlock_irqrestore(&global_lock, flags); |
1140 | } | 1149 | } |
1141 | 1150 | ||