diff options
author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2011-01-26 17:41:51 -0500 |
---|---|---|
committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2011-01-26 17:44:48 -0500 |
commit | f8db543cc4e96dc82e0bd249899321be44ec3427 (patch) | |
tree | 72c5f286364439587cad12675c30ec2fc44b457e | |
parent | 7be35bec55b1b6d6a2483e0ec3703a483da1e5a6 (diff) |
EDF-WM: rely on generic enforcement timer
Since LITMUS^RT 2010.2 has generic support for precise budget
enforcement, we don't need to implement it EDF-WM anymore.
-rw-r--r-- | litmus/sched_edf_wm.c | 97 |
1 files changed, 0 insertions, 97 deletions
diff --git a/litmus/sched_edf_wm.c b/litmus/sched_edf_wm.c index f4219ca812d3..8b7be32b40dd 100644 --- a/litmus/sched_edf_wm.c +++ b/litmus/sched_edf_wm.c | |||
@@ -18,10 +18,6 @@ typedef struct { | |||
18 | int cpu; | 18 | int cpu; |
19 | struct task_struct* scheduled; /* only RT tasks */ | 19 | struct task_struct* scheduled; /* only RT tasks */ |
20 | 20 | ||
21 | /* The enforcement timer is used to accurately police | ||
22 | * slice budgets. */ | ||
23 | struct hrtimer enforcement_timer; | ||
24 | int timer_armed; | ||
25 | /* | 21 | /* |
26 | * scheduling lock slock | 22 | * scheduling lock slock |
27 | * protects the domain and serializes scheduling decisions | 23 | * protects the domain and serializes scheduling decisions |
@@ -39,7 +35,6 @@ DEFINE_PER_CPU(wm_domain_t, wm_domains); | |||
39 | #define local_domain (&__get_cpu_var(wm_domains)) | 35 | #define local_domain (&__get_cpu_var(wm_domains)) |
40 | #define remote_domain(cpu) (&per_cpu(wm_domains, cpu)) | 36 | #define remote_domain(cpu) (&per_cpu(wm_domains, cpu)) |
41 | #define domain_of_task(task) (remote_domain(get_partition(task))) | 37 | #define domain_of_task(task) (remote_domain(get_partition(task))) |
42 | #define domain_from_timer(t) (container_of((t), wm_domain_t, enforcement_timer)) | ||
43 | 38 | ||
44 | static int is_sliced_task(struct task_struct* t) | 39 | static int is_sliced_task(struct task_struct* t) |
45 | { | 40 | { |
@@ -115,14 +110,6 @@ static lt_t slice_budget_remaining(struct task_struct* t) | |||
115 | return slice_budget(t) - slice_exec_time(t); | 110 | return slice_budget(t) - slice_exec_time(t); |
116 | } | 111 | } |
117 | 112 | ||
118 | static lt_t wm_budget_remaining(struct task_struct* t) | ||
119 | { | ||
120 | if (is_sliced_task(t)) | ||
121 | return slice_budget_remaining(t); | ||
122 | else | ||
123 | return budget_remaining(t); | ||
124 | } | ||
125 | |||
126 | static int wm_budget_exhausted(struct task_struct* t) | 113 | static int wm_budget_exhausted(struct task_struct* t) |
127 | { | 114 | { |
128 | if (is_sliced_task(t)) | 115 | if (is_sliced_task(t)) |
@@ -214,78 +201,6 @@ static void preempt(wm_domain_t *dom) | |||
214 | preempt_if_preemptable(NULL, dom->cpu); | 201 | preempt_if_preemptable(NULL, dom->cpu); |
215 | } | 202 | } |
216 | 203 | ||
217 | static enum hrtimer_restart on_enforcement_timeout(struct hrtimer *timer) | ||
218 | { | ||
219 | wm_domain_t *dom = domain_from_timer(timer); | ||
220 | unsigned long flags; | ||
221 | |||
222 | raw_spin_lock_irqsave(&dom->slock, flags); | ||
223 | if (likely(dom->timer_armed)) { | ||
224 | TRACE_DOM(dom, "enforcement timer fired.\n"); | ||
225 | dom->timer_armed = 0; | ||
226 | preempt(dom); | ||
227 | } else | ||
228 | TRACE_DOM(dom, "timer fired but not armed???\n"); | ||
229 | raw_spin_unlock_irqrestore(&dom->slock, flags); | ||
230 | return HRTIMER_NORESTART; | ||
231 | } | ||
232 | |||
233 | /* assumes called with IRQs off */ | ||
234 | static void cancel_enforcement_timer(wm_domain_t* dom) | ||
235 | { | ||
236 | int ret; | ||
237 | |||
238 | TRACE_DOM(dom, "cancelling enforcement timer.\n"); | ||
239 | |||
240 | /* Arming the timer makes only sense locally. */ | ||
241 | BUG_ON(dom->cpu != raw_smp_processor_id()); | ||
242 | |||
243 | /* Since interrupts are disabled and and dom->timer_armed is only | ||
244 | * modified locally, we do not need to lock this domain. | ||
245 | */ | ||
246 | |||
247 | if (dom->timer_armed) { | ||
248 | ret = hrtimer_try_to_cancel(&dom->enforcement_timer); | ||
249 | /* Should never be inactive. */ | ||
250 | BUG_ON(ret == 0); | ||
251 | /* Should never be running concurrently. */ | ||
252 | BUG_ON(ret == -1); | ||
253 | |||
254 | dom->timer_armed = 0; | ||
255 | } | ||
256 | } | ||
257 | |||
258 | /* assumes called with IRQs off */ | ||
259 | static void arm_enforcement_timer(wm_domain_t* dom, struct task_struct* t) | ||
260 | { | ||
261 | lt_t when_to_fire; | ||
262 | |||
263 | TRACE_DOM(dom, "arming enforcement timer.\n"); | ||
264 | |||
265 | /* The task has to belong to this domain. */ | ||
266 | BUG_ON(domain_of_task(t) != dom); | ||
267 | |||
268 | /* Arming the timer makes only sense locally. */ | ||
269 | BUG_ON(dom->cpu != raw_smp_processor_id()); | ||
270 | |||
271 | /* Calling this when there is no budget left for the task | ||
272 | * makes no sense. */ | ||
273 | BUG_ON(wm_budget_exhausted(t)); | ||
274 | |||
275 | /* __hrtimer_start_range_ns() cancels the timer | ||
276 | * anyway, so we don't have to check whether it is still armed | ||
277 | */ | ||
278 | |||
279 | when_to_fire = litmus_clock() + wm_budget_remaining(t); | ||
280 | __hrtimer_start_range_ns(&dom->enforcement_timer, | ||
281 | ns_to_ktime(when_to_fire), | ||
282 | 0 /* delta */, | ||
283 | HRTIMER_MODE_ABS_PINNED, | ||
284 | 0 /* no wakeup */); | ||
285 | |||
286 | dom->timer_armed = 1; | ||
287 | } | ||
288 | |||
289 | static void wm_domain_init(wm_domain_t* dom, | 204 | static void wm_domain_init(wm_domain_t* dom, |
290 | check_resched_needed_t check, | 205 | check_resched_needed_t check, |
291 | release_jobs_t release, | 206 | release_jobs_t release, |
@@ -294,9 +209,6 @@ static void wm_domain_init(wm_domain_t* dom, | |||
294 | edf_domain_init(&dom->domain, check, release); | 209 | edf_domain_init(&dom->domain, check, release); |
295 | dom->cpu = cpu; | 210 | dom->cpu = cpu; |
296 | dom->scheduled = NULL; | 211 | dom->scheduled = NULL; |
297 | dom->timer_armed = 0; | ||
298 | hrtimer_init(&dom->enforcement_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); | ||
299 | dom->enforcement_timer.function = on_enforcement_timeout; | ||
300 | } | 212 | } |
301 | 213 | ||
302 | static void wm_requeue_remote(struct task_struct *t) | 214 | static void wm_requeue_remote(struct task_struct *t) |
@@ -473,15 +385,6 @@ static struct task_struct* wm_schedule(struct task_struct * prev) | |||
473 | wm_requeue_remote(migrate); | 385 | wm_requeue_remote(migrate); |
474 | } | 386 | } |
475 | 387 | ||
476 | if (next && budget_precisely_enforced(next)) { | ||
477 | /* Make sure we call into the scheduler when this budget | ||
478 | * expires. */ | ||
479 | arm_enforcement_timer(dom, next); | ||
480 | } else if (dom->timer_armed) { | ||
481 | /* Make sure we don't cause unnecessary interrupts. */ | ||
482 | cancel_enforcement_timer(dom); | ||
483 | } | ||
484 | |||
485 | return next; | 388 | return next; |
486 | } | 389 | } |
487 | 390 | ||