diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2011-04-20 00:37:50 -0400 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2011-04-20 00:37:50 -0400 |
commit | a91d4578f17b20c20407195583553341c58f3f85 (patch) | |
tree | 5051d1da29990d5adea96cea2647d33ec859d97f | |
parent | 86fca3f0c9f9270b3315696738eca47bd4c6013c (diff) |
Fixed BE server bugs.
-rw-r--r-- | litmus/sched_edf_hsb.c | 80 | ||||
-rw-r--r-- | litmus/servers.c | 26 |
2 files changed, 67 insertions, 39 deletions
diff --git a/litmus/sched_edf_hsb.c b/litmus/sched_edf_hsb.c index adbcc2551280..49cc75d9ea81 100644 --- a/litmus/sched_edf_hsb.c +++ b/litmus/sched_edf_hsb.c | |||
@@ -176,7 +176,7 @@ static struct sched_plugin edf_hsb_plugin __cacheline_aligned_in_smp; | |||
176 | #define task_job_no(task) (tsk_rt(task)->job_params.job_no) | 176 | #define task_job_no(task) (tsk_rt(task)->job_params.job_no) |
177 | #define task_data(task) ((task_data_t*)tsk_rt(task)->plugin_data) | 177 | #define task_data(task) ((task_data_t*)tsk_rt(task)->plugin_data) |
178 | #define task_srt_server(task) ((server_t*)task_data(task)->srt_server) | 178 | #define task_srt_server(task) ((server_t*)task_data(task)->srt_server) |
179 | #define server_slack(s) ((server_t*)s->data) | 179 | #define server_slack(s) ((server_t*)(s)->data) |
180 | #define server_has_slack(s) (server_slack(s)->deadline != 0) | 180 | #define server_has_slack(s) (server_slack(s)->deadline != 0) |
181 | #define local_cpu_entry (&__get_cpu_var(cpu_entries)) | 181 | #define local_cpu_entry (&__get_cpu_var(cpu_entries)) |
182 | #define global_lock (&srt_domain.ready_lock) | 182 | #define global_lock (&srt_domain.ready_lock) |
@@ -332,6 +332,7 @@ static void donate_slack(server_t *donator) | |||
332 | */ | 332 | */ |
333 | static void check_donate_slack(server_t *donator, struct task_struct *was_scheduled) | 333 | static void check_donate_slack(server_t *donator, struct task_struct *was_scheduled) |
334 | { | 334 | { |
335 | server_t *slack = server_slack(donator); | ||
335 | hrt_server_t *hrt_server; | 336 | hrt_server_t *hrt_server; |
336 | int donate = 0; | 337 | int donate = 0; |
337 | 338 | ||
@@ -342,7 +343,6 @@ static void check_donate_slack(server_t *donator, struct task_struct *was_schedu | |||
342 | return; | 343 | return; |
343 | 344 | ||
344 | if (server_has_slack(donator)) { | 345 | if (server_has_slack(donator)) { |
345 | server_t *slack = server_slack(donator); | ||
346 | TRACE_SERVER_SUB(donator, "dead: %d, rel: %d, job: %d already donated", | 346 | TRACE_SERVER_SUB(donator, "dead: %d, rel: %d, job: %d already donated", |
347 | slack->deadline, slack->release, slack->job_no); | 347 | slack->deadline, slack->release, slack->job_no); |
348 | return; | 348 | return; |
@@ -592,6 +592,7 @@ static void requeue_server(server_t *server, lt_t now) | |||
592 | TRACE_SERVER_SUB(server, "P%d now ready at %llu", now); | 592 | TRACE_SERVER_SUB(server, "P%d now ready at %llu", now); |
593 | hrt_server = container_of(server, hrt_server_t, server); | 593 | hrt_server = container_of(server, hrt_server_t, server); |
594 | hrt_server->ready = 1; | 594 | hrt_server->ready = 1; |
595 | remove_slack(server_slack(server)); | ||
595 | hrt_server->no_slack = 0; | 596 | hrt_server->no_slack = 0; |
596 | sched_trace_action(NULL, SERVER_RELEASED_ACTION); | 597 | sched_trace_action(NULL, SERVER_RELEASED_ACTION); |
597 | } else if (server->type == S_BE) { | 598 | } else if (server->type == S_BE) { |
@@ -644,6 +645,7 @@ static noinline void link_server(cpu_entry_t *entry, | |||
644 | BUG_ON(next_server->job_no + 1 < task_job_no(entry->linked)); | 645 | BUG_ON(next_server->job_no + 1 < task_job_no(entry->linked)); |
645 | BUG_ON(lt_after(get_deadline(entry->linked), | 646 | BUG_ON(lt_after(get_deadline(entry->linked), |
646 | next_server->deadline)); | 647 | next_server->deadline)); |
648 | BUG_ON(head_in_list(&task_data(entry->linked)->candidate_list)); | ||
647 | } else if (next_server->type == S_HRT) { | 649 | } else if (next_server->type == S_HRT) { |
648 | /* HRT servers should never, ever migrate */ | 650 | /* HRT servers should never, ever migrate */ |
649 | BUG_ON(entry->cpu != task_cpu(entry->linked)); | 651 | BUG_ON(entry->cpu != task_cpu(entry->linked)); |
@@ -651,10 +653,12 @@ static noinline void link_server(cpu_entry_t *entry, | |||
651 | } else if (next_server->type == S_SLACK) { | 653 | } else if (next_server->type == S_SLACK) { |
652 | /* Should have already been removed from slack list */ | 654 | /* Should have already been removed from slack list */ |
653 | BUG_ON(head_in_list(&task_data(entry->linked)->candidate_list)); | 655 | BUG_ON(head_in_list(&task_data(entry->linked)->candidate_list)); |
656 | BUG_ON(is_be(entry->linked) && is_queued(entry->linked)); | ||
654 | sched_trace_action(entry->linked, SLACK_RUN_ACTION); | 657 | sched_trace_action(entry->linked, SLACK_RUN_ACTION); |
655 | } else { /* BE */ | 658 | } else { /* BE */ |
656 | /* Should have already been removed from ready heap */ | 659 | /* Should have already been removed from ready heap */ |
657 | BUG_ON(bheap_node_in_heap(next_server->hn)); | 660 | BUG_ON(bheap_node_in_heap(next_server->hn)); |
661 | BUG_ON(is_queued(entry->linked)); | ||
658 | sched_trace_action(entry->linked, next_server->id); | 662 | sched_trace_action(entry->linked, next_server->id); |
659 | } | 663 | } |
660 | 664 | ||
@@ -832,7 +836,7 @@ static noinline void unlink(struct task_struct* t) | |||
832 | 836 | ||
833 | if (head_in_list(&task_data(t)->candidate_list)) { | 837 | if (head_in_list(&task_data(t)->candidate_list)) { |
834 | list_del_init(&task_data(t)->candidate_list); | 838 | list_del_init(&task_data(t)->candidate_list); |
835 | } | 839 | } |
836 | 840 | ||
837 | entry = task_sched_entry(t); | 841 | entry = task_sched_entry(t); |
838 | 842 | ||
@@ -860,7 +864,6 @@ static noinline void unlink(struct task_struct* t) | |||
860 | remove(get_rt_domain(entry, t), t); | 864 | remove(get_rt_domain(entry, t), t); |
861 | BUG_ON(is_queued(t)); | 865 | BUG_ON(is_queued(t)); |
862 | } | 866 | } |
863 | |||
864 | } | 867 | } |
865 | } | 868 | } |
866 | 869 | ||
@@ -999,8 +1002,9 @@ static struct task_struct* next_eligible_hrt(hrt_server_t *hrt_server) | |||
999 | slack = lt_subtract(dead, budget); | 1002 | slack = lt_subtract(dead, budget); |
1000 | budget = hrt_server->server.budget; | 1003 | budget = hrt_server->server.budget; |
1001 | 1004 | ||
1002 | TRACE_SERVER_SUB(&hrt_server->server, "dead: %llu, budget: %llu", | 1005 | TRACE_SERVER_SUB(&hrt_server->server, "dead: %llu, budget: %llu" |
1003 | TIME(dead), TIME(budget)); | 1006 | "now: %llu, slack: %llu", |
1007 | TIME(dead), TIME(budget), TIME(now), TIME(slack)); | ||
1004 | 1008 | ||
1005 | if (!head_in_list(&hrt_server->server.release_list) && | 1009 | if (!head_in_list(&hrt_server->server.release_list) && |
1006 | lt_before_eq(dead, now)) { | 1010 | lt_before_eq(dead, now)) { |
@@ -1008,6 +1012,7 @@ static struct task_struct* next_eligible_hrt(hrt_server_t *hrt_server) | |||
1008 | catchup_server(&hrt_server->server, now); | 1012 | catchup_server(&hrt_server->server, now); |
1009 | TRACE_SERVER_SUB(&hrt_server->server, "now ready"); | 1013 | TRACE_SERVER_SUB(&hrt_server->server, "now ready"); |
1010 | hrt_server->ready = 1; | 1014 | hrt_server->ready = 1; |
1015 | remove_slack(server_slack(&hrt_server->server)); | ||
1011 | hrt_server->no_slack = 0; | 1016 | hrt_server->no_slack = 0; |
1012 | 1017 | ||
1013 | slack = lt_subtract(hrt_server->server.deadline, | 1018 | slack = lt_subtract(hrt_server->server.deadline, |
@@ -1017,10 +1022,11 @@ static struct task_struct* next_eligible_hrt(hrt_server_t *hrt_server) | |||
1017 | } | 1022 | } |
1018 | 1023 | ||
1019 | /* If the slack timer is active, this is not necessary */ | 1024 | /* If the slack timer is active, this is not necessary */ |
1020 | if (!hrtimer_active(&hrt_server->slack_timer)) { | 1025 | if (!hrtimer_active(&hrt_server->slack_timer) && hrt_server->ready) { |
1021 | if (lt_before_eq(slack, now) && !hrt_server->no_slack) { | 1026 | if (lt_before_eq(slack, now) && !hrt_server->no_slack) { |
1022 | /* The server missed the shift to no slack */ | 1027 | /* The server missed the shift to no slack */ |
1023 | TRACE_SERVER_SUB(&hrt_server->server, "now no slack"); | 1028 | TRACE_SERVER_SUB(&hrt_server->server, "no slack: %llu", |
1029 | TIME(slack)); | ||
1024 | hrt_server->no_slack = 1; | 1030 | hrt_server->no_slack = 1; |
1025 | sched_trace_action(task, NO_SLACK_ACTION); | 1031 | sched_trace_action(task, NO_SLACK_ACTION); |
1026 | } else { | 1032 | } else { |
@@ -1109,7 +1115,7 @@ static inline server_t* next_be_server(void) | |||
1109 | return (hn) ? hn->value : NULL; | 1115 | return (hn) ? hn->value : NULL; |
1110 | } | 1116 | } |
1111 | 1117 | ||
1112 | static server_t* next_eligible_be_server(void) | 1118 | static noinline server_t* next_eligible_be_server(void) |
1113 | { | 1119 | { |
1114 | server_t *be_server = next_be_server(); | 1120 | server_t *be_server = next_be_server(); |
1115 | lt_t now = litmus_clock(); | 1121 | lt_t now = litmus_clock(); |
@@ -1125,6 +1131,7 @@ static server_t* next_eligible_be_server(void) | |||
1125 | be_server->hn); | 1131 | be_server->hn); |
1126 | 1132 | ||
1127 | be_server = next_be_server(); | 1133 | be_server = next_be_server(); |
1134 | TRACE_SERVER_SUB(be_server, "catching up BE server"); | ||
1128 | sched_trace_action(NULL, SERVER_RELEASED_ACTION); /* Release */ | 1135 | sched_trace_action(NULL, SERVER_RELEASED_ACTION); /* Release */ |
1129 | } | 1136 | } |
1130 | 1137 | ||
@@ -1132,6 +1139,12 @@ static server_t* next_eligible_be_server(void) | |||
1132 | be_server = NULL; | 1139 | be_server = NULL; |
1133 | } | 1140 | } |
1134 | 1141 | ||
1142 | if (be_server) { | ||
1143 | TRACE_SERVER_SUB(be_server, "dead: %llu, rel: %llu, budget: %llu", | ||
1144 | be_server->deadline, be_server->release, | ||
1145 | be_server->budget); | ||
1146 | } | ||
1147 | |||
1135 | return be_server; | 1148 | return be_server; |
1136 | } | 1149 | } |
1137 | 1150 | ||
@@ -1363,8 +1376,8 @@ static void preempt(cpu_entry_t *entry, struct task_struct *next, | |||
1363 | 1376 | ||
1364 | remove_from_ready(next_server, next, entry); | 1377 | remove_from_ready(next_server, next, entry); |
1365 | 1378 | ||
1366 | check_for_slack_preempt(next, next_server, entry, slack_resched); | ||
1367 | linked = entry->linked; | 1379 | linked = entry->linked; |
1380 | check_for_slack_preempt(next, next_server, entry, slack_resched); | ||
1368 | link_to_cpu(entry, next, next_server); | 1381 | link_to_cpu(entry, next, next_server); |
1369 | 1382 | ||
1370 | /* No need for this if only the server was preempted */ | 1383 | /* No need for this if only the server was preempted */ |
@@ -1382,7 +1395,7 @@ static void preempt(cpu_entry_t *entry, struct task_struct *next, | |||
1382 | * 1. task is being run by a slack server on a different CPU | 1395 | * 1. task is being run by a slack server on a different CPU |
1383 | * 2. slack donated by server is running a task on a different CPU | 1396 | * 2. slack donated by server is running a task on a different CPU |
1384 | */ | 1397 | */ |
1385 | static void check_for_slack_preempt(struct task_struct *task, | 1398 | static noinline void check_for_slack_preempt(struct task_struct *task, |
1386 | server_t *server, | 1399 | server_t *server, |
1387 | cpu_entry_t *next_entry, | 1400 | cpu_entry_t *next_entry, |
1388 | int resched) | 1401 | int resched) |
@@ -1397,6 +1410,23 @@ static void check_for_slack_preempt(struct task_struct *task, | |||
1397 | 1410 | ||
1398 | if (entry != next_entry) { | 1411 | if (entry != next_entry) { |
1399 | TRACE_TASK_SUB(task, "was on P%d", entry->cpu); | 1412 | TRACE_TASK_SUB(task, "was on P%d", entry->cpu); |
1413 | BUG_ON(entry->linked_server->type != S_SLACK && | ||
1414 | server->type == S_SLACK && entry->linked_server->type == S_BE); | ||
1415 | |||
1416 | TRACE_SUB("hi"); | ||
1417 | |||
1418 | BUG_ON(entry->linked_server->type != S_SLACK && | ||
1419 | server->type == S_SRT && entry->linked_server->type == S_SRT); | ||
1420 | |||
1421 | TRACE_SUB("hi"); | ||
1422 | |||
1423 | BUG_ON(entry->linked_server->type != S_SLACK && | ||
1424 | server->type == S_SRT); | ||
1425 | |||
1426 | TRACE_SUB("hi"); | ||
1427 | |||
1428 | BUG_ON(entry->linked_server->type == S_BE && server->type == S_BE); | ||
1429 | |||
1400 | BUG_ON(entry->linked_server->type != S_SLACK); | 1430 | BUG_ON(entry->linked_server->type != S_SLACK); |
1401 | 1431 | ||
1402 | unlink(task); | 1432 | unlink(task); |
@@ -1471,15 +1501,6 @@ static void check_for_global_preempt(void) | |||
1471 | TRACE_TASK_SUB(next_task, | 1501 | TRACE_TASK_SUB(next_task, |
1472 | "Already on P%d", | 1502 | "Already on P%d", |
1473 | sched->cpu); | 1503 | sched->cpu); |
1474 | |||
1475 | if (entry->linked) { | ||
1476 | requeue(entry->linked, | ||
1477 | get_rt_domain(entry, | ||
1478 | entry->linked)); | ||
1479 | unlink(entry->linked); | ||
1480 | } | ||
1481 | preempt_if_preemptable(entry->scheduled, | ||
1482 | entry->cpu); | ||
1483 | break; | 1504 | break; |
1484 | } | 1505 | } |
1485 | } | 1506 | } |
@@ -1770,6 +1791,7 @@ static void hrt_server_released(server_t *server) | |||
1770 | 1791 | ||
1771 | hrt_server->no_slack = 0; | 1792 | hrt_server->no_slack = 0; |
1772 | hrt_server->ready = 1; | 1793 | hrt_server->ready = 1; |
1794 | remove_slack(&hrt_server->server); | ||
1773 | 1795 | ||
1774 | check_for_hrt_preempt(entry); | 1796 | check_for_hrt_preempt(entry); |
1775 | 1797 | ||
@@ -1843,6 +1865,9 @@ static int admit_be_server(unsigned long long wcet, | |||
1843 | wcet, period, 1); | 1865 | wcet, period, 1); |
1844 | be_server->type = S_BE; | 1866 | be_server->type = S_BE; |
1845 | server_slack_create(be_server); | 1867 | server_slack_create(be_server); |
1868 | |||
1869 | TRACE_SERVER_SUB(be_server, "admitted BE server"); | ||
1870 | |||
1846 | list_add(&be_server->list, &be_servers); | 1871 | list_add(&be_server->list, &be_servers); |
1847 | out: | 1872 | out: |
1848 | return rv; | 1873 | return rv; |
@@ -1872,6 +1897,8 @@ static void stop_be_servers(void) | |||
1872 | 1897 | ||
1873 | //atomic_set(&servers_running, 0); | 1898 | //atomic_set(&servers_running, 0); |
1874 | 1899 | ||
1900 | TRACE_SUB("stopping BE servers"); | ||
1901 | |||
1875 | list_for_each_safe(pos, safe, &be_servers) { | 1902 | list_for_each_safe(pos, safe, &be_servers) { |
1876 | be_server = list_entry(pos, server_t, list); | 1903 | be_server = list_entry(pos, server_t, list); |
1877 | 1904 | ||
@@ -2143,7 +2170,7 @@ static void edf_hsb_task_exit(struct task_struct *task) | |||
2143 | static struct task_struct* edf_hsb_schedule(struct task_struct *prev) | 2170 | static struct task_struct* edf_hsb_schedule(struct task_struct *prev) |
2144 | { | 2171 | { |
2145 | unsigned long flags; | 2172 | unsigned long flags; |
2146 | int blocks, preempted, sleep, was_slack, np, srt_preempt, donated; | 2173 | int blocks, preempted, sleep, was_slack, np, hrt_preempt, donated; |
2147 | struct task_struct *curr; | 2174 | struct task_struct *curr; |
2148 | cpu_entry_t *entry = local_cpu_entry; | 2175 | cpu_entry_t *entry = local_cpu_entry; |
2149 | 2176 | ||
@@ -2209,16 +2236,17 @@ static struct task_struct* edf_hsb_schedule(struct task_struct *prev) | |||
2209 | entry->scheduled_server = entry->linked_server; | 2236 | entry->scheduled_server = entry->linked_server; |
2210 | sched_state_task_picked(); | 2237 | sched_state_task_picked(); |
2211 | 2238 | ||
2212 | /* An SRT was preempted by an HRT task. Due to the linking logic, | 2239 | /* An non-HRT was preempted by an HRT task. Because of the way linking |
2213 | * the SRT cannot check for a preemption until it is descheduled. | 2240 | * works, it cannot link itself to anything else until the non-migratory |
2241 | * HRT task is scheduled. | ||
2214 | */ | 2242 | */ |
2215 | srt_preempt = preempted && entry->linked && curr && | 2243 | hrt_preempt = preempted && entry->linked && curr && |
2216 | is_hrt(entry->linked) && !is_hrt(curr); | 2244 | is_hrt(entry->linked) && !is_hrt(curr); |
2217 | /* A server just donated slack */ | 2245 | /* A server just donated slack */ |
2218 | donated = entry->linked && entry->linked_server->type != S_SLACK && | 2246 | donated = entry->linked && entry->linked_server->type != S_SLACK && |
2219 | head_in_list(&server_slack(entry->linked_server)->list); | 2247 | head_in_list(&server_slack(entry->linked_server)->list); |
2220 | 2248 | ||
2221 | if (srt_preempt || donated) | 2249 | if (hrt_preempt || donated) |
2222 | check_for_global_preempt(); | 2250 | check_for_global_preempt(); |
2223 | 2251 | ||
2224 | if (entry->scheduled) | 2252 | if (entry->scheduled) |
@@ -2273,7 +2301,7 @@ static void edf_hsb_task_new(struct task_struct *task, int on_rq, int running) | |||
2273 | * This tends to happen when the first tasks enter the system. | 2301 | * This tends to happen when the first tasks enter the system. |
2274 | */ | 2302 | */ |
2275 | if (running) { | 2303 | if (running) { |
2276 | BUG_ON(entry->scheduled); | 2304 | //BUG_ON(entry->scheduled); |
2277 | 2305 | ||
2278 | #ifdef CONFIG_RELEASE_MASTER | 2306 | #ifdef CONFIG_RELEASE_MASTER |
2279 | if (entry->cpu != edf_hsb_release_master) { | 2307 | if (entry->cpu != edf_hsb_release_master) { |
diff --git a/litmus/servers.c b/litmus/servers.c index e0cc79e7a74b..5aebbe5ec1c1 100644 --- a/litmus/servers.c +++ b/litmus/servers.c | |||
@@ -486,19 +486,19 @@ static int server_proc_write(struct file *file, const char __user *input, | |||
486 | "server config: %s\n", pos); | 486 | "server config: %s\n", pos); |
487 | goto loop_end; | 487 | goto loop_end; |
488 | } | 488 | } |
489 | space_check = pos + chars_seen; | 489 | /* space_check = pos + chars_seen; */ |
490 | if (space_check != newline) { | 490 | /* if (space_check != newline) { */ |
491 | /* If the newline was not right after the numbers | 491 | /* /\* If the newline was not right after the numbers */ |
492 | * converted, ensure extra characters are just space | 492 | /* * converted, ensure extra characters are just space */ |
493 | */ | 493 | /* *\/ */ |
494 | for (; *space_check; space_check++) { | 494 | /* for (; *space_check; space_check++) { */ |
495 | if (!isspace(*space_check)) { | 495 | /* if (!isspace(*space_check)) { */ |
496 | printk(KERN_WARNING "Extra characters " | 496 | /* printk(KERN_WARNING "Extra characters " */ |
497 | "in line: %s\n", pos); | 497 | /* "in line: %s\n", pos); */ |
498 | goto loop_end; | 498 | /* goto loop_end; */ |
499 | } | 499 | /* } */ |
500 | } | 500 | /* } */ |
501 | } | 501 | /* } */ |
502 | 502 | ||
503 | ret = server_param_check(wcet, period, cpu); | 503 | ret = server_param_check(wcet, period, cpu); |
504 | if (ret) goto loop_end; | 504 | if (ret) goto loop_end; |