aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--litmus/sched_edf_hsb.c80
-rw-r--r--litmus/servers.c26
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 */
333static void check_donate_slack(server_t *donator, struct task_struct *was_scheduled) 333static 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
1112static server_t* next_eligible_be_server(void) 1118static 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 */
1385static void check_for_slack_preempt(struct task_struct *task, 1398static 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)
2143static struct task_struct* edf_hsb_schedule(struct task_struct *prev) 2170static 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;