diff options
author | Nathan O <otternes@cs.unc.edu> | 2020-02-13 12:38:24 -0500 |
---|---|---|
committer | Nathan O <otternes@cs.unc.edu> | 2020-02-13 12:43:29 -0500 |
commit | 96d38276b2dc7f5a5a0bdfd4407f88b6833ab031 (patch) | |
tree | 1449270672ed7fe03eb29b9aee648361e1314931 /litmus/sched_gsn_edf.c | |
parent | 665d44284956094a722b4692ed07df1f692d0232 (diff) |
Fix balancing issue, GEDF plugin
- Fixed a bug where some new balancing code wasn't commented out when
it needed to be. (It wasn't in the version of Linux that the previous
version of LITMUS was based on, so I missed it earlier.)
- The GSN-EDF plugin can now be activated, and runs tasks without
crashing (though I haven't verified that it schedules stuff in the
correct order yet).
- *All remaining plugins probably need to be modified in the same was
as the GSN-EDF plugin*. Specifically, the "prev" argument to the
"<plugin>_schedule(...)" function may be NULL, and the plugin must be
able to handle such a case!
Diffstat (limited to 'litmus/sched_gsn_edf.c')
-rw-r--r-- | litmus/sched_gsn_edf.c | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/litmus/sched_gsn_edf.c b/litmus/sched_gsn_edf.c index 12316b4e0663..38a3aa3a9e47 100644 --- a/litmus/sched_gsn_edf.c +++ b/litmus/sched_gsn_edf.c | |||
@@ -422,9 +422,9 @@ static struct task_struct* gsnedf_schedule(struct task_struct * prev) | |||
422 | raw_spin_lock(&gsnedf_lock); | 422 | raw_spin_lock(&gsnedf_lock); |
423 | 423 | ||
424 | /* sanity checking */ | 424 | /* sanity checking */ |
425 | BUG_ON(entry->scheduled && entry->scheduled != prev); | 425 | BUG_ON(entry->scheduled && prev && (entry->scheduled != prev)); |
426 | BUG_ON(entry->scheduled && !is_realtime(prev)); | 426 | BUG_ON(entry->scheduled && prev && !is_realtime(prev)); |
427 | BUG_ON(is_realtime(prev) && !entry->scheduled); | 427 | BUG_ON(prev && is_realtime(prev) && !entry->scheduled); |
428 | 428 | ||
429 | /* (0) Determine state */ | 429 | /* (0) Determine state */ |
430 | exists = entry->scheduled != NULL; | 430 | exists = entry->scheduled != NULL; |
@@ -439,15 +439,18 @@ static struct task_struct* gsnedf_schedule(struct task_struct * prev) | |||
439 | TRACE_TASK(prev, "invoked gsnedf_schedule.\n"); | 439 | TRACE_TASK(prev, "invoked gsnedf_schedule.\n"); |
440 | #endif | 440 | #endif |
441 | 441 | ||
442 | if (exists) | 442 | if (exists) { |
443 | prev = entry->scheduled; | ||
443 | TRACE_TASK(prev, | 444 | TRACE_TASK(prev, |
444 | "blocks:%d out_of_time:%d np:%d sleep:%d preempt:%d " | 445 | "blocks:%d out_of_time:%d np:%d sleep:%d preempt:%d " |
445 | "state:%d sig:%d\n", | 446 | "state:%d sig:%d\n", |
446 | blocks, out_of_time, np, sleep, preempt, | 447 | blocks, out_of_time, np, sleep, preempt, |
447 | prev->state, signal_pending(prev)); | 448 | prev->state, signal_pending(prev)); |
448 | if (entry->linked && preempt) | 449 | } |
450 | if (entry->linked && preempt) { | ||
449 | TRACE_TASK(prev, "will be preempted by %s/%d\n", | 451 | TRACE_TASK(prev, "will be preempted by %s/%d\n", |
450 | entry->linked->comm, entry->linked->pid); | 452 | entry->linked->comm, entry->linked->pid); |
453 | } | ||
451 | 454 | ||
452 | 455 | ||
453 | /* If a task blocks we have no choice but to reschedule. | 456 | /* If a task blocks we have no choice but to reschedule. |
@@ -481,8 +484,7 @@ static struct task_struct* gsnedf_schedule(struct task_struct * prev) | |||
481 | /* The final scheduling decision. Do we need to switch for some reason? | 484 | /* The final scheduling decision. Do we need to switch for some reason? |
482 | * If linked is different from scheduled, then select linked as next. | 485 | * If linked is different from scheduled, then select linked as next. |
483 | */ | 486 | */ |
484 | if ((!np || blocks) && | 487 | if ((!np || blocks) && (entry->linked != entry->scheduled)) { |
485 | entry->linked != entry->scheduled) { | ||
486 | /* Schedule a linked job? */ | 488 | /* Schedule a linked job? */ |
487 | if (entry->linked) { | 489 | if (entry->linked) { |
488 | entry->linked->rt_param.scheduled_on = entry->cpu; | 490 | entry->linked->rt_param.scheduled_on = entry->cpu; |
@@ -494,12 +496,13 @@ static struct task_struct* gsnedf_schedule(struct task_struct * prev) | |||
494 | entry->scheduled->rt_param.scheduled_on = NO_CPU; | 496 | entry->scheduled->rt_param.scheduled_on = NO_CPU; |
495 | TRACE_TASK(entry->scheduled, "scheduled_on = NO_CPU\n"); | 497 | TRACE_TASK(entry->scheduled, "scheduled_on = NO_CPU\n"); |
496 | } | 498 | } |
497 | } else | 499 | } else { |
498 | /* Only override Linux scheduler if we have a real-time task | 500 | /* Only override Linux scheduler if we have a real-time task |
499 | * scheduled that needs to continue. | 501 | * scheduled that needs to continue. |
500 | */ | 502 | */ |
501 | if (exists) | 503 | if (exists) |
502 | next = prev; | 504 | next = prev; |
505 | } | ||
503 | 506 | ||
504 | sched_state_task_picked(); | 507 | sched_state_task_picked(); |
505 | 508 | ||
@@ -508,13 +511,13 @@ static struct task_struct* gsnedf_schedule(struct task_struct * prev) | |||
508 | #ifdef WANT_ALL_SCHED_EVENTS | 511 | #ifdef WANT_ALL_SCHED_EVENTS |
509 | TRACE("gsnedf_lock released, next=0x%p\n", next); | 512 | TRACE("gsnedf_lock released, next=0x%p\n", next); |
510 | 513 | ||
511 | if (next) | 514 | if (next) { |
512 | TRACE_TASK(next, "scheduled at %llu\n", litmus_clock()); | 515 | TRACE_TASK(next, "scheduled at %llu\n", litmus_clock()); |
513 | else if (exists && !next) | 516 | } else if (exists && !next) { |
514 | TRACE("becomes idle at %llu.\n", litmus_clock()); | 517 | TRACE("becomes idle at %llu.\n", litmus_clock()); |
518 | } | ||
515 | #endif | 519 | #endif |
516 | 520 | ||
517 | |||
518 | return next; | 521 | return next; |
519 | } | 522 | } |
520 | 523 | ||