diff options
author | Guruprasad Aphale <gurua@cs.unc.edu> | 2010-09-19 13:15:05 -0400 |
---|---|---|
committer | Guruprasad Aphale <gurua@cs.unc.edu> | 2010-09-19 13:15:05 -0400 |
commit | 126e0fa95c0c7026ae2994e74ea72a48baa8e938 (patch) | |
tree | 36a3b0a5f3fd54541bb87ab47c93c6d6b41b8deb | |
parent | dcba0138a3fe593f9377cce45de473fca9f94084 (diff) |
Removed bug from edf-wm code
Updated the code to remove the condition that was causing soft-lockup
problem.
-rw-r--r-- | litmus/jobs.c | 5 | ||||
-rw-r--r-- | litmus/sched_edf_wm.c | 58 |
2 files changed, 44 insertions, 19 deletions
diff --git a/litmus/jobs.c b/litmus/jobs.c index 92ba04bea1b2..4eed6e04fe0e 100644 --- a/litmus/jobs.c +++ b/litmus/jobs.c | |||
@@ -13,9 +13,10 @@ void prepare_for_next_period(struct task_struct *t) | |||
13 | t->rt_param.job_params.release = t->rt_param.job_params.deadline; | 13 | t->rt_param.job_params.release = t->rt_param.job_params.deadline; |
14 | t->rt_param.job_params.deadline += get_rt_period(t); | 14 | t->rt_param.job_params.deadline += get_rt_period(t); |
15 | t->rt_param.job_params.exec_time = 0; | 15 | t->rt_param.job_params.exec_time = 0; |
16 | t->rt_param.job_params.exec_time_curr_cpu = 0; | ||
16 | /* update job sequence number */ | 17 | /* update job sequence number */ |
17 | t->rt_param.job_params.job_no++; | 18 | t->rt_param.job_params.job_no++; |
18 | 19 | t->rt_param.job_params.execs[0] = t->rt_param.task_params.exec_cost; | |
19 | /* don't confuse Linux */ | 20 | /* don't confuse Linux */ |
20 | t->rt.time_slice = 1; | 21 | t->rt.time_slice = 1; |
21 | } | 22 | } |
@@ -66,8 +67,8 @@ long complete_job(void) | |||
66 | 67 | ||
67 | void prepare_next_slice(struct task_struct *t, int new_release) | 68 | void prepare_next_slice(struct task_struct *t, int new_release) |
68 | { | 69 | { |
70 | int i; | ||
69 | BUG_ON(!t); | 71 | BUG_ON(!t); |
70 | int i=0; | ||
71 | 72 | ||
72 | if(t->rt_param.job_params.job_no == 0){ | 73 | if(t->rt_param.job_params.job_no == 0){ |
73 | /* This is the first job of this task. Update all parameters such as release time, deadline for each slice. */ | 74 | /* This is the first job of this task. Update all parameters such as release time, deadline for each slice. */ |
diff --git a/litmus/sched_edf_wm.c b/litmus/sched_edf_wm.c index 9ce0ebd97af5..64447f50f6ae 100644 --- a/litmus/sched_edf_wm.c +++ b/litmus/sched_edf_wm.c | |||
@@ -52,6 +52,7 @@ DEFINE_PER_CPU(edfwm_domain_t, edfwm_domains); | |||
52 | 52 | ||
53 | static enum hrtimer_restart on_release_timer(struct hrtimer *timer) | 53 | static enum hrtimer_restart on_release_timer(struct hrtimer *timer) |
54 | { | 54 | { |
55 | TRACE("calling scheduler_tick() after timer expiry, %llu \n", litmus_clock()); | ||
55 | scheduler_tick(); | 56 | scheduler_tick(); |
56 | return HRTIMER_NORESTART; | 57 | return HRTIMER_NORESTART; |
57 | } | 58 | } |
@@ -162,15 +163,26 @@ static int edfwm_check_resched(rt_domain_t *edf) | |||
162 | static int job_completion(struct task_struct* t,int forced) | 163 | static int job_completion(struct task_struct* t,int forced) |
163 | { | 164 | { |
164 | lt_t now; | 165 | lt_t now; |
166 | int t_flag=0; | ||
167 | edfwm_domain_t *edfwm = local_edfwm; | ||
168 | |||
165 | sched_trace_task_completion(t,forced); | 169 | sched_trace_task_completion(t,forced); |
166 | TRACE_TASK(t, "job_completion().\n"); | 170 | TRACE_TASK(t, "job_completion().\n"); |
167 | now = litmus_clock(); | 171 | now = litmus_clock(); |
172 | |||
173 | if(edfwm->timer_flag == 1){ | ||
174 | hrtimer_try_to_cancel(&edfwm->timer); | ||
175 | } | ||
176 | |||
168 | if(is_tardy(t,now)){ | 177 | if(is_tardy(t,now)){ |
169 | TRACE_TASK(t,"became tardy\n"); | 178 | TRACE_TASK(t,"became tardy\n"); |
179 | t_flag=1; | ||
170 | if(t->rt_param.task_params.curr == t->rt_param.task_params.count -1 ) | 180 | if(t->rt_param.task_params.curr == t->rt_param.task_params.count -1 ) |
171 | TRACE_TASK(t,"Task deadline, %llu, finished on %llu, Deadline miss for the job\n",t->rt_param.job_params.deadline,now); | 181 | TRACE_TASK(t,"Task deadline, %llu, finished on %llu, Deadline miss for the job\n",t->rt_param.job_params.deadline,now); |
172 | else | 182 | else |
173 | TRACE_TASK(t,"Task deadline, %llu, finished on %llu, Deadline miss for the subjob: %d\n",t->rt_param.job_params.deadline,now,t->rt_param.task_params.curr); | 183 | TRACE_TASK(t,"Task deadline, %llu, finished on %llu, Deadline miss for the subjob: %d\n",t->rt_param.job_params.deadline,now,t->rt_param.task_params.curr); |
184 | //release_at(t, now); | ||
185 | |||
174 | } | 186 | } |
175 | set_rt_flags(t, RT_F_SLEEP); | 187 | set_rt_flags(t, RT_F_SLEEP); |
176 | 188 | ||
@@ -186,9 +198,12 @@ static int job_completion(struct task_struct* t,int forced) | |||
186 | else{ | 198 | else{ |
187 | 199 | ||
188 | t->rt_param.job_params.exec_time = 0; | 200 | t->rt_param.job_params.exec_time = 0; |
201 | if(t_flag == 1) | ||
202 | t->rt_param.job_params.deadline = litmus_clock(); | ||
189 | prepare_for_next_period(t); | 203 | prepare_for_next_period(t); |
190 | return 0; | 204 | return 2; |
191 | } | 205 | } |
206 | return 0; | ||
192 | } | 207 | } |
193 | 208 | ||
194 | 209 | ||
@@ -199,7 +214,7 @@ static void edfwm_tick(struct task_struct *t) | |||
199 | lt_t now, exec_time, exec_cost; | 214 | lt_t now, exec_time, exec_cost; |
200 | int curr,count=1; | 215 | int curr,count=1; |
201 | int flag = 1; | 216 | int flag = 1; |
202 | int block = edfwm->block; | 217 | //int block = edfwm->block; |
203 | BUG_ON(!t); | 218 | BUG_ON(!t); |
204 | BUG_ON(is_realtime(t) && t != edfwm->scheduled); | 219 | BUG_ON(is_realtime(t) && t != edfwm->scheduled); |
205 | 220 | ||
@@ -223,10 +238,11 @@ static void edfwm_tick(struct task_struct *t) | |||
223 | 238 | ||
224 | if (is_realtime(t) && flag) { | 239 | if (is_realtime(t) && flag) { |
225 | 240 | ||
226 | if(count > 1){ | 241 | /* if(count > 1) |
242 | { | ||
227 | TRACE_TASK(t,"edfwm tick: trying to stop timer (0x%p); end: %llu , at %llu\n",&edfwm->timer,edfwm->end_timer, litmus_clock()); | 243 | TRACE_TASK(t,"edfwm tick: trying to stop timer (0x%p); end: %llu , at %llu\n",&edfwm->timer,edfwm->end_timer, litmus_clock()); |
228 | hrtimer_try_to_cancel(&edfwm->timer); | 244 | hrtimer_try_to_cancel(&edfwm->timer); |
229 | } | 245 | }*/ |
230 | if (!is_np(t)) { | 246 | if (!is_np(t)) { |
231 | set_tsk_need_resched(t); | 247 | set_tsk_need_resched(t); |
232 | TRACE("edfwm_scheduler_tick: " | 248 | TRACE("edfwm_scheduler_tick: " |
@@ -240,14 +256,16 @@ static void edfwm_tick(struct task_struct *t) | |||
240 | } | 256 | } |
241 | } | 257 | } |
242 | now = litmus_clock(); | 258 | now = litmus_clock(); |
243 | if(block != 1 && count > 1 && flag ==0 && edfwm->end_timer <= now && t->state == TASK_RUNNING){ | 259 | /* if(count>1){ |
260 | if(block != 1 && count > 1 && flag ==0 && edfwm->end_timer <= now && t->state == TASK_RUNNING){ | ||
244 | edfwm->end_timer = now + t->rt_param.job_params.execs[t->rt_param.task_params.curr] - t->rt_param.job_params.exec_time_curr_cpu; | 261 | edfwm->end_timer = now + t->rt_param.job_params.execs[t->rt_param.task_params.curr] - t->rt_param.job_params.exec_time_curr_cpu; |
245 | if(edfwm->end_timer - now > 1000){ | 262 | if(edfwm->end_timer - now > 1000 && !edfwm->timer_flag){ |
246 | __hrtimer_start_range_ns(&edfwm->timer,ns_to_ktime(edfwm->end_timer),0,HRTIMER_MODE_ABS_PINNED,0); | 263 | __hrtimer_start_range_ns(&edfwm->timer,ns_to_ktime(edfwm->end_timer),0,HRTIMER_MODE_ABS_PINNED,0); |
247 | edfwm->timer_flag = 1; | 264 | edfwm->timer_flag = 1; |
248 | TRACE_TASK(t,"edfwm tick: timer (0x%p) started at : %llu, should go off at %llu \n",&edfwm->timer,now,edfwm->end_timer); | 265 | TRACE_TASK(t,"edfwm tick: timer (0x%p) started at : %llu, should go off at %llu \n",&edfwm->timer,now,edfwm->end_timer); |
249 | } | 266 | } |
250 | } | 267 | } |
268 | }*/ | ||
251 | } | 269 | } |
252 | 270 | ||
253 | 271 | ||
@@ -274,11 +292,11 @@ static struct task_struct* edfwm_schedule(struct task_struct * prev) | |||
274 | * edfwm->schedule may be null and prev _is_ realtime | 292 | * edfwm->schedule may be null and prev _is_ realtime |
275 | */ | 293 | */ |
276 | 294 | ||
277 | /*if(edfwm->scheduled && edfwm->scheduled != prev){ | 295 | if(edfwm->scheduled && edfwm->scheduled != prev){ |
278 | edfwm->scheduled = NULL; | 296 | edfwm->scheduled = NULL; |
279 | spin_unlock(&edfwm->slock); | 297 | raw_spin_unlock(&edfwm->slock); |
280 | return NULL; | 298 | return NULL; |
281 | }*/ | 299 | } |
282 | 300 | ||
283 | BUG_ON(edfwm->scheduled && edfwm->scheduled != prev); | 301 | BUG_ON(edfwm->scheduled && edfwm->scheduled != prev); |
284 | BUG_ON(edfwm->scheduled && !is_realtime(prev)); | 302 | BUG_ON(edfwm->scheduled && !is_realtime(prev)); |
@@ -337,6 +355,7 @@ static struct task_struct* edfwm_schedule(struct task_struct * prev) | |||
337 | * budget or wants to sleep completes. We may have to reschedule after | 355 | * budget or wants to sleep completes. We may have to reschedule after |
338 | * this. | 356 | * this. |
339 | */ | 357 | */ |
358 | // TRACE_TASK(edfwm->scheduled, "out of time: %d, sleep: %d, NP: %d, !blocks: %d\n",out_of_time, sleep, np, !blocks); | ||
340 | if (!np && (out_of_time || sleep) && !blocks) { | 359 | if (!np && (out_of_time || sleep) && !blocks) { |
341 | 360 | ||
342 | TRACE_TASK(edfwm->scheduled,"NP: %d, out_of_time: %d, sleep: %d,blocks: %d\n",np,out_of_time,sleep,blocks); | 361 | TRACE_TASK(edfwm->scheduled,"NP: %d, out_of_time: %d, sleep: %d,blocks: %d\n",np,out_of_time,sleep,blocks); |
@@ -364,7 +383,7 @@ static struct task_struct* edfwm_schedule(struct task_struct * prev) | |||
364 | remove(edf,edfwm->scheduled); | 383 | remove(edf,edfwm->scheduled); |
365 | 384 | ||
366 | if (edfwm->scheduled && !blocks && !complete && smp_processor_id() == edfwm->scheduled->rt_param.task_params.cpu){ | 385 | if (edfwm->scheduled && !blocks && !complete && smp_processor_id() == edfwm->scheduled->rt_param.task_params.cpu){ |
367 | TRACE_TASK(edfwm->scheduled," task requeued on %d\n",smp_processor_id()); | 386 | TRACE_TASK(edfwm->scheduled," task kept on %d(same cpu)\n",smp_processor_id()); |
368 | requeue(edfwm->scheduled, edf,edfwm); | 387 | requeue(edfwm->scheduled, edf,edfwm); |
369 | } | 388 | } |
370 | 389 | ||
@@ -375,6 +394,7 @@ static struct task_struct* edfwm_schedule(struct task_struct * prev) | |||
375 | if(complete) | 394 | if(complete) |
376 | { | 395 | { |
377 | edf1 = task_edf(edfwm->scheduled); | 396 | edf1 = task_edf(edfwm->scheduled); |
397 | TRACE_TASK(edfwm->scheduled," task requeued on %d\n",smp_processor_id()); | ||
378 | requeue(edfwm->scheduled,edf1,edfwm); | 398 | requeue(edfwm->scheduled,edf1,edfwm); |
379 | } | 399 | } |
380 | 400 | ||
@@ -391,18 +411,22 @@ static struct task_struct* edfwm_schedule(struct task_struct * prev) | |||
391 | next = prev; | 411 | next = prev; |
392 | 412 | ||
393 | if (next) { | 413 | if (next) { |
394 | 414 | now = litmus_clock(); | |
395 | TRACE_TASK(next, "edfwm scheduled at %llu\n", litmus_clock()); | 415 | TRACE_TASK(next, "edfwm scheduled at %llu\n", litmus_clock()); |
416 | TRACE_TASK(next, "resched: %d, exists: %d, NP: %d, out of time: %d, sleep: %d, complete: %d, !blocks: %d\n",resched, exists,np,out_of_time, sleep, complete, !blocks); | ||
396 | set_rt_flags(next, RT_F_RUNNING); | 417 | set_rt_flags(next, RT_F_RUNNING); |
397 | 418 | ||
398 | if(next->rt_param.task_params.count > 1){ | 419 | // if(next->rt_param.task_params.count > 1) |
399 | if((out_of_time || sleep) && complete && !blocks){ | 420 | { |
400 | now = litmus_clock(); | 421 | if(((out_of_time || sleep) && complete && !blocks) || next->rt_param.job_params.job_no==2){ |
401 | edfwm->end_timer = now + next->rt_param.job_params.execs[next->rt_param.task_params.curr]; | 422 | edfwm->end_timer = now + next->rt_param.job_params.execs[next->rt_param.task_params.curr]; |
402 | if(edfwm->end_timer - now > 1000){ | 423 | if(edfwm->end_timer - now < 100) |
424 | edfwm->end_timer = now + 100; | ||
425 | // if(edfwm->end_timer - now > 100 && !edfwm->timer_flag){ | ||
426 | if(!edfwm->timer_flag){ | ||
403 | __hrtimer_start_range_ns(&edfwm->timer,ns_to_ktime(edfwm->end_timer),0,HRTIMER_MODE_ABS_PINNED,0); | 427 | __hrtimer_start_range_ns(&edfwm->timer,ns_to_ktime(edfwm->end_timer),0,HRTIMER_MODE_ABS_PINNED,0); |
404 | edfwm->timer_flag = 1; | 428 | edfwm->timer_flag = 1; |
405 | TRACE_TASK(next,"edfwm schedule: timer(0x%p) started at : %llu, should go off at %llu \n",&edfwm->timer,now,edfwm->end_timer); | 429 | TRACE_TASK(next,"edfwm schedule: timer(0x%p) started at : %llu, should go off at %llu , diff= %llu, required exec: %llu\n",&edfwm->timer,now,edfwm->end_timer,edfwm->end_timer-now, next->rt_param.job_params.execs[next->rt_param.task_params.curr]); |
406 | } | 430 | } |
407 | } | 431 | } |
408 | } | 432 | } |
@@ -546,7 +570,7 @@ static void edfwm_task_block(struct task_struct *t) | |||
546 | TRACE_TASK(t, "block at %llu, state=%d\n", litmus_clock(), t->state); | 570 | TRACE_TASK(t, "block at %llu, state=%d\n", litmus_clock(), t->state); |
547 | 571 | ||
548 | BUG_ON(!is_realtime(t)); | 572 | BUG_ON(!is_realtime(t)); |
549 | BUG_ON(is_queued(t)); | 573 | //BUG_ON(is_queued(t)); |
550 | } | 574 | } |
551 | 575 | ||
552 | static void edfwm_task_exit(struct task_struct * t) | 576 | static void edfwm_task_exit(struct task_struct * t) |