aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--litmus/sched_psn_edf.c65
1 files changed, 41 insertions, 24 deletions
diff --git a/litmus/sched_psn_edf.c b/litmus/sched_psn_edf.c
index e50b27391d21..8148c9cb0c33 100644
--- a/litmus/sched_psn_edf.c
+++ b/litmus/sched_psn_edf.c
@@ -20,6 +20,9 @@
20#include <litmus/sched_plugin.h> 20#include <litmus/sched_plugin.h>
21#include <litmus/edf_common.h> 21#include <litmus/edf_common.h>
22 22
23#ifdef CONFIG_FMLP
24#include <litmus/prio_sem.h>
25#endif
23 26
24typedef struct { 27typedef struct {
25 rt_domain_t domain; 28 rt_domain_t domain;
@@ -307,9 +310,10 @@ static void psnedf_task_exit(struct task_struct * t)
307} 310}
308 311
309#ifdef CONFIG_FMLP 312#ifdef CONFIG_FMLP
310static long psnedf_pi_block(struct pi_semaphore *sem, 313static long psnedf_fmlp_pi_block(struct pi_semaphore *_sem,
311 struct task_struct *new_waiter) 314 struct task_struct *new_waiter)
312{ 315{
316 struct fmlp_semaphore *sem = to_fmlp(_sem);
313 psnedf_domain_t* pedf; 317 psnedf_domain_t* pedf;
314 rt_domain_t* edf; 318 rt_domain_t* edf;
315 struct task_struct* t; 319 struct task_struct* t;
@@ -317,7 +321,7 @@ static long psnedf_pi_block(struct pi_semaphore *sem,
317 321
318 BUG_ON(!new_waiter); 322 BUG_ON(!new_waiter);
319 323
320 if (edf_higher_prio(new_waiter, sem->hp.cpu_task[cpu])) { 324 if (edf_higher_prio(new_waiter, sem->pi.hp.cpu_task[cpu])) {
321 TRACE_TASK(new_waiter, " boosts priority\n"); 325 TRACE_TASK(new_waiter, " boosts priority\n");
322 pedf = task_pedf(new_waiter); 326 pedf = task_pedf(new_waiter);
323 edf = task_edf(new_waiter); 327 edf = task_edf(new_waiter);
@@ -326,11 +330,13 @@ static long psnedf_pi_block(struct pi_semaphore *sem,
326 raw_spin_lock(&pedf->slock); 330 raw_spin_lock(&pedf->slock);
327 331
328 /* store new highest-priority task */ 332 /* store new highest-priority task */
329 sem->hp.cpu_task[cpu] = new_waiter; 333 sem->pi.hp.cpu_task[cpu] = new_waiter;
330 if (sem->holder && 334 if (sem->holder &&
331 get_partition(sem->holder) == get_partition(new_waiter)) { 335 get_partition(sem->holder) == get_partition(new_waiter)) {
336
332 /* let holder inherit */ 337 /* let holder inherit */
333 sem->holder->rt_param.inh_task = new_waiter; 338 sem->holder->rt_param.eff_priority = new_waiter;
339
334 t = sem->holder; 340 t = sem->holder;
335 if (is_queued(t)) { 341 if (is_queued(t)) {
336 /* queued in domain*/ 342 /* queued in domain*/
@@ -354,21 +360,28 @@ static long psnedf_pi_block(struct pi_semaphore *sem,
354 return 0; 360 return 0;
355} 361}
356 362
357static long psnedf_inherit_priority(struct pi_semaphore *sem, 363static long psnedf_fmlp_inherit_priority(struct pi_semaphore *_sem,
358 struct task_struct *new_owner) 364 struct task_struct *new_owner)
359{ 365{
366 struct fmlp_semaphore *sem = to_fmlp(_sem);
360 int cpu = get_partition(new_owner); 367 int cpu = get_partition(new_owner);
361 368
362 new_owner->rt_param.inh_task = sem->hp.cpu_task[cpu]; 369 if (sem->pi.hp.cpu_task[cpu] && new_owner != sem->pi.hp.cpu_task[cpu]) {
363 if (sem->hp.cpu_task[cpu] && new_owner != sem->hp.cpu_task[cpu]) { 370 new_owner->rt_param.eff_priority = sem->pi.hp.cpu_task[cpu];
364 TRACE_TASK(new_owner, 371 TRACE_TASK(new_owner,
365 "inherited priority from %s/%d\n", 372 "inherited priority from %s/%d\n",
366 sem->hp.cpu_task[cpu]->comm, 373 sem->pi.hp.cpu_task[cpu]->comm,
367 sem->hp.cpu_task[cpu]->pid); 374 sem->pi.hp.cpu_task[cpu]->pid);
368 } else 375 }
376 else
377 {
378 /* inherit "self" to remain consistent with pi_sem_stack model. */
379 new_owner->rt_param.eff_priority = new_owner;
369 TRACE_TASK(new_owner, 380 TRACE_TASK(new_owner,
370 "cannot inherit priority: " 381 "cannot inherit priority: "
371 "no higher priority job waits on this CPU!\n"); 382 "no higher priority job waits on this CPU!\n");
383 }
384
372 /* make new owner non-preemptable as required by FMLP under 385 /* make new owner non-preemptable as required by FMLP under
373 * PSN-EDF. 386 * PSN-EDF.
374 */ 387 */
@@ -380,8 +393,9 @@ static long psnedf_inherit_priority(struct pi_semaphore *sem,
380/* This function is called on a semaphore release, and assumes that 393/* This function is called on a semaphore release, and assumes that
381 * the current task is also the semaphore holder. 394 * the current task is also the semaphore holder.
382 */ 395 */
383static long psnedf_return_priority(struct pi_semaphore *sem) 396static long psnedf_fmlp_return_priority(struct pi_semaphore *_sem)
384{ 397{
398 struct fmlp_semaphore* sem = to_fmlp(_sem);
385 struct task_struct* t = current; 399 struct task_struct* t = current;
386 psnedf_domain_t* pedf = task_pedf(t); 400 psnedf_domain_t* pedf = task_pedf(t);
387 rt_domain_t* edf = task_edf(t); 401 rt_domain_t* edf = task_edf(t);
@@ -389,13 +403,12 @@ static long psnedf_return_priority(struct pi_semaphore *sem)
389 int cpu = get_partition(current); 403 int cpu = get_partition(current);
390 int still_np; 404 int still_np;
391 405
392
393 /* Find new highest-priority semaphore task 406 /* Find new highest-priority semaphore task
394 * if holder task is the current hp.cpu_task[cpu]. 407 * if holder task is the current hp.cpu_task[cpu].
395 * 408 *
396 * Calling function holds sem->wait.lock. 409 * Calling function holds sem->wait.lock.
397 */ 410 */
398 if (t == sem->hp.cpu_task[cpu]) 411 if (t == sem->pi.hp.cpu_task[cpu])
399 edf_set_hp_cpu_task(sem, cpu); 412 edf_set_hp_cpu_task(sem, cpu);
400 413
401 still_np = take_np(current); 414 still_np = take_np(current);
@@ -404,12 +417,16 @@ static long psnedf_return_priority(struct pi_semaphore *sem)
404 * should always be zero */ 417 * should always be zero */
405 BUG_ON(still_np); 418 BUG_ON(still_np);
406 419
407 if (current->rt_param.inh_task) { 420
421 if (current->rt_param.eff_priority &&
422 (current->rt_param.eff_priority != current)) {
408 TRACE_CUR("return priority of %s/%d\n", 423 TRACE_CUR("return priority of %s/%d\n",
409 current->rt_param.inh_task->comm, 424 current->rt_param.eff_priority->comm,
410 current->rt_param.inh_task->pid); 425 current->rt_param.eff_priority->pid);
411 } else 426 }
427 else {
412 TRACE_CUR(" no priority to return %p\n", sem); 428 TRACE_CUR(" no priority to return %p\n", sem);
429 }
413 430
414 431
415 /* Always check for delayed preemptions that might have become 432 /* Always check for delayed preemptions that might have become
@@ -417,8 +434,8 @@ static long psnedf_return_priority(struct pi_semaphore *sem)
417 */ 434 */
418 raw_spin_lock(&pedf->slock); 435 raw_spin_lock(&pedf->slock);
419 436
420 /* Reset inh_task to NULL. */ 437 /* Reset eff_priority to NULL since we don't hold the lock. */
421 current->rt_param.inh_task = NULL; 438 current->rt_param.eff_priority = NULL;
422 439
423 /* check if we need to reschedule */ 440 /* check if we need to reschedule */
424 if (edf_preemption_needed(edf, current)) 441 if (edf_preemption_needed(edf, current))
@@ -452,9 +469,9 @@ static struct sched_plugin psn_edf_plugin __cacheline_aligned_in_smp = {
452 .task_block = psnedf_task_block, 469 .task_block = psnedf_task_block,
453#ifdef CONFIG_FMLP 470#ifdef CONFIG_FMLP
454 .fmlp_active = 1, 471 .fmlp_active = 1,
455 .pi_block = psnedf_pi_block, 472 .fmlp_pi_block = psnedf_fmlp_pi_block,
456 .inherit_priority = psnedf_inherit_priority, 473 .fmlp_inherit_priority = psnedf_fmlp_inherit_priority,
457 .return_priority = psnedf_return_priority, 474 .fmlp_return_priority = psnedf_fmlp_return_priority,
458#endif 475#endif
459 .admit_task = psnedf_admit_task 476 .admit_task = psnedf_admit_task
460}; 477};