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 | ||
