aboutsummaryrefslogtreecommitdiffstats
path: root/litmus/sched_edf_hsb.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2011-04-04 03:58:25 -0400
committerJonathan Herman <hermanjl@cs.unc.edu>2011-04-04 03:58:25 -0400
commit010daf8f84dc0bb196c0d2f3f8fb8255e6d19b8b (patch)
treeb0cee758b3bf4e0b13fc9d1a2cfb6996508ed39d /litmus/sched_edf_hsb.c
parent080b5d97e8407994a1c697a1b5929ce3209db03c (diff)
slack stealing
Diffstat (limited to 'litmus/sched_edf_hsb.c')
-rw-r--r--litmus/sched_edf_hsb.c685
1 files changed, 525 insertions, 160 deletions
diff --git a/litmus/sched_edf_hsb.c b/litmus/sched_edf_hsb.c
index 12abe3def2d3..4b2c58ec6b75 100644
--- a/litmus/sched_edf_hsb.c
+++ b/litmus/sched_edf_hsb.c
@@ -16,6 +16,10 @@
16 * admit_[hrt|be]_server 16 * admit_[hrt|be]_server
17 * 17 *
18 * TODO BE SERVER TASK PREEMPTGION A;SDIFHSAKEUHFLKH 18 * TODO BE SERVER TASK PREEMPTGION A;SDIFHSAKEUHFLKH
19 * TODO BE server heap needed?
20 * TODO move slack completion into release
21 * TODO fix concurrent arms
22 * TODO slack and BE servers
19 * 23 *
20 */ 24 */
21#include <linux/module.h> 25#include <linux/module.h>
@@ -34,7 +38,6 @@
34#include <litmus/edf_common.h> 38#include <litmus/edf_common.h>
35#include <litmus/sched_trace.h> 39#include <litmus/sched_trace.h>
36#include <litmus/servers.h> 40#include <litmus/servers.h>
37
38#define DEBUG_EDF_HSB 41#define DEBUG_EDF_HSB
39 42
40/* DOES NOT WORK */ 43/* DOES NOT WORK */
@@ -43,6 +46,7 @@
43#define BE_PROC_NAME "be_servers" 46#define BE_PROC_NAME "be_servers"
44#define HRT_PROC_NAME "hrt_servers" 47#define HRT_PROC_NAME "hrt_servers"
45#define BE_SERVER_BASE 100 48#define BE_SERVER_BASE 100
49#define SLACK_MIN NSEC_PER_MSEC
46 50
47#define TIME(x) \ 51#define TIME(x) \
48 ({lt_t y = x; \ 52 ({lt_t y = x; \
@@ -67,11 +71,21 @@ atomic_t servers_running = ATOMIC_INIT(0);
67#define TRACE_TASK_SUB(t, fmt, args...) \ 71#define TRACE_TASK_SUB(t, fmt, args...) \
68 TRACE_SUB("(%s/%d:%d) " fmt, (t)->comm, (t)->pid, \ 72 TRACE_SUB("(%s/%d:%d) " fmt, (t)->comm, (t)->pid, \
69 (t)->rt_param.job_params.job_no, ##args) 73 (t)->rt_param.job_params.job_no, ##args)
74#define TRACE_SERVER_SUB(s, fmt, args...) \
75 TRACE_SUB(SERVER_FMT " " fmt, SERVER_ARGS(s), ##args)
70#else 76#else
71#define TRACE_SUB(fmt, args...) 77#define TRACE_SUB(fmt, args...)
72#define TRACE_TASK_SUB(t, fmt, args...) 78#define TRACE_TASK_SUB(t, fmt, args...)
79#define TRACE_SERVER_SUB(s, fmt, args...)
73#endif 80#endif
74 81
82typedef enum {
83 S_HRT,
84 S_SRT,
85 S_BE,
86 S_SLACK
87} server_type_t;
88
75typedef struct { 89typedef struct {
76 server_t server; 90 server_t server;
77 rt_domain_t hrt_domain; /* EDF for HRT tasks assigned here */ 91 rt_domain_t hrt_domain; /* EDF for HRT tasks assigned here */
@@ -108,6 +122,9 @@ static server_domain_t server_domain; /* Useful tools for server scheduling */
108static struct list_head be_servers; /* All BE servers */ 122static struct list_head be_servers; /* All BE servers */
109static struct bheap be_ready_servers; /* Runnable BE servers */ 123static struct bheap be_ready_servers; /* Runnable BE servers */
110 124
125static struct list_head slack_queue;
126static struct list_head slack_candidates;
127
111static int release_master; /* CPU which will release tasks and global servers */ 128static int release_master; /* CPU which will release tasks and global servers */
112 129
113static struct proc_dir_entry *edf_hsb_proc_dir = NULL; 130static struct proc_dir_entry *edf_hsb_proc_dir = NULL;
@@ -117,9 +134,194 @@ static struct sched_plugin edf_hsb_plugin __cacheline_aligned_in_smp;
117#define task_sched_entry(task) (&per_cpu(cpu_entries, task_cpu(task))) 134#define task_sched_entry(task) (&per_cpu(cpu_entries, task_cpu(task)))
118#define task_linked_entry(task) (&per_cpu(cpu_entries, task->rt_param.linked_on)) 135#define task_linked_entry(task) (&per_cpu(cpu_entries, task->rt_param.linked_on))
119#define task_job_no(task) (tsk_rt(task)->job_params.job_no) 136#define task_job_no(task) (tsk_rt(task)->job_params.job_no)
137#define task_srt_server(task) ((server_t*)tsk_rt(task)->plugin_data)
138#define task_slack_server(task) ((server_t*)tsk_rt(task)->slack_server)
120#define global_lock (&srt_domain.ready_lock) 139#define global_lock (&srt_domain.ready_lock)
121#define is_active_plugin (litmus == &edf_hsb_plugin) 140#define is_active_plugin (litmus == &edf_hsb_plugin)
122 141
142static inline int head_in_list(struct list_head *list)
143{
144 if ((list->next == list->prev && list->prev == list) ||
145 (list->next == LIST_POISON1 && list->prev == LIST_POISON2))
146 return 0;
147 else
148 return 1;
149}
150
151/* In the next methods check to see if have donated. If so, do what?
152 * Server_stop. in check for hrt, need to make sure a check for global is
153 * called. in the other one, just need to make sure we unlink and crap and
154 * then call for it again.
155 * What happens if an srt is released that is scheduled?
156 * Then the effective deadline will mark it.
157 */
158static server_t* next_eligible_slack(void)
159{
160 server_t *next_slack = NULL, *donator;
161 lt_t now = litmus_clock();
162
163 while (!list_empty(&slack_queue)) {
164 next_slack = list_entry(slack_queue.next, server_t, list);
165
166 if (lt_after(next_slack->deadline, now) &&
167 next_slack->budget > SLACK_MIN) {
168 break;
169 } else {
170 /* Slack has expired or has too little time */
171 TRACE_SUB("slack " SERVER_FMT " has expired",
172 SERVER_ARGS(next_slack));
173 sched_trace_action(NULL, 7);
174
175 list_del(&next_slack->list);
176 donator = (server_t*)next_slack->data;
177 donator->data = NULL;
178 server_destroy(next_slack);
179 kfree(next_slack);
180
181 next_slack = NULL;
182 }
183 }
184
185 if (next_slack)
186 TRACE_SERVER_SUB(next_slack, "found eligible slack, "
187 "now: %llu, dead: %llu", now,
188 next_slack->deadline);
189 else
190 TRACE_SUB("no eligible slack");
191
192 return next_slack;
193}
194
195static void add_slack(server_t *slack)
196{
197 struct list_head *pos;
198 server_t *queued;
199 TRACE_SERVER_SUB(slack, "adding");
200
201 BUG_ON(head_in_list(&slack->list));
202
203 list_for_each_prev(pos, &slack_queue) {
204 queued = list_entry(pos, server_t, list);
205 if (lt_before_eq(queued->deadline, slack->deadline)) {
206 __list_add(&slack->list, pos, pos->next);
207 return;
208 }
209 }
210 list_add(&slack->list, &slack_queue);
211}
212
213static void add_slack_candidate(struct task_struct *task)
214{
215 struct list_head *pos;
216 struct task_struct *queued;
217
218 tsk_rt(task)->slack_candidate = 1;
219 INIT_LIST_HEAD(&tsk_rt(task)->slack_list);
220
221 list_for_each_prev(pos, &slack_candidates) {
222 queued = list_entry(pos, struct task_struct,
223 rt_param.slack_list);
224 if (lt_before_eq(get_deadline(queued), get_deadline(task))) {
225 TRACE_TASK_SUB(task, "adding after %d", queued->pid);
226 __list_add(&tsk_rt(task)->slack_list,
227 pos, pos->next);
228 return;
229 }
230 }
231 TRACE_TASK_SUB(task, "adding to end of list");
232 list_add(&tsk_rt(task)->slack_list, &slack_candidates);
233}
234
235static struct task_struct* next_eligible_hrt(hrt_server_t*);
236
237static void donate_slack(server_t *donator, struct task_struct *was_scheduled)
238{
239 server_t *slack;
240 hrt_server_t *hrt_server;
241 int donate = 0;
242
243 if (donator->budget < SLACK_MIN) {
244 TRACE_SERVER_SUB(donator, "cannot donate slack");
245 return;
246 }
247
248 if (donator->type == S_SRT &&
249 donator->job_no <= task_job_no(was_scheduled)) {
250 donate = 1;
251 } else if (donator->type == S_HRT &&
252 lt_before_eq(litmus_clock(), get_deadline(was_scheduled))) {
253 hrt_server = container_of(donator, hrt_server_t, server);
254 if (!next_eligible_hrt(hrt_server)) {
255 donate = 1;
256 }
257 } else if (donator-> type == S_BE && !__jobs_pending(&be_domain)) {
258 donate = 1;
259 }
260
261 if (!donate) {
262 TRACE_SERVER_SUB(donator, "doesn't want to donate slack");
263 return;
264 }
265
266 TRACE_SERVER_SUB(donator, "donated %llu slack", TIME(donator->budget));
267 sched_trace_action(was_scheduled, 9);
268 slack = kmalloc(sizeof(server_t), GFP_ATOMIC);
269 server_init(slack, donator->id, donator->budget,
270 donator->period, 0);
271 slack->type = S_SLACK;
272 server_release_at(slack, donator->release);
273 slack->data = donator;
274 donator->data = slack;
275
276 add_slack(slack);
277}
278
279static void reclaim_slack(server_t *donator)
280{
281 TRACE_SERVER_SUB(donator, "wants to reclaim slack");
282}
283
284static struct task_struct* pick_next_slack(server_t *slack, cpu_entry_t *entry)
285{
286 struct task_struct *rv = NULL;
287 if (!slack)
288 goto out;
289 if (!list_empty(&slack_candidates)) {
290 rv = list_entry(slack_candidates.next, struct task_struct,
291 rt_param.slack_list);
292 TRACE_TASK_SUB(rv, "is next slack");
293 } else if (entry && entry->linked &&
294 entry->linked_server->type == S_SLACK) {
295 rv = entry->linked;
296 }
297 out:
298 return rv;
299}
300
301static void take_next_slack(struct task_struct *task)
302{
303 if (tsk_rt(task)->slack_candidate) {
304 TRACE_TASK_SUB(task, "deleting slack");
305 list_del(&tsk_rt(task)->slack_list);
306 tsk_rt(task)->slack_candidate = 0;
307 } else {
308 TRACE_TASK_SUB(task, "can't delete slack");
309 }
310}
311
312static void check_slack_candidate(struct task_struct *task)
313{
314 TRACE_TASK_SUB(task, "checking");
315 if (is_srt(task) && task_srt_server(task)->job_no >=
316 task_job_no(task) && lt_after(get_release(task), litmus_clock()) &&
317 get_rt_flags(task) != RT_F_SLEEP &&
318 !tsk_rt(task)->slack_candidate)
319{
320 add_slack_candidate(task);
321 sched_trace_action(task, 8);
322 }
323}
324
123/* 325/*
124 * FIFO for BE tasks. 326 * FIFO for BE tasks.
125 */ 327 */
@@ -334,37 +536,38 @@ static inline void slack_timer_cancel(hrt_server_t *hrt_server)
334 * tasks as this method cannot determine which BE server to use. 536 * tasks as this method cannot determine which BE server to use.
335 */ 537 */
336static noinline void link_server(cpu_entry_t *entry, 538static noinline void link_server(cpu_entry_t *entry,
337 server_t *be_server) 539 server_t *next_server)
338{ 540{
339 server_t *srt_server; 541 BUG_ON(!next_server);
340 542
341 if (is_srt(entry->linked)) { 543 if (next_server->type == S_SRT) {
342 srt_server = tsk_rt(entry->linked)->plugin_data;
343 TRACE_TASK_SUB(entry->linked, "resuming SRT server," 544 TRACE_TASK_SUB(entry->linked, "resuming SRT server,"
344 "budget*: %llu, exec_time: %llu, deadline: %llu," 545 "budget*: %llu, exec_time: %llu, deadline: %llu,"
345 "job_no: %d", 546 "job_no: %d",
346 srt_server->budget, get_exec_time(entry->linked), 547 next_server->budget, get_exec_time(entry->linked),
347 get_deadline(entry->linked), srt_server->job_no); 548 get_deadline(entry->linked), next_server->job_no);
348 BUG_ON(lt_after(srt_server->budget, 549 BUG_ON(lt_after(next_server->budget,
349 get_exec_cost(entry->linked))); 550 get_exec_cost(entry->linked)));
350 551
351 BUG_ON(srt_server->job_no < task_job_no(entry->linked)); 552 BUG_ON(next_server->job_no < task_job_no(entry->linked));
352 BUG_ON(lt_after(get_deadline(entry->linked), 553 BUG_ON(lt_after(get_deadline(entry->linked),
353 srt_server->deadline)); 554 next_server->deadline));
354
355 entry->linked_server = srt_server;
356 } else if (is_hrt(entry->linked)) { 555 } else if (is_hrt(entry->linked)) {
357 /* HRT servers should never, ever migrate */ 556 /* HRT servers should never, ever migrate */
358 BUG_ON(entry->cpu != task_cpu(entry->linked)); 557 BUG_ON(entry->cpu != task_cpu(entry->linked));
359 slack_timer_cancel(&entry->hrt_server); 558 slack_timer_cancel(&entry->hrt_server);
360 entry->linked_server = &entry->hrt_server.server; 559 } else if (next_server->type == S_SLACK) {
560 /* Should have already been removed */
561 BUG_ON(tsk_rt(entry->linked)->slack_candidate);
562 TRACE_SERVER_SUB(next_server, "linking slack server");
563 sched_trace_action(entry->linked, 5);
564 tsk_rt(entry->linked)->slack_server = next_server;
361 } else { /* BE */ 565 } else { /* BE */
362 BUG_ON(!be_server); 566 BUG_ON(bheap_node_in_heap(next_server->hn));
363 BUG_ON(bheap_node_in_heap(be_server->hn)); 567 sched_trace_action(entry->linked, 200 + next_server->id);
364 entry->linked_server = be_server;
365 sched_trace_action(entry->linked, 200 + be_server->id);
366 } 568 }
367 569
570 entry->linked_server = next_server;
368 server_run(entry->linked_server, entry->linked, &server_domain); 571 server_run(entry->linked_server, entry->linked, &server_domain);
369} 572}
370 573
@@ -374,7 +577,7 @@ static noinline void link_server(cpu_entry_t *entry,
374 * This must be called BEFORE a task is unlinked. 577 * This must be called BEFORE a task is unlinked.
375 */ 578 */
376static noinline void unlink_server(cpu_entry_t *entry, 579static noinline void unlink_server(cpu_entry_t *entry,
377 server_t *be_server) 580 server_t *next_server)
378{ 581{
379 lt_t now; 582 lt_t now;
380 int added; 583 int added;
@@ -402,8 +605,21 @@ static noinline void unlink_server(cpu_entry_t *entry,
402 605
403 } 606 }
404 607
608 if (entry->linked_server->type == S_SLACK) {
609 tsk_rt(entry->linked)->slack_server = NULL;
610 }
611
612 /* Requeue SRT servers, they will be garbage collected later */
613 if (entry->linked_server->type == S_SLACK &&
614 next_server != entry->linked_server &&
615 next_server) {
616 add_slack(entry->linked_server);
617 sched_trace_action(entry->linked, 6);
618 check_slack_candidate(entry->linked);
619 }
620
405 /* Requeue eligible BE servers if they are not about to run again */ 621 /* Requeue eligible BE servers if they are not about to run again */
406 if (is_be(entry->linked) && entry->linked_server != be_server) { 622 if (is_be(entry->linked) && entry->linked_server != next_server) {
407 if (lt_before(entry->linked_server->release, now)) { 623 if (lt_before(entry->linked_server->release, now)) {
408 TRACE_SUB("inserting %d", entry->linked_server->id); 624 TRACE_SUB("inserting %d", entry->linked_server->id);
409 bheap_insert(server_order, &be_ready_servers, 625 bheap_insert(server_order, &be_ready_servers,
@@ -428,6 +644,7 @@ static noinline void unlink_server(cpu_entry_t *entry,
428 slack_timer_arm(&entry->hrt_server); 644 slack_timer_arm(&entry->hrt_server);
429 } 645 }
430 } 646 }
647 entry->linked_server = NULL;
431} 648}
432 649
433/* Update the link of a CPU. 650/* Update the link of a CPU.
@@ -437,7 +654,7 @@ static noinline void unlink_server(cpu_entry_t *entry,
437 */ 654 */
438static noinline void link_task_to_cpu(cpu_entry_t *entry, 655static noinline void link_task_to_cpu(cpu_entry_t *entry,
439 struct task_struct* linked, 656 struct task_struct* linked,
440 server_t* be_server) 657 server_t* next_server)
441{ 658{
442 cpu_entry_t *sched; 659 cpu_entry_t *sched;
443 server_t *tmp_server; 660 server_t *tmp_server;
@@ -449,7 +666,7 @@ static noinline void link_task_to_cpu(cpu_entry_t *entry,
449 666
450 /* Currently linked task is set to be unlinked. */ 667 /* Currently linked task is set to be unlinked. */
451 if (entry->linked) { 668 if (entry->linked) {
452 unlink_server(entry, be_server); 669 unlink_server(entry, next_server);
453 entry->linked->rt_param.linked_on = NO_CPU; 670 entry->linked->rt_param.linked_on = NO_CPU;
454 entry->linked = NULL; 671 entry->linked = NULL;
455 } 672 }
@@ -484,13 +701,12 @@ static noinline void link_task_to_cpu(cpu_entry_t *entry,
484 701
485 linked->rt_param.linked_on = sched->cpu; 702 linked->rt_param.linked_on = sched->cpu;
486 sched->linked = linked; 703 sched->linked = linked;
487 link_server(sched, be_server); 704 link_server(sched, next_server);
488 705
489 update_cpu_position(sched); 706 update_cpu_position(sched);
490 BUG_ON(!entry->linked && entry->linked_server);
491 707
492 linked = tmp_task; 708 linked = tmp_task;
493 be_server = tmp_server; 709 next_server = tmp_server;
494 } 710 }
495 } 711 }
496 if (linked) /* might be NULL due to swap */ 712 if (linked) /* might be NULL due to swap */
@@ -498,7 +714,7 @@ static noinline void link_task_to_cpu(cpu_entry_t *entry,
498 } 714 }
499 entry->linked = linked; 715 entry->linked = linked;
500 if (linked) 716 if (linked)
501 link_server(entry, be_server); 717 link_server(entry, next_server);
502 else 718 else
503 entry->linked_server = NULL; 719 entry->linked_server = NULL;
504 BUG_ON(!entry->linked && entry->linked_server); 720 BUG_ON(!entry->linked && entry->linked_server);
@@ -627,6 +843,30 @@ static struct task_struct* next_eligible_hrt(hrt_server_t *hrt_server)
627 return task; 843 return task;
628} 844}
629 845
846static struct task_struct* next_eligible_srt(void)
847{
848 struct task_struct *next_srt = __peek_ready(&srt_domain);
849 server_t *srt_server;
850
851 /* Catch up srt server. This happens when the job is tardy due
852 * to overutilization of the system.
853 */
854 if (next_srt) {
855 srt_server = tsk_rt(next_srt)->plugin_data;
856 if (srt_server->deadline < get_deadline(next_srt)) {
857 TRACE_SUB("catching up SRT to %llu",
858 get_release(next_srt));
859 server_release_at(srt_server, get_release(next_srt));
860 srt_server->job_no = task_job_no(next_srt);
861 }
862 }
863
864 if (next_srt && tsk_rt(next_srt)->slack_candidate)
865 take_next_slack(next_srt);
866
867 return next_srt;
868}
869
630/* 870/*
631 * The highest priority BE server. 871 * The highest priority BE server.
632 */ 872 */
@@ -636,27 +876,11 @@ static inline server_t* next_be_server(void)
636 return (hn) ? hn->value : NULL; 876 return (hn) ? hn->value : NULL;
637} 877}
638 878
639/* 879static server_t* next_eligible_be_server(void)
640 * Either an srt task or a be server is next. The deadline of the chosen
641 * task / server is put into deadline.
642 * TODO: remove this class business.
643 */
644static task_class_t next_global_task(struct task_struct **task_srt,
645 server_t **server_be,
646 lt_t *deadline)
647{ 880{
648 task_class_t rv = RT_CLASS_HARD; /* Represents invalid here */ 881 server_t *be_server = next_be_server();
649 struct task_struct *next_srt;
650 server_t *be_server, *srt_server;
651 lt_t now = litmus_clock(); 882 lt_t now = litmus_clock();
652 883
653 *task_srt = NULL;
654 *server_be = NULL;
655 *deadline = 0;
656
657 be_server = next_be_server();
658 next_srt = __peek_ready(&srt_domain);
659
660 /* Catch up any late be servers. This happens when the servers 884 /* Catch up any late be servers. This happens when the servers
661 * could not find tasks to schedule or if the system is 885 * could not find tasks to schedule or if the system is
662 * overutilized. 886 * overutilized.
@@ -670,56 +894,87 @@ static task_class_t next_global_task(struct task_struct **task_srt,
670 be_server->hn); 894 be_server->hn);
671 be_server = next_be_server(); 895 be_server = next_be_server();
672 } 896 }
897 return be_server;
898}
673 899
674 /* Catch up srt server. This happens when the job is tardy due 900static inline server_t* earlier_server(server_t *first, server_t *second)
675 * to overutilization of the system. 901{
676 */ 902 if (!first)
677 if (next_srt) { 903 return second;
678 srt_server = tsk_rt(next_srt)->plugin_data; 904 if (!second)
679 if (srt_server->deadline < get_deadline(next_srt)) { 905 return first;
680 TRACE_SUB("catching up SRT to %llu", 906 return (lt_before_eq(first->deadline, second->deadline)) ?
681 get_release(next_srt)); 907 first : second;
682 server_release_at(srt_server, get_release(next_srt)); 908}
683 srt_server->job_no = task_job_no(next_srt);
684 }
685 }
686 909
687 TRACE_SUB("be_server: %d, next_srt: %d", 910/*
911 * Either an srt task or a be server is next. The deadline of the chosen
912 * task / server is put into deadline.
913 * TODO: remove this class business.
914 */
915static lt_t next_global_task(struct task_struct **task_srt,
916 server_t **server_be,
917 server_t **server_slack)
918{
919 struct task_struct *next_srt;
920 server_t *be_server, *slack_server, *first_server;
921 lt_t deadline = 0;
922
923 *task_srt = NULL;
924 *server_be = NULL;
925 *server_slack = NULL;
926
927 be_server = next_eligible_be_server();
928 next_srt = next_eligible_srt();
929 slack_server = next_eligible_slack();
930
931 TRACE_SUB("be_server: %d, next_srt: %d, next_slack: %d",
688 (be_server) ? be_server->id : -1, 932 (be_server) ? be_server->id : -1,
689 (next_srt) ? next_srt->pid : -1); 933 (next_srt) ? next_srt->pid : -1,
934 (slack_server) ? slack_server->id : -1);
690 BUG_ON(next_srt && !is_srt(next_srt)); 935 BUG_ON(next_srt && !is_srt(next_srt));
691 936
692 if (next_srt && (!be_server || 937 first_server = earlier_server(be_server, slack_server);
938 first_server = be_server;
939
940 if (next_srt && (!first_server ||
693 lt_before(get_deadline(next_srt), 941 lt_before(get_deadline(next_srt),
694 be_server->deadline))) { 942 first_server->deadline))) {
695 /* SRT is next task */ 943 /* SRT is next task */
696 *server_be = NULL; 944 *server_be = NULL;
945 *server_slack = NULL;
697 *task_srt = next_srt; 946 *task_srt = next_srt;
698 *deadline = get_deadline(next_srt); 947 deadline = get_deadline(next_srt);
699 rv = RT_CLASS_SOFT; 948 } else if (be_server && be_server == first_server) {
700 } else if (be_server) {
701 /* BE is next task */ 949 /* BE is next task */
702 *server_be = be_server; 950 *server_be = be_server;
951 *server_slack = NULL;
952 *task_srt = NULL;
953 deadline = be_server->deadline;
954 } else if (slack_server) {
955 /* Slack is next task */
956 *server_be = NULL;
957 *server_slack = slack_server;
703 *task_srt = NULL; 958 *task_srt = NULL;
704 *deadline = be_server->deadline; 959 deadline = slack_server->deadline;
705 rv = RT_CLASS_BEST_EFFORT;
706 } 960 }
707 961
708 return rv; 962 return deadline;
709} 963}
710 964
711/* 965/*
712 * Adds a task to the appropriate queue (ready / release) in a domain. 966 * Adds a task to the appropriate queue (ready / release) in a domain.
713 */ 967 */
714static noinline void requeue(struct task_struct *task, rt_domain_t *domain) 968static noinline void requeue(struct task_struct *task, rt_domain_t *domain,
969 server_t *server)
715{ 970{
716 int was_added; 971 int was_added;
717 BUG_ON(!is_realtime(task)); 972 BUG_ON(!is_realtime(task));
718 BUG_ON(is_queued(task));
719 BUG_ON(is_be(task) && domain != &be_domain);
720 BUG_ON(is_srt(task) && domain != &srt_domain);
721 973
722 if (is_released(task, litmus_clock())) { 974 if (is_queued(task)) {
975 if (!is_released(task, litmus_clock()))
976 check_slack_candidate(task);
977 } else if (is_released(task, litmus_clock())) {
723 TRACE_TASK_SUB(task, "requeuing on ready"); 978 TRACE_TASK_SUB(task, "requeuing on ready");
724 __add_ready(domain, task); 979 __add_ready(domain, task);
725 } else { 980 } else {
@@ -745,25 +1000,134 @@ static noinline void requeue(struct task_struct *task, rt_domain_t *domain)
745 * be tasks. For other tasks, the server can be calculated later. 1000 * be tasks. For other tasks, the server can be calculated later.
746 */ 1001 */
747static void preempt(cpu_entry_t *entry, struct task_struct *next, 1002static void preempt(cpu_entry_t *entry, struct task_struct *next,
748 server_t *be_server) 1003 server_t *next_server)
749{ 1004{
750 rt_domain_t *domain; 1005 rt_domain_t *domain;
751 1006
752 if (entry->linked) { 1007 if (entry->linked) {
753 domain = get_rt_domain(entry, entry->linked); 1008 domain = get_rt_domain(entry, entry->linked);
754 requeue(entry->linked, domain); 1009 requeue(entry->linked, domain, entry->linked_server);
755 } 1010 }
756 1011
757 link_task_to_cpu(entry, next, be_server); 1012 link_task_to_cpu(entry, next, next_server);
758 preempt_if_preemptable(entry->scheduled, entry->cpu); 1013 preempt_if_preemptable(entry->scheduled, entry->cpu);
759} 1014}
760 1015
1016static inline struct task_struct* pick_next_be(server_t *be_server,
1017 cpu_entry_t *entry)
1018{
1019 struct task_struct *next_be = NULL;
1020 if (!be_server)
1021 goto out;
1022 next_be = __peek_ready(&be_domain);
1023 if (!next_be && entry->linked && is_be(entry->linked))
1024 next_be = entry->linked;
1025 out:
1026 return next_be;
1027}
1028
1029static cpu_entry_t* check_for_slack_preempt(struct task_struct *task,
1030 cpu_entry_t *next_entry)
1031{
1032 cpu_entry_t *preempted = NULL;
1033 cpu_entry_t *entry = task_linked_entry(task);
1034 server_t *slack_server = task_slack_server(task);
1035
1036 BUG_ON(!is_srt(task));
1037
1038 if (!slack_server || !slack_server->running)
1039 goto out;
1040
1041 TRACE_TASK_SUB(task, "slack preempt");
1042 sched_trace_action(task, 10);
1043
1044 preempted = entry;
1045
1046 unlink(task);
1047 take_next_slack(task);
1048 out:
1049 return preempted;
1050}
1051
1052/*
1053 * Selects and links the next task for the given CPU.
1054 * TODO: this method is terrible
1055 */
1056static void edf_hsb_pick_next(cpu_entry_t *entry)
1057{
1058 lt_t deadline;
1059 struct task_struct *next_hrt, *next_srt, *next_be, *next_slack;
1060 server_t *be_server, *slack_server;
1061 cpu_entry_t *preempted;
1062
1063 BUG_ON(entry->linked);
1064
1065 next_hrt = next_eligible_hrt(&entry->hrt_server);
1066
1067 if (next_hrt) {
1068 /* HRT is next task */
1069 link_task_to_cpu(entry, next_hrt, &entry->hrt_server.server);
1070 remove(&entry->hrt_server.hrt_domain, next_hrt);
1071 } else {
1072 deadline = next_global_task(&next_srt,
1073 &be_server,
1074 &slack_server);
1075
1076 if (next_srt) {
1077 remove(&srt_domain, next_srt);
1078
1079 preempted = check_for_slack_preempt(next_srt, entry);
1080 if (preempted) {
1081 edf_hsb_pick_next(preempted);
1082 preempt_if_preemptable(preempted->scheduled,
1083 preempted->cpu);
1084 }
1085
1086 link_task_to_cpu(entry, next_srt,
1087 task_srt_server(next_srt));
1088 } else if (be_server) {
1089 next_be = __take_ready(&be_domain);
1090
1091 if (next_be) {
1092 TRACE_SUB("deleting be server %d",
1093 be_server->id);
1094 bheap_delete(server_order, &be_ready_servers,
1095 be_server->hn);
1096 link_task_to_cpu(entry, next_be, be_server);
1097 }
1098 } else if (slack_server) {
1099 next_slack = pick_next_slack(slack_server, NULL);
1100
1101 if (next_slack) {
1102 take_next_slack(next_slack);
1103 list_del(&slack_server->list);
1104 TRACE_TASK_SUB(next_slack, "taking");
1105 link_task_to_cpu(entry, next_slack, slack_server);
1106 }
1107 }
1108 }
1109
1110 /* Try SRT again */
1111 if (!entry->linked) {
1112 next_srt = __take_ready(&srt_domain);
1113 if (!next_srt)
1114 return;
1115 preempted = check_for_slack_preempt(next_srt, entry);
1116 if (preempted) {
1117 edf_hsb_pick_next(preempted);
1118 preempt_if_preemptable(preempted->scheduled,
1119 preempted->cpu);
1120 }
1121
1122 link_task_to_cpu(entry, next_srt, task_srt_server(next_srt));
1123 }
1124}
1125
761static void check_for_global_preempt(void) 1126static void check_for_global_preempt(void)
762{ 1127{
763 task_class_t class;
764 cpu_entry_t *entry; 1128 cpu_entry_t *entry;
765 server_t *be_server = NULL; 1129 server_t *be_server = NULL, *slack_server = NULL, *next_server;
766 struct task_struct *next_srt, *next_be; 1130 struct task_struct *next_srt, *next_be, *next_slack;
767 struct task_struct *next_task = (struct task_struct*)1; /* Not null */ 1131 struct task_struct *next_task = (struct task_struct*)1; /* Not null */
768 lt_t deadline; 1132 lt_t deadline;
769 1133
@@ -775,21 +1139,27 @@ static void check_for_global_preempt(void)
775 BUG_ON(entry->linked && is_hrt(entry->linked)); 1139 BUG_ON(entry->linked && is_hrt(entry->linked));
776 1140
777 /* Get the potential challengers */ 1141 /* Get the potential challengers */
778 class = next_global_task(&next_srt, 1142 deadline = next_global_task(&next_srt,
779 &be_server, 1143 &be_server,
780 &deadline); 1144 &slack_server);
781 next_be = __peek_ready(&be_domain); 1145 next_be = pick_next_be(be_server, entry);
1146 next_slack = pick_next_slack(slack_server, entry);
782 1147
783 /* If there is no existing BE, then the server must have 1148 /* If there is no existing BE, then the server must have
784 * a new BE task to schedule. If it doesn't, try SRT. 1149 * a new BE task to schedule. If it doesn't, others.
785 */ 1150 */
786 if (be_server && !next_be && 1151 if (be_server && !next_be) {
787 (!entry->linked || !is_be(entry->linked))) {
788 TRACE_SUB("2"); 1152 TRACE_SUB("2");
789 be_server = NULL; 1153 be_server = NULL;
790 next_srt = __peek_ready(&srt_domain); 1154 next_srt = next_eligible_srt();
1155 deadline = (next_srt) ?get_deadline(next_srt) : 0;
1156 }
1157
1158 if (slack_server && !next_slack) {
1159 TRACE_SUB("3");
1160 slack_server = NULL;
1161 next_srt = next_eligible_srt();
791 deadline = (next_srt) ?get_deadline(next_srt) : 0; 1162 deadline = (next_srt) ?get_deadline(next_srt) : 0;
792 class = RT_CLASS_SOFT;
793 } 1163 }
794 1164
795 TRACE_SUB("4"); 1165 TRACE_SUB("4");
@@ -815,8 +1185,7 @@ static void check_for_global_preempt(void)
815 lt_before(deadline, entry->linked_server->deadline)){ 1185 lt_before(deadline, entry->linked_server->deadline)){
816 TRACE_SUB("8"); 1186 TRACE_SUB("8");
817 /* Swap two BE servers here */ 1187 /* Swap two BE servers here */
818 if ((class & get_class(entry->linked)) == 1188 if (be_server && entry->linked_server->type == S_BE) {
819 RT_CLASS_BEST_EFFORT) {
820 TRACE_SUB("9"); 1189 TRACE_SUB("9");
821 bheap_delete(server_order, 1190 bheap_delete(server_order,
822 &be_ready_servers, 1191 &be_ready_servers,
@@ -827,6 +1196,16 @@ static void check_for_global_preempt(void)
827 next_task = entry->linked; 1196 next_task = entry->linked;
828 goto loop_end; 1197 goto loop_end;
829 } 1198 }
1199 /* Swap two slack servers here */
1200 if (slack_server && entry->linked_server->type == S_SLACK) {
1201 TRACE_SUB("9.5");
1202 list_del(&slack_server->list);
1203 unlink_server(entry, slack_server);
1204 link_server(entry, slack_server);
1205 update_cpu_position(entry);
1206 next_task = entry->linked;
1207 goto loop_end;
1208 }
830 TRACE_SUB("10"); 1209 TRACE_SUB("10");
831 goto loop_end_preempt; 1210 goto loop_end_preempt;
832 } 1211 }
@@ -835,9 +1214,11 @@ static void check_for_global_preempt(void)
835 1214
836 loop_end_preempt: 1215 loop_end_preempt:
837 TRACE_SUB("13"); 1216 TRACE_SUB("13");
838 if (class == RT_CLASS_SOFT) { 1217 if (next_srt) {
839 next_task = next_srt; 1218 next_task = next_srt;
840 } else { 1219 next_server = task_srt_server(next_task);
1220 check_for_slack_preempt(next_srt, entry);
1221 } else if (next_be) {
841 next_task = next_be; 1222 next_task = next_be;
842 if (bheap_node_in_heap(be_server->hn)) { 1223 if (bheap_node_in_heap(be_server->hn)) {
843 TRACE_SUB("deleting be server %d", 1224 TRACE_SUB("deleting be server %d",
@@ -845,11 +1226,20 @@ static void check_for_global_preempt(void)
845 bheap_delete(server_order, &be_ready_servers, 1226 bheap_delete(server_order, &be_ready_servers,
846 be_server->hn); 1227 be_server->hn);
847 } 1228 }
1229 next_server = be_server;
1230 } else { /* Slack */
1231 next_task = next_slack;
1232 next_server = slack_server;
1233 list_del(&slack_server->list);
848 } 1234 }
849 BUG_ON(!next_task); 1235 BUG_ON(!next_task);
850 TRACE_TASK_SUB(next_task, "preempting on P%d", entry->cpu); 1236 TRACE_TASK_SUB(next_task, "preempting on P%d", entry->cpu);
851 remove(get_rt_domain(entry, next_task), next_task); 1237
852 preempt(entry, next_task, be_server); 1238 if (next_server != slack_server && is_queued(next_task))
1239 remove(get_rt_domain(entry, next_task), next_task);
1240 else if (next_slack)
1241 take_next_slack(next_slack);
1242 preempt(entry, next_task, next_server);
853 1243
854 loop_end: 1244 loop_end:
855 TRACE_SUB("14"); 1245 TRACE_SUB("14");
@@ -868,15 +1258,18 @@ static void check_for_hrt_preempt(cpu_entry_t *entry)
868 1258
869 TRACE_SUB("checking for HRT preempt on P%d", entry->cpu); 1259 TRACE_SUB("checking for HRT preempt on P%d", entry->cpu);
870 1260
1261 if (next_hrt)
1262 reclaim_slack(&server->server);
1263
871 if (next_hrt && 1264 if (next_hrt &&
872 (!entry->linked || !is_hrt(entry->linked) || 1265 (!entry->linked || !is_hrt(entry->linked) ||
873 edf_preemption_needed(&server->hrt_domain, entry->linked))) { 1266 edf_preemption_needed(&server->hrt_domain, entry->linked))) {
874 1267
875 TRACE_TASK_SUB(next_hrt, "preempting on CPU %d", entry->cpu); 1268 TRACE_TASK_SUB(next_hrt, "preempting on CPU %d", entry->cpu);
876 remove(&server->hrt_domain, next_hrt); 1269 remove(&server->hrt_domain, next_hrt);
877 preempt(entry, next_hrt, NULL); 1270 preempt(entry, next_hrt, &server->server);
878 1271
879 /* We might have just kicked off an SRT. Check to see if it 1272 /* We might have just kicked off something. Check to see if it
880 * preempts anything. 1273 * preempts anything.
881 */ 1274 */
882 if (curr && !is_hrt(curr)) 1275 if (curr && !is_hrt(curr))
@@ -900,14 +1293,14 @@ static void job_arrival(struct task_struct *task, cpu_entry_t *entry)
900 TRACE_TASK_SUB(task, "Arriving on P%d", entry->cpu); 1293 TRACE_TASK_SUB(task, "Arriving on P%d", entry->cpu);
901 1294
902 if (is_hrt(task)) { 1295 if (is_hrt(task)) {
903 requeue(task, &entry->hrt_server.hrt_domain); 1296 requeue(task, &entry->hrt_server.hrt_domain, NULL);
904 check_for_hrt_preempt(entry); 1297 check_for_hrt_preempt(entry);
905 } else if (is_srt(task)) { 1298 } else if (is_srt(task)) {
906 requeue(task, &srt_domain); 1299 requeue(task, &srt_domain, NULL);
907 check_for_global_preempt(); 1300 check_for_global_preempt();
908 } else /* BE */ { 1301 } else /* BE */ {
909 was_empty = !__jobs_pending(&be_domain); 1302 was_empty = !__jobs_pending(&be_domain);
910 requeue(task, &be_domain); 1303 requeue(task, &be_domain, NULL);
911 1304
912 /* Only way this could cause a preemption is if 1305 /* Only way this could cause a preemption is if
913 * an eligible BE server could not queue up a task. 1306 * an eligible BE server could not queue up a task.
@@ -917,51 +1310,6 @@ static void job_arrival(struct task_struct *task, cpu_entry_t *entry)
917 } 1310 }
918} 1311}
919 1312
920/*
921 * Selects and links the next task for the given CPU.
922 */
923static void edf_hsb_pick_next(cpu_entry_t *entry)
924{
925 task_class_t class;
926 lt_t deadline;
927 struct task_struct *next_hrt, *next_srt, *next_be;
928 server_t *be_server;
929
930 BUG_ON(entry->linked);
931
932 next_hrt = next_eligible_hrt(&entry->hrt_server);
933
934 if (next_hrt) {
935 /* HRT is next task */
936 link_task_to_cpu(entry, next_hrt, NULL);
937 remove(&entry->hrt_server.hrt_domain, next_hrt);
938 } else {
939 class = next_global_task(&next_srt,
940 &be_server,
941 &deadline);
942 if (next_srt) {
943 remove(&srt_domain, next_srt);
944 link_task_to_cpu(entry, next_srt, NULL);
945 } else if (be_server) {
946 next_be = __take_ready(&be_domain);
947
948 if (next_be) {
949 TRACE_SUB("deleting be server %d",
950 be_server->id);
951 bheap_delete(server_order, &be_ready_servers,
952 be_server->hn);
953 link_task_to_cpu(entry, next_be, be_server);
954 } else {
955 /* Nothing to schedule! Try SRT */
956 next_srt = __take_ready(&srt_domain);
957 if (!next_srt)
958 return;
959 link_task_to_cpu(entry, next_srt, NULL);
960 }
961 }
962 }
963}
964
965/****************************************************************************** 1313/******************************************************************************
966 * Timer methods 1314 * Timer methods
967 ******************************************************************************/ 1315 ******************************************************************************/
@@ -1069,26 +1417,37 @@ static enum hrtimer_restart slack_timer_fire(struct hrtimer *timer)
1069 1417
1070static void job_completion(cpu_entry_t *entry, struct task_struct* task) 1418static void job_completion(cpu_entry_t *entry, struct task_struct* task)
1071{ 1419{
1072 server_t *srt_server; 1420 server_t *server = entry->linked_server;
1073 set_rt_flags(task, RT_F_SLEEP); 1421 set_rt_flags(task, RT_F_SLEEP);
1074 1422
1075 TRACE_TASK_SUB(task, "completed"); 1423 TRACE_TASK_SUB(task, "completed");
1076 1424
1077 unlink(task); 1425 unlink(task);
1078 1426
1079 if (is_srt(task)) { 1427 donate_slack(server, task);
1080 srt_server = tsk_rt(task)->plugin_data; 1428
1429 if (server->type == S_SLACK && is_srt(task)) {
1430 TRACE_TASK_SUB(task, "slack server catching up");
1431 tsk_rt(task)->job_params.job_no++;
1432 add_slack(server);
1433 check_slack_candidate(task);
1434 sched_trace_task_completion(task, 1);
1435 return;
1436 }
1437
1438 BUG_ON(is_queued(task));
1081 1439
1440 if (server->type == S_SRT) {
1082 /* If the task is behind the server it must release immediately, 1441 /* If the task is behind the server it must release immediately,
1083 * leaving its release time and deadline unchanged. 1442 * leaving its release time and deadline unchanged.
1084 */ 1443 */
1085 if (srt_server->job_no > tsk_rt(task)->job_params.job_no) { 1444 if (server->job_no > tsk_rt(task)->job_params.job_no) {
1086 TRACE_TASK_SUB(task, "catching up"); 1445 TRACE_TASK_SUB(task, "catching up");
1087 tsk_rt(task)->job_params.job_no++; 1446 tsk_rt(task)->job_params.job_no++;
1088 } else { 1447 } else {
1089 /* Otherwise release them both */ 1448 /* Otherwise release them both */
1090 prepare_for_next_period(task); 1449 prepare_for_next_period(task);
1091 server_release(srt_server); 1450 server_release(server);
1092 } 1451 }
1093 } else { 1452 } else {
1094 prepare_for_next_period(task); 1453 prepare_for_next_period(task);
@@ -1115,9 +1474,9 @@ static void server_completed(server_t *server, struct task_struct *task)
1115 TRACE_TASK_TIMER(task, "server %d completed, task exec: %llu", 1474 TRACE_TASK_TIMER(task, "server %d completed, task exec: %llu",
1116 server->id, get_exec_time(task)); 1475 server->id, get_exec_time(task));
1117 BUG_ON(entry->linked != task); 1476 BUG_ON(entry->linked != task);
1118 sched_trace_action(entry->linked, 1); 1477 //sched_trace_action(entry->linked, 1);
1119 1478
1120 if (is_srt(task)) { 1479 if (server->type == S_SRT) {
1121 TRACE_TASK_SUB(task, "must wait on server"); 1480 TRACE_TASK_SUB(task, "must wait on server");
1122 1481
1123 /* The job must now take the priority and release time 1482 /* The job must now take the priority and release time
@@ -1131,6 +1490,8 @@ static void server_completed(server_t *server, struct task_struct *task)
1131 tsk_rt(task)->job_params.release = server->deadline; 1490 tsk_rt(task)->job_params.release = server->deadline;
1132 tsk_rt(task)->job_params.deadline = server->deadline + 1491 tsk_rt(task)->job_params.deadline = server->deadline +
1133 get_rt_period(task); 1492 get_rt_period(task);
1493
1494 check_slack_candidate(task);
1134 } 1495 }
1135 1496
1136 /* Someone else may have brought this server forward. 1497 /* Someone else may have brought this server forward.
@@ -1143,14 +1504,15 @@ static void server_completed(server_t *server, struct task_struct *task)
1143 hrt_server = container_of(server, hrt_server_t, server); 1504 hrt_server = container_of(server, hrt_server_t, server);
1144 TRACE_SUB("P%d no longer ready", entry->cpu); 1505 TRACE_SUB("P%d no longer ready", entry->cpu);
1145 hrt_server->ready = 0; 1506 hrt_server->ready = 0;
1146 } 1507 }
1147 1508
1148 unlink(task); 1509 unlink(task);
1149 requeue(task, get_rt_domain(entry, task)); 1510 requeue(task, get_rt_domain(entry, task), server);
1150 1511
1151 /* Need to pick the next task to run */ 1512 /* Need to pick the next task to run */
1152 edf_hsb_pick_next(entry); 1513 check_for_global_preempt();
1153 preempt_if_preemptable(entry->scheduled, entry->cpu); 1514 if (!entry->linked)
1515 preempt_if_preemptable(entry->scheduled, entry->cpu);
1154} 1516}
1155 1517
1156static void hrt_server_released(server_t *server) 1518static void hrt_server_released(server_t *server)
@@ -1169,14 +1531,16 @@ static void hrt_server_released(server_t *server)
1169 if (entry->linked && is_hrt(entry->linked) && 1531 if (entry->linked && is_hrt(entry->linked) &&
1170 !is_eligible(entry->linked, hrt_server)) { 1532 !is_eligible(entry->linked, hrt_server)) {
1171 1533
1172 requeue(entry->linked, &hrt_server->hrt_domain); 1534 requeue(entry->linked, &hrt_server->hrt_domain,
1535 entry->linked_server);
1173 unlink(entry->linked); 1536 unlink(entry->linked);
1174 1537
1175 server_release(server); 1538 server_release(server);
1176 edf_hsb_pick_next(entry); 1539 edf_hsb_pick_next(entry);
1177 preempt_if_preemptable(entry->scheduled, entry->cpu); 1540 preempt_if_preemptable(entry->scheduled, entry->cpu);
1178 } else { 1541 } else {
1179 /* Otherwise check to see if a different task should * be running. 1542 /* Otherwise check to see if a different task should
1543 * be running.
1180 */ 1544 */
1181 check_for_hrt_preempt(entry); 1545 check_for_hrt_preempt(entry);
1182 1546
@@ -1204,7 +1568,7 @@ static void servers_released(struct list_head *servers)
1204 list_for_each(pos, servers) { 1568 list_for_each(pos, servers) {
1205 server = list_entry(pos, server_t, release_list); 1569 server = list_entry(pos, server_t, release_list);
1206 1570
1207 if (server->type == RT_CLASS_BEST_EFFORT) { 1571 if (server->type == S_BE) {
1208 was_be = 1; 1572 was_be = 1;
1209 BUG_ON(bheap_node_in_heap(server->hn)); 1573 BUG_ON(bheap_node_in_heap(server->hn));
1210 TRACE_SUB("inserting be server %d", server->id); 1574 TRACE_SUB("inserting be server %d", server->id);
@@ -1249,7 +1613,7 @@ static int admit_be_server(unsigned long long wcet,
1249 be_server = kmalloc(sizeof(server_t), GFP_ATOMIC); 1613 be_server = kmalloc(sizeof(server_t), GFP_ATOMIC);
1250 server_init(be_server, BE_SERVER_BASE + ++curr_be, 1614 server_init(be_server, BE_SERVER_BASE + ++curr_be,
1251 wcet, period, 1); 1615 wcet, period, 1);
1252 be_server->type = RT_CLASS_BEST_EFFORT; 1616 be_server->type = S_BE;
1253 1617
1254 TRACE("created BE server %d (%llu, %llu)\n", be_server->id, 1618 TRACE("created BE server %d (%llu, %llu)\n", be_server->id,
1255 wcet, period); 1619 wcet, period);
@@ -1314,7 +1678,7 @@ static int admit_hrt_server(unsigned long long wcet,
1314 hrt_server->no_slack = 0; 1678 hrt_server->no_slack = 0;
1315 1679
1316 server_init(&hrt_server->server, cpu, wcet, period, 1); 1680 server_init(&hrt_server->server, cpu, wcet, period, 1);
1317 hrt_server->server.type = RT_CLASS_HARD; 1681 hrt_server->server.type = S_HRT;
1318 1682
1319 edf_domain_init(&hrt_server->hrt_domain, NULL, 1683 edf_domain_init(&hrt_server->hrt_domain, NULL,
1320 release_hrt_jobs); 1684 release_hrt_jobs);
@@ -1603,8 +1967,6 @@ static struct task_struct* edf_hsb_schedule(struct task_struct *prev)
1603 entry->scheduled = entry->linked; 1967 entry->scheduled = entry->linked;
1604 sched_state_task_picked(); 1968 sched_state_task_picked();
1605 1969
1606 BUG_ON(entry->scheduled && is_queued(entry->scheduled));
1607
1608 if (entry->scheduled) 1970 if (entry->scheduled)
1609 TRACE_TASK(entry->scheduled, "scheduled at %llu\n", 1971 TRACE_TASK(entry->scheduled, "scheduled at %llu\n",
1610 TIME(litmus_clock())); 1972 TIME(litmus_clock()));
@@ -1637,7 +1999,8 @@ static void edf_hsb_task_new(struct task_struct *task, int on_rq, int running)
1637 srt_server = kmalloc(sizeof(server_t), GFP_ATOMIC); 1999 srt_server = kmalloc(sizeof(server_t), GFP_ATOMIC);
1638 server_init(srt_server, task->pid, get_exec_cost(task), 2000 server_init(srt_server, task->pid, get_exec_cost(task),
1639 get_rt_period(task), 0); 2001 get_rt_period(task), 0);
1640 srt_server->type = RT_CLASS_SOFT; 2002 srt_server->type = S_SRT;
2003 srt_server->data = task;
1641 srt_server->job_no = tsk_rt(task)->job_params.job_no; 2004 srt_server->job_no = tsk_rt(task)->job_params.job_no;
1642 server_release_at(srt_server, get_release(task)); 2005 server_release_at(srt_server, get_release(task));
1643 } 2006 }
@@ -1758,6 +2121,8 @@ static int __init init_edf_hsb(void)
1758 bheap_init(&cpu_heap); 2121 bheap_init(&cpu_heap);
1759 bheap_init(&be_ready_servers); 2122 bheap_init(&be_ready_servers);
1760 INIT_LIST_HEAD(&be_servers); 2123 INIT_LIST_HEAD(&be_servers);
2124 INIT_LIST_HEAD(&slack_queue);
2125 INIT_LIST_HEAD(&slack_candidates);
1761 2126
1762 for_each_online_cpu(cpu) { 2127 for_each_online_cpu(cpu) {
1763 entry = &per_cpu(cpu_entries, cpu); 2128 entry = &per_cpu(cpu_entries, cpu);