diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2013-03-13 14:41:03 -0400 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2013-03-13 14:57:09 -0400 |
commit | a51fba95554e70bd74308c13cf804102a99973b3 (patch) | |
tree | 189167694d7ce6bbea486b83335b3e9cfbb843fe | |
parent | 5a2819df472ccbd2915fa0d50d7ce04b97b0849b (diff) | |
parent | f4ffe0719dfc150ee182f308d31a226b034f206b (diff) |
Merge branch 'gh/staging' into temp
Conflicts:
include/litmus/litmus.h
include/litmus/rt_param.h
litmus/Makefile
litmus/sched_cedf.c
litmus/sched_gsn_edf.c
-rw-r--r-- | include/litmus/litmus.h | 23 | ||||
-rw-r--r-- | include/litmus/rt_param.h | 19 | ||||
-rw-r--r-- | litmus/Kconfig | 21 | ||||
-rw-r--r-- | litmus/Makefile | 3 | ||||
-rw-r--r-- | litmus/aux_tasks.c | 7 | ||||
-rw-r--r-- | litmus/jobs.c | 8 | ||||
-rw-r--r-- | litmus/litmus_softirq.c | 7 | ||||
-rw-r--r-- | litmus/sched_cedf.c | 31 | ||||
-rw-r--r-- | litmus/sched_gsn_edf.c | 7 | ||||
-rw-r--r-- | litmus/sched_pfair.c | 2 | ||||
-rw-r--r-- | litmus/sched_pfp.c | 2 | ||||
-rw-r--r-- | litmus/sched_psn_edf.c | 4 | ||||
-rw-r--r-- | litmus/uncachedev.c | 102 |
13 files changed, 186 insertions, 50 deletions
diff --git a/include/litmus/litmus.h b/include/litmus/litmus.h index 17d30326034c..70b421d59d34 100644 --- a/include/litmus/litmus.h +++ b/include/litmus/litmus.h | |||
@@ -61,6 +61,7 @@ void litmus_exit_task(struct task_struct *tsk); | |||
61 | #define get_partition(t) (tsk_rt(t)->task_params.cpu) | 61 | #define get_partition(t) (tsk_rt(t)->task_params.cpu) |
62 | #define get_priority(t) (tsk_rt(t)->task_params.priority) | 62 | #define get_priority(t) (tsk_rt(t)->task_params.priority) |
63 | #define get_class(t) (tsk_rt(t)->task_params.cls) | 63 | #define get_class(t) (tsk_rt(t)->task_params.cls) |
64 | #define get_release_policy(t) (tsk_rt(t)->task_params.release_policy) | ||
64 | 65 | ||
65 | /* job_param macros */ | 66 | /* job_param macros */ |
66 | #define get_exec_time(t) (tsk_rt(t)->job_params.exec_time) | 67 | #define get_exec_time(t) (tsk_rt(t)->job_params.exec_time) |
@@ -72,6 +73,15 @@ void litmus_exit_task(struct task_struct *tsk); | |||
72 | #define effective_priority(t) ((!(tsk_rt(t)->inh_task)) ? t : tsk_rt(t)->inh_task) | 73 | #define effective_priority(t) ((!(tsk_rt(t)->inh_task)) ? t : tsk_rt(t)->inh_task) |
73 | #define base_priority(t) (t) | 74 | #define base_priority(t) (t) |
74 | 75 | ||
76 | /* release policy macros */ | ||
77 | #define is_periodic(t) (get_release_policy(t) == PERIODIC) | ||
78 | #define is_sporadic(t) (get_release_policy(t) == SPORADIC) | ||
79 | #ifdef CONFIG_ALLOW_EARLY_RELEASE | ||
80 | #define is_early_releasing(t) (get_release_policy(t) == EARLY) | ||
81 | #else | ||
82 | #define is_early_releasing(t) (0) | ||
83 | #endif | ||
84 | |||
75 | #define is_hrt(t) \ | 85 | #define is_hrt(t) \ |
76 | (tsk_rt(t)->task_params.cls == RT_CLASS_HARD) | 86 | (tsk_rt(t)->task_params.cls == RT_CLASS_HARD) |
77 | #define is_srt(t) \ | 87 | #define is_srt(t) \ |
@@ -85,19 +95,6 @@ static inline lt_t litmus_clock(void) | |||
85 | return ktime_to_ns(ktime_get()); | 95 | return ktime_to_ns(ktime_get()); |
86 | } | 96 | } |
87 | 97 | ||
88 | static inline int is_persistent(struct task_struct* t) | ||
89 | { | ||
90 | int is_per = ( 0 | ||
91 | #ifdef CONFIG_REALTIME_AUX_TASKS | ||
92 | || t->rt_param.is_aux_task | ||
93 | #endif | ||
94 | #ifdef CONFIG_LITMUS_SOFTIRQD | ||
95 | || t->rt_param.is_interrupt_thread | ||
96 | #endif | ||
97 | ); | ||
98 | return is_per; | ||
99 | } | ||
100 | |||
101 | /* A macro to convert from nanoseconds to ktime_t. */ | 98 | /* A macro to convert from nanoseconds to ktime_t. */ |
102 | #define ns_to_ktime(t) ktime_add_ns(ktime_set(0, 0), t) | 99 | #define ns_to_ktime(t) ktime_add_ns(ktime_set(0, 0), t) |
103 | 100 | ||
diff --git a/include/litmus/rt_param.h b/include/litmus/rt_param.h index d9b0fa329b67..bf0ee8dbae6e 100644 --- a/include/litmus/rt_param.h +++ b/include/litmus/rt_param.h | |||
@@ -41,6 +41,24 @@ typedef enum { | |||
41 | PRECISE_SIGNALS, /* budget signals are triggered with hrtimers */ | 41 | PRECISE_SIGNALS, /* budget signals are triggered with hrtimers */ |
42 | } budget_signal_policy_t; | 42 | } budget_signal_policy_t; |
43 | 43 | ||
44 | /* Release behaviors for jobs. PERIODIC and EARLY jobs | ||
45 | must end by calling sys_complete_job() (or equivalent) | ||
46 | to set up their next release and deadline. */ | ||
47 | typedef enum { | ||
48 | /* Jobs are released sporadically (provided job precedence | ||
49 | constraints are met). */ | ||
50 | SPORADIC, | ||
51 | |||
52 | /* Jobs are released periodically (provided job precedence | ||
53 | constraints are met). */ | ||
54 | PERIODIC, | ||
55 | |||
56 | /* Jobs are released immediately after meeting precedence | ||
57 | constraints. Beware this can peg your CPUs if used in | ||
58 | the wrong applications. Only supported by EDF schedulers. */ | ||
59 | EARLY | ||
60 | } release_policy_t; | ||
61 | |||
44 | typedef enum { | 62 | typedef enum { |
45 | AUX_ENABLE = 0x1, | 63 | AUX_ENABLE = 0x1, |
46 | AUX_CURRENT = (AUX_ENABLE<<1), | 64 | AUX_CURRENT = (AUX_ENABLE<<1), |
@@ -115,6 +133,7 @@ struct rt_task { | |||
115 | task_class_t cls; | 133 | task_class_t cls; |
116 | budget_policy_t budget_policy; /* ignored by pfair */ | 134 | budget_policy_t budget_policy; /* ignored by pfair */ |
117 | budget_signal_policy_t budget_signal_policy; /* currently ignored by pfair */ | 135 | budget_signal_policy_t budget_signal_policy; /* currently ignored by pfair */ |
136 | release_policy_t release_policy; | ||
118 | }; | 137 | }; |
119 | 138 | ||
120 | union np_flag { | 139 | union np_flag { |
diff --git a/litmus/Kconfig b/litmus/Kconfig index 9e8ef804b499..437ce82f97e9 100644 --- a/litmus/Kconfig +++ b/litmus/Kconfig | |||
@@ -180,6 +180,27 @@ config SCHED_CPU_AFFINITY | |||
180 | 180 | ||
181 | Say Yes if unsure. | 181 | Say Yes if unsure. |
182 | 182 | ||
183 | config ALLOW_EARLY_RELEASE | ||
184 | bool "Allow Early Releasing" | ||
185 | default y | ||
186 | help | ||
187 | Allow tasks to release jobs early (while still maintaining job | ||
188 | precedence constraints). Only supported by EDF schedulers. Early | ||
189 | releasing must be explicitly requested by real-time tasks via | ||
190 | the task_params passed to sys_set_task_rt_param(). | ||
191 | |||
192 | Early releasing can improve job response times while maintaining | ||
193 | real-time correctness. However, it can easily peg your CPUs | ||
194 | since tasks never suspend to wait for their next job. As such, early | ||
195 | releasing is really only useful in the context of implementing | ||
196 | bandwidth servers, interrupt handling threads, or short-lived | ||
197 | computations. | ||
198 | |||
199 | Beware that early releasing may affect real-time analysis | ||
200 | if using locking protocols or I/O. | ||
201 | |||
202 | Say Yes if unsure. | ||
203 | |||
183 | choice | 204 | choice |
184 | prompt "EDF Tie-Break Behavior" | 205 | prompt "EDF Tie-Break Behavior" |
185 | default EDF_TIE_BREAK_LATENESS_NORM | 206 | default EDF_TIE_BREAK_LATENESS_NORM |
diff --git a/litmus/Makefile b/litmus/Makefile index 6b7acf0bbf2c..642a03617d4a 100644 --- a/litmus/Makefile +++ b/litmus/Makefile | |||
@@ -18,7 +18,8 @@ obj-y = sched_plugin.o litmus.o \ | |||
18 | bheap.o \ | 18 | bheap.o \ |
19 | binheap.o \ | 19 | binheap.o \ |
20 | ctrldev.o \ | 20 | ctrldev.o \ |
21 | aux_tasks.o \ | 21 | aux_tasks.o \ |
22 | uncachedev.o \ | ||
22 | sched_gsn_edf.o \ | 23 | sched_gsn_edf.o \ |
23 | sched_psn_edf.o \ | 24 | sched_psn_edf.o \ |
24 | sched_pfp.o | 25 | sched_pfp.o |
diff --git a/litmus/aux_tasks.c b/litmus/aux_tasks.c index a9fa9df5ef8b..db6523a3dcf7 100644 --- a/litmus/aux_tasks.c +++ b/litmus/aux_tasks.c | |||
@@ -27,14 +27,17 @@ static int admit_aux_task(struct task_struct *t) | |||
27 | * fail-safe. | 27 | * fail-safe. |
28 | */ | 28 | */ |
29 | struct rt_task tp = { | 29 | struct rt_task tp = { |
30 | .exec_cost = AUX_SLICE_NS, | ||
30 | .period = AUX_SLICE_NS, | 31 | .period = AUX_SLICE_NS, |
31 | .relative_deadline = AUX_SLICE_NS, | 32 | .relative_deadline = AUX_SLICE_NS, |
32 | .exec_cost = AUX_SLICE_NS, /* allow full utilization with buget tracking */ | ||
33 | .phase = 0, | 33 | .phase = 0, |
34 | .cpu = task_cpu(leader), /* take CPU of group leader */ | 34 | .cpu = task_cpu(leader), /* take CPU of group leader */ |
35 | .priority = LITMUS_LOWEST_PRIORITY, | ||
36 | .cls = RT_CLASS_BEST_EFFORT, | ||
35 | .budget_policy = QUANTUM_ENFORCEMENT, | 37 | .budget_policy = QUANTUM_ENFORCEMENT, |
36 | .budget_signal_policy = NO_SIGNALS, | 38 | .budget_signal_policy = NO_SIGNALS, |
37 | .cls = RT_CLASS_BEST_EFFORT | 39 | /* use SPORADIC instead of EARLY since util = 1.0 */ |
40 | .release_policy = SPORADIC, | ||
38 | }; | 41 | }; |
39 | 42 | ||
40 | struct sched_param param = { .sched_priority = 0}; | 43 | struct sched_param param = { .sched_priority = 0}; |
diff --git a/litmus/jobs.c b/litmus/jobs.c index 659625433867..991c6e60be74 100644 --- a/litmus/jobs.c +++ b/litmus/jobs.c | |||
@@ -8,14 +8,6 @@ | |||
8 | 8 | ||
9 | static inline void setup_release(struct task_struct *t, lt_t release) | 9 | static inline void setup_release(struct task_struct *t, lt_t release) |
10 | { | 10 | { |
11 | /* Shift all tasks that are actually daemons that inherit | ||
12 | * priority to be released immediatly. They need to be ready to run | ||
13 | * at _all_ times. | ||
14 | */ | ||
15 | if (unlikely(is_persistent(t))) { | ||
16 | release = litmus_clock(); | ||
17 | } | ||
18 | |||
19 | /* prepare next release */ | 11 | /* prepare next release */ |
20 | t->rt_param.job_params.release = release; | 12 | t->rt_param.job_params.release = release; |
21 | t->rt_param.job_params.deadline = release + get_rt_relative_deadline(t); | 13 | t->rt_param.job_params.deadline = release + get_rt_relative_deadline(t); |
diff --git a/litmus/litmus_softirq.c b/litmus/litmus_softirq.c index aa83b363be7c..6ecea650673b 100644 --- a/litmus/litmus_softirq.c +++ b/litmus/litmus_softirq.c | |||
@@ -263,14 +263,17 @@ static int become_litmus_daemon(struct task_struct* tsk) | |||
263 | int ret = 0; | 263 | int ret = 0; |
264 | 264 | ||
265 | struct rt_task tp = { | 265 | struct rt_task tp = { |
266 | .exec_cost = KLMIRQD_SLICE_NS, | ||
266 | .period = KLMIRQD_SLICE_NS, | 267 | .period = KLMIRQD_SLICE_NS, |
267 | .relative_deadline = KLMIRQD_SLICE_NS, | 268 | .relative_deadline = KLMIRQD_SLICE_NS, |
268 | .exec_cost = KLMIRQD_SLICE_NS, | ||
269 | .phase = 0, | 269 | .phase = 0, |
270 | .cpu = task_cpu(current), | 270 | .cpu = task_cpu(current), |
271 | .priority = LITMUS_LOWEST_PRIORITY, | ||
272 | .cls = RT_CLASS_BEST_EFFORT, | ||
271 | .budget_policy = NO_ENFORCEMENT, | 273 | .budget_policy = NO_ENFORCEMENT, |
272 | .budget_signal_policy = NO_SIGNALS, | 274 | .budget_signal_policy = NO_SIGNALS, |
273 | .cls = RT_CLASS_BEST_EFFORT | 275 | /* use SPORADIC instead of EARLY since util = 1.0 */ |
276 | .release_policy = SPORADIC, | ||
274 | }; | 277 | }; |
275 | 278 | ||
276 | struct sched_param param = { .sched_priority = 0}; | 279 | struct sched_param param = { .sched_priority = 0}; |
diff --git a/litmus/sched_cedf.c b/litmus/sched_cedf.c index efb11bb8c656..78ae5a080138 100644 --- a/litmus/sched_cedf.c +++ b/litmus/sched_cedf.c | |||
@@ -315,7 +315,7 @@ static noinline void requeue(struct task_struct* task) | |||
315 | /* sanity check before insertion */ | 315 | /* sanity check before insertion */ |
316 | BUG_ON(is_queued(task)); | 316 | BUG_ON(is_queued(task)); |
317 | 317 | ||
318 | if (is_released(task, litmus_clock())) | 318 | if (is_early_releasing(task) || is_released(task, litmus_clock())) { |
319 | #ifdef CONFIG_REALTIME_AUX_TASKS | 319 | #ifdef CONFIG_REALTIME_AUX_TASKS |
320 | if (unlikely(tsk_rt(task)->is_aux_task && task->state != TASK_RUNNING && !tsk_rt(task)->aux_ready)) { | 320 | if (unlikely(tsk_rt(task)->is_aux_task && task->state != TASK_RUNNING && !tsk_rt(task)->aux_ready)) { |
321 | /* aux_task probably transitioned to real-time while it was blocked */ | 321 | /* aux_task probably transitioned to real-time while it was blocked */ |
@@ -325,6 +325,7 @@ static noinline void requeue(struct task_struct* task) | |||
325 | else | 325 | else |
326 | #endif | 326 | #endif |
327 | __add_ready(&cluster->domain, task); | 327 | __add_ready(&cluster->domain, task); |
328 | } | ||
328 | else { | 329 | else { |
329 | TRACE_TASK(task, "not requeueing non-yet-released job\n"); | 330 | TRACE_TASK(task, "not requeueing non-yet-released job\n"); |
330 | } | 331 | } |
@@ -411,24 +412,22 @@ static void cedf_release_jobs(rt_domain_t* rt, struct bheap* tasks) | |||
411 | /* caller holds cluster_lock */ | 412 | /* caller holds cluster_lock */ |
412 | static noinline void job_completion(struct task_struct *t, int forced) | 413 | static noinline void job_completion(struct task_struct *t, int forced) |
413 | { | 414 | { |
415 | int do_release = 0; | ||
414 | lt_t now; | 416 | lt_t now; |
415 | BUG_ON(!t); | 417 | BUG_ON(!t); |
416 | 418 | ||
417 | sched_trace_task_completion(t, forced); | 419 | sched_trace_task_completion(t, forced); |
418 | 420 | ||
419 | TRACE_TASK(t, "job_completion() at %llu.\n", litmus_clock()); | 421 | now = litmus_clock(); |
420 | 422 | TRACE_TASK(t, "job_completion() at %llu.\n", now); | |
421 | #ifdef CONFIG_LITMUS_LOCKING | ||
422 | BUG_ON(!is_persistent(t) && tsk_rt(t)->inh_task); | ||
423 | #endif | ||
424 | 423 | ||
425 | /* set flags */ | 424 | /* set flags */ |
426 | tsk_rt(t)->completed = 1; | 425 | tsk_rt(t)->completed = 1; |
427 | /* prepare for next period */ | 426 | /* prepare for next period */ |
428 | prepare_for_next_period(t); | 427 | prepare_for_next_period(t); |
429 | 428 | ||
430 | now = litmus_clock(); | 429 | do_release = (is_early_releasing(t) || is_released(t, now)); |
431 | if (is_released(t, now)) { | 430 | if (do_release) { |
432 | /* log here to capture overheads */ | 431 | /* log here to capture overheads */ |
433 | sched_trace_task_release(t); | 432 | sched_trace_task_release(t); |
434 | } | 433 | } |
@@ -438,7 +437,7 @@ static noinline void job_completion(struct task_struct *t, int forced) | |||
438 | /* release or arm next job */ | 437 | /* release or arm next job */ |
439 | tsk_rt(t)->completed = 0; | 438 | tsk_rt(t)->completed = 0; |
440 | if (is_running(t)) { | 439 | if (is_running(t)) { |
441 | if (!is_released(t, now)) | 440 | if (!do_release) |
442 | add_release(&task_cpu_cluster(t)->domain, t); | 441 | add_release(&task_cpu_cluster(t)->domain, t); |
443 | else | 442 | else |
444 | cedf_job_arrival(t); | 443 | cedf_job_arrival(t); |
@@ -1027,17 +1026,16 @@ static void cedf_task_wake_up(struct task_struct *task) | |||
1027 | { | 1026 | { |
1028 | unsigned long flags; | 1027 | unsigned long flags; |
1029 | cedf_domain_t *cluster; | 1028 | cedf_domain_t *cluster; |
1030 | lt_t now = litmus_clock(); | 1029 | lt_t now; |
1031 | |||
1032 | TRACE_TASK(task, "wake_up at %llu\n", now); | ||
1033 | 1030 | ||
1034 | cluster = task_cpu_cluster(task); | 1031 | cluster = task_cpu_cluster(task); |
1035 | 1032 | ||
1036 | raw_spin_lock_irqsave(&cluster->cluster_lock, flags); | 1033 | raw_spin_lock_irqsave(&cluster->cluster_lock, flags); |
1037 | 1034 | ||
1038 | if (unlikely(is_persistent(task) && is_tardy(task, now))) { | 1035 | now = litmus_clock(); |
1039 | /* treat tardy perisistent tasks as if they were sporadic | 1036 | TRACE_TASK(task, "wake_up at %llu\n", now); |
1040 | tasks by releasing a new job if they're tardy. */ | 1037 | |
1038 | if (is_sporadic(task) && is_tardy(task, now)) { | ||
1041 | release_at(task, now); | 1039 | release_at(task, now); |
1042 | sched_trace_task_release(task); | 1040 | sched_trace_task_release(task); |
1043 | } | 1041 | } |
@@ -1150,7 +1148,8 @@ static long cedf_admit_task(struct task_struct* tsk) | |||
1150 | edf_max_heap_base_priority_order); | 1148 | edf_max_heap_base_priority_order); |
1151 | #endif | 1149 | #endif |
1152 | 1150 | ||
1153 | return (task_cpu(tsk) == tsk->rt_param.task_params.cpu) ? 0 : -EINVAL; | 1151 | return (remote_cluster(task_cpu(tsk)) == task_cpu_cluster(tsk)) ? |
1152 | 0 : -EINVAL; | ||
1154 | } | 1153 | } |
1155 | 1154 | ||
1156 | 1155 | ||
diff --git a/litmus/sched_gsn_edf.c b/litmus/sched_gsn_edf.c index 46a10fa17044..08cdf5c0e492 100644 --- a/litmus/sched_gsn_edf.c +++ b/litmus/sched_gsn_edf.c | |||
@@ -308,7 +308,7 @@ static noinline void requeue(struct task_struct* task) | |||
308 | /* sanity check before insertion */ | 308 | /* sanity check before insertion */ |
309 | BUG_ON(is_queued(task)); | 309 | BUG_ON(is_queued(task)); |
310 | 310 | ||
311 | if (is_released(task, litmus_clock())) { | 311 | if (is_early_releasing(task) || is_released(task, litmus_clock())) { |
312 | #ifdef CONFIG_REALTIME_AUX_TASKS | 312 | #ifdef CONFIG_REALTIME_AUX_TASKS |
313 | if (unlikely(tsk_rt(task)->is_aux_task && !is_running(task))) { | 313 | if (unlikely(tsk_rt(task)->is_aux_task && !is_running(task))) { |
314 | /* aux_task probably transitioned to real-time while it was blocked */ | 314 | /* aux_task probably transitioned to real-time while it was blocked */ |
@@ -411,8 +411,7 @@ static noinline void job_completion(struct task_struct *t, int forced) | |||
411 | tsk_rt(t)->completed = 1; | 411 | tsk_rt(t)->completed = 1; |
412 | /* prepare for next period */ | 412 | /* prepare for next period */ |
413 | prepare_for_next_period(t); | 413 | prepare_for_next_period(t); |
414 | 414 | if (is_early_releasing(t) || is_released(t, litmus_clock())) | |
415 | if (is_released(t, litmus_clock())) | ||
416 | sched_trace_task_release(t); | 415 | sched_trace_task_release(t); |
417 | /* unlink */ | 416 | /* unlink */ |
418 | unlink(t); | 417 | unlink(t); |
@@ -1008,7 +1007,7 @@ static void gsnedf_task_wake_up(struct task_struct *task) | |||
1008 | #if 0 | 1007 | #if 0 |
1009 | /* sporadic task model. will increment job numbers automatically */ | 1008 | /* sporadic task model. will increment job numbers automatically */ |
1010 | now = litmus_clock(); | 1009 | now = litmus_clock(); |
1011 | if (is_tardy(task, now)) { | 1010 | if (is_sporadic(task) && is_tardy(task, now)) { |
1012 | /* new sporadic release */ | 1011 | /* new sporadic release */ |
1013 | release_at(task, now); | 1012 | release_at(task, now); |
1014 | sched_trace_task_release(task); | 1013 | sched_trace_task_release(task); |
diff --git a/litmus/sched_pfair.c b/litmus/sched_pfair.c index 6a89b003306c..d5fb3a832adc 100644 --- a/litmus/sched_pfair.c +++ b/litmus/sched_pfair.c | |||
@@ -710,7 +710,7 @@ static void pfair_task_wake_up(struct task_struct *t) | |||
710 | */ | 710 | */ |
711 | requeue = tsk_rt(t)->flags == RT_F_REQUEUE; | 711 | requeue = tsk_rt(t)->flags == RT_F_REQUEUE; |
712 | now = litmus_clock(); | 712 | now = litmus_clock(); |
713 | if (lt_before(get_deadline(t), now)) { | 713 | if (is_tardy(t, now)) { |
714 | TRACE_TASK(t, "sporadic release!\n"); | 714 | TRACE_TASK(t, "sporadic release!\n"); |
715 | release_at(t, now); | 715 | release_at(t, now); |
716 | prepare_release(t, time2quanta(now, CEIL)); | 716 | prepare_release(t, time2quanta(now, CEIL)); |
diff --git a/litmus/sched_pfp.c b/litmus/sched_pfp.c index 56d5a61c25e4..6edec830f063 100644 --- a/litmus/sched_pfp.c +++ b/litmus/sched_pfp.c | |||
@@ -359,7 +359,7 @@ static void pfp_task_wake_up(struct task_struct *task) | |||
359 | BUG_ON(is_queued(task)); | 359 | BUG_ON(is_queued(task)); |
360 | #endif | 360 | #endif |
361 | now = litmus_clock(); | 361 | now = litmus_clock(); |
362 | if (is_tardy(task, now) | 362 | if (is_sporadic(task) && is_tardy(task, now) |
363 | #ifdef CONFIG_LITMUS_LOCKING | 363 | #ifdef CONFIG_LITMUS_LOCKING |
364 | /* We need to take suspensions because of semaphores into | 364 | /* We need to take suspensions because of semaphores into |
365 | * account! If a job resumes after being suspended due to acquiring | 365 | * account! If a job resumes after being suspended due to acquiring |
diff --git a/litmus/sched_psn_edf.c b/litmus/sched_psn_edf.c index fabff1be9bba..d1177cab152d 100644 --- a/litmus/sched_psn_edf.c +++ b/litmus/sched_psn_edf.c | |||
@@ -61,7 +61,7 @@ static void requeue(struct task_struct* t, rt_domain_t *edf) | |||
61 | TRACE_TASK(t, "requeue: !TASK_RUNNING\n"); | 61 | TRACE_TASK(t, "requeue: !TASK_RUNNING\n"); |
62 | 62 | ||
63 | tsk_rt(t)->completed = 0; | 63 | tsk_rt(t)->completed = 0; |
64 | if (is_released(t, litmus_clock())) | 64 | if (is_early_releasing(t) || is_released(t, litmus_clock())) |
65 | __add_ready(edf, t); | 65 | __add_ready(edf, t); |
66 | else | 66 | else |
67 | add_release(edf, t); /* it has got to wait */ | 67 | add_release(edf, t); /* it has got to wait */ |
@@ -335,7 +335,7 @@ static void psnedf_task_wake_up(struct task_struct *task) | |||
335 | raw_spin_lock_irqsave(&pedf->slock, flags); | 335 | raw_spin_lock_irqsave(&pedf->slock, flags); |
336 | BUG_ON(is_queued(task)); | 336 | BUG_ON(is_queued(task)); |
337 | now = litmus_clock(); | 337 | now = litmus_clock(); |
338 | if (is_tardy(task, now) | 338 | if (is_sporadic(task) && is_tardy(task, now) |
339 | #ifdef CONFIG_LITMUS_LOCKING | 339 | #ifdef CONFIG_LITMUS_LOCKING |
340 | /* We need to take suspensions because of semaphores into | 340 | /* We need to take suspensions because of semaphores into |
341 | * account! If a job resumes after being suspended due to acquiring | 341 | * account! If a job resumes after being suspended due to acquiring |
diff --git a/litmus/uncachedev.c b/litmus/uncachedev.c new file mode 100644 index 000000000000..06a6a7c17983 --- /dev/null +++ b/litmus/uncachedev.c | |||
@@ -0,0 +1,102 @@ | |||
1 | #include <linux/sched.h> | ||
2 | #include <linux/kernel.h> | ||
3 | #include <linux/mm.h> | ||
4 | #include <linux/fs.h> | ||
5 | #include <linux/errno.h> | ||
6 | #include <linux/highmem.h> | ||
7 | #include <asm/page.h> | ||
8 | #include <linux/miscdevice.h> | ||
9 | #include <linux/module.h> | ||
10 | |||
11 | #include <litmus/litmus.h> | ||
12 | |||
13 | /* device for allocating pages not cached by the CPU */ | ||
14 | |||
15 | #define UNCACHE_NAME "litmus/uncache" | ||
16 | |||
17 | void litmus_uncache_vm_open(struct vm_area_struct *vma) | ||
18 | { | ||
19 | } | ||
20 | |||
21 | void litmus_uncache_vm_close(struct vm_area_struct *vma) | ||
22 | { | ||
23 | } | ||
24 | |||
25 | int litmus_uncache_vm_fault(struct vm_area_struct* vma, | ||
26 | struct vm_fault* vmf) | ||
27 | { | ||
28 | /* modeled after SG DMA video4linux, but without DMA. */ | ||
29 | /* (see drivers/media/video/videobuf-dma-sg.c) */ | ||
30 | struct page *page; | ||
31 | |||
32 | page = alloc_page(GFP_USER); | ||
33 | if (!page) | ||
34 | return VM_FAULT_OOM; | ||
35 | |||
36 | clear_user_highpage(page, (unsigned long)vmf->virtual_address); | ||
37 | vmf->page = page; | ||
38 | |||
39 | return 0; | ||
40 | } | ||
41 | |||
42 | static struct vm_operations_struct litmus_uncache_vm_ops = { | ||
43 | .open = litmus_uncache_vm_open, | ||
44 | .close = litmus_uncache_vm_close, | ||
45 | .fault = litmus_uncache_vm_fault, | ||
46 | }; | ||
47 | |||
48 | static int litmus_uncache_mmap(struct file* filp, struct vm_area_struct* vma) | ||
49 | { | ||
50 | /* first make sure mapper knows what he's doing */ | ||
51 | |||
52 | /* you can only map the "first" page */ | ||
53 | if (vma->vm_pgoff != 0) | ||
54 | return -EINVAL; | ||
55 | |||
56 | /* you can't share it with anyone */ | ||
57 | if (vma->vm_flags & (VM_MAYSHARE | VM_SHARED)) | ||
58 | return -EINVAL; | ||
59 | |||
60 | /* cannot be expanded, and is not a "normal" page. */ | ||
61 | vma->vm_flags |= VM_DONTEXPAND; | ||
62 | |||
63 | /* noncached pages are not explicitly locked in memory (for now). */ | ||
64 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | ||
65 | |||
66 | vma->vm_ops = &litmus_uncache_vm_ops; | ||
67 | |||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | static struct file_operations litmus_uncache_fops = { | ||
72 | .owner = THIS_MODULE, | ||
73 | .mmap = litmus_uncache_mmap, | ||
74 | }; | ||
75 | |||
76 | static struct miscdevice litmus_uncache_dev = { | ||
77 | .name = UNCACHE_NAME, | ||
78 | .minor = MISC_DYNAMIC_MINOR, | ||
79 | .fops = &litmus_uncache_fops, | ||
80 | /* pages are not locked, so there is no reason why | ||
81 | anyone cannot allocate an uncache pages */ | ||
82 | .mode = (S_IRUGO | S_IWUGO), | ||
83 | }; | ||
84 | |||
85 | static int __init init_litmus_uncache_dev(void) | ||
86 | { | ||
87 | int err; | ||
88 | |||
89 | printk("Initializing LITMUS^RT uncache device.\n"); | ||
90 | err = misc_register(&litmus_uncache_dev); | ||
91 | if (err) | ||
92 | printk("Could not allocate %s device (%d).\n", UNCACHE_NAME, err); | ||
93 | return err; | ||
94 | } | ||
95 | |||
96 | static void __exit exit_litmus_uncache_dev(void) | ||
97 | { | ||
98 | misc_deregister(&litmus_uncache_dev); | ||
99 | } | ||
100 | |||
101 | module_init(init_litmus_uncache_dev); | ||
102 | module_exit(exit_litmus_uncache_dev); | ||