diff options
| author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:39:40 -0500 |
|---|---|---|
| committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:39:40 -0500 |
| commit | ea53c912f8a86a8567697115b6a0d8152beee5c8 (patch) | |
| tree | dd5ebfd653be7ad4d31e4226c8ffbeabcfaa33a6 | |
| parent | 53c37bbcc07707f88312efca136aa239f25d775c (diff) | |
Prepare k-FMLP for integration with Linux 3.0
Also added k-fmlp support to CEDF.
| -rw-r--r-- | litmus/sched_cedf.c | 603 | ||||
| -rw-r--r-- | litmus/sched_gsn_edf.c | 36 |
2 files changed, 590 insertions, 49 deletions
diff --git a/litmus/sched_cedf.c b/litmus/sched_cedf.c index 73fe1c442a0d..5e977dd2fef0 100644 --- a/litmus/sched_cedf.c +++ b/litmus/sched_cedf.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <linux/percpu.h> | 29 | #include <linux/percpu.h> |
| 30 | #include <linux/sched.h> | 30 | #include <linux/sched.h> |
| 31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
| 32 | #include <linux/uaccess.h> | ||
| 32 | 33 | ||
| 33 | #include <linux/module.h> | 34 | #include <linux/module.h> |
| 34 | 35 | ||
| @@ -45,7 +46,6 @@ | |||
| 45 | 46 | ||
| 46 | /* to configure the cluster size */ | 47 | /* to configure the cluster size */ |
| 47 | #include <litmus/litmus_proc.h> | 48 | #include <litmus/litmus_proc.h> |
| 48 | #include <linux/uaccess.h> | ||
| 49 | 49 | ||
| 50 | /* Reference configuration variable. Determines which cache level is used to | 50 | /* Reference configuration variable. Determines which cache level is used to |
| 51 | * group CPUs into clusters. GLOBAL_CLUSTER, which is the default, means that | 51 | * group CPUs into clusters. GLOBAL_CLUSTER, which is the default, means that |
| @@ -95,7 +95,7 @@ typedef struct clusterdomain { | |||
| 95 | struct bheap_node *heap_node; | 95 | struct bheap_node *heap_node; |
| 96 | struct bheap cpu_heap; | 96 | struct bheap cpu_heap; |
| 97 | /* lock for this cluster */ | 97 | /* lock for this cluster */ |
| 98 | #define lock domain.ready_lock | 98 | #define cedf_lock domain.ready_lock |
| 99 | } cedf_domain_t; | 99 | } cedf_domain_t; |
| 100 | 100 | ||
| 101 | /* a cedf_domain per cluster; allocation is done at init/activation time */ | 101 | /* a cedf_domain per cluster; allocation is done at init/activation time */ |
| @@ -292,12 +292,12 @@ static void cedf_release_jobs(rt_domain_t* rt, struct bheap* tasks) | |||
| 292 | cedf_domain_t* cluster = container_of(rt, cedf_domain_t, domain); | 292 | cedf_domain_t* cluster = container_of(rt, cedf_domain_t, domain); |
| 293 | unsigned long flags; | 293 | unsigned long flags; |
| 294 | 294 | ||
| 295 | raw_spin_lock_irqsave(&cluster->lock, flags); | 295 | raw_spin_lock_irqsave(&cluster->cedf_lock, flags); |
| 296 | 296 | ||
| 297 | __merge_ready(&cluster->domain, tasks); | 297 | __merge_ready(&cluster->domain, tasks); |
| 298 | check_for_preemptions(cluster); | 298 | check_for_preemptions(cluster); |
| 299 | 299 | ||
| 300 | raw_spin_unlock_irqrestore(&cluster->lock, flags); | 300 | raw_spin_unlock_irqrestore(&cluster->cedf_lock, flags); |
| 301 | } | 301 | } |
| 302 | 302 | ||
| 303 | /* caller holds cedf_lock */ | 303 | /* caller holds cedf_lock */ |
| @@ -378,7 +378,7 @@ static struct task_struct* cedf_schedule(struct task_struct * prev) | |||
| 378 | int out_of_time, sleep, preempt, np, exists, blocks; | 378 | int out_of_time, sleep, preempt, np, exists, blocks; |
| 379 | struct task_struct* next = NULL; | 379 | struct task_struct* next = NULL; |
| 380 | 380 | ||
| 381 | raw_spin_lock(&cluster->lock); | 381 | raw_spin_lock(&cluster->cedf_lock); |
| 382 | clear_will_schedule(); | 382 | clear_will_schedule(); |
| 383 | 383 | ||
| 384 | /* sanity checking */ | 384 | /* sanity checking */ |
| @@ -462,7 +462,7 @@ static struct task_struct* cedf_schedule(struct task_struct * prev) | |||
| 462 | next = prev; | 462 | next = prev; |
| 463 | 463 | ||
| 464 | sched_state_task_picked(); | 464 | sched_state_task_picked(); |
| 465 | raw_spin_unlock(&cluster->lock); | 465 | raw_spin_unlock(&cluster->cedf_lock); |
| 466 | 466 | ||
| 467 | #ifdef WANT_ALL_SCHED_EVENTS | 467 | #ifdef WANT_ALL_SCHED_EVENTS |
| 468 | TRACE("cedf_lock released, next=0x%p\n", next); | 468 | TRACE("cedf_lock released, next=0x%p\n", next); |
| @@ -504,7 +504,7 @@ static void cedf_task_new(struct task_struct * t, int on_rq, int running) | |||
| 504 | /* the cluster doesn't change even if t is running */ | 504 | /* the cluster doesn't change even if t is running */ |
| 505 | cluster = task_cpu_cluster(t); | 505 | cluster = task_cpu_cluster(t); |
| 506 | 506 | ||
| 507 | raw_spin_lock_irqsave(&cluster->domain.ready_lock, flags); | 507 | raw_spin_lock_irqsave(&cluster->cedf_lock, flags); |
| 508 | 508 | ||
| 509 | /* setup job params */ | 509 | /* setup job params */ |
| 510 | release_at(t, litmus_clock()); | 510 | release_at(t, litmus_clock()); |
| @@ -521,7 +521,7 @@ static void cedf_task_new(struct task_struct * t, int on_rq, int running) | |||
| 521 | t->rt_param.linked_on = NO_CPU; | 521 | t->rt_param.linked_on = NO_CPU; |
| 522 | 522 | ||
| 523 | cedf_job_arrival(t); | 523 | cedf_job_arrival(t); |
| 524 | raw_spin_unlock_irqrestore(&(cluster->domain.ready_lock), flags); | 524 | raw_spin_unlock_irqrestore(&(cluster->cedf_lock), flags); |
| 525 | } | 525 | } |
| 526 | 526 | ||
| 527 | static void cedf_task_wake_up(struct task_struct *task) | 527 | static void cedf_task_wake_up(struct task_struct *task) |
| @@ -534,7 +534,7 @@ static void cedf_task_wake_up(struct task_struct *task) | |||
| 534 | 534 | ||
| 535 | cluster = task_cpu_cluster(task); | 535 | cluster = task_cpu_cluster(task); |
| 536 | 536 | ||
| 537 | raw_spin_lock_irqsave(&cluster->lock, flags); | 537 | raw_spin_lock_irqsave(&cluster->cedf_lock, flags); |
| 538 | /* We need to take suspensions because of semaphores into | 538 | /* We need to take suspensions because of semaphores into |
| 539 | * account! If a job resumes after being suspended due to acquiring | 539 | * account! If a job resumes after being suspended due to acquiring |
| 540 | * a semaphore, it should never be treated as a new job release. | 540 | * a semaphore, it should never be treated as a new job release. |
| @@ -557,7 +557,7 @@ static void cedf_task_wake_up(struct task_struct *task) | |||
| 557 | } | 557 | } |
| 558 | } | 558 | } |
| 559 | cedf_job_arrival(task); | 559 | cedf_job_arrival(task); |
| 560 | raw_spin_unlock_irqrestore(&cluster->lock, flags); | 560 | raw_spin_unlock_irqrestore(&cluster->cedf_lock, flags); |
| 561 | } | 561 | } |
| 562 | 562 | ||
| 563 | static void cedf_task_block(struct task_struct *t) | 563 | static void cedf_task_block(struct task_struct *t) |
| @@ -570,9 +570,9 @@ static void cedf_task_block(struct task_struct *t) | |||
| 570 | cluster = task_cpu_cluster(t); | 570 | cluster = task_cpu_cluster(t); |
| 571 | 571 | ||
| 572 | /* unlink if necessary */ | 572 | /* unlink if necessary */ |
| 573 | raw_spin_lock_irqsave(&cluster->lock, flags); | 573 | raw_spin_lock_irqsave(&cluster->cedf_lock, flags); |
| 574 | unlink(t); | 574 | unlink(t); |
| 575 | raw_spin_unlock_irqrestore(&cluster->lock, flags); | 575 | raw_spin_unlock_irqrestore(&cluster->cedf_lock, flags); |
| 576 | 576 | ||
| 577 | BUG_ON(!is_realtime(t)); | 577 | BUG_ON(!is_realtime(t)); |
| 578 | } | 578 | } |
| @@ -584,7 +584,7 @@ static void cedf_task_exit(struct task_struct * t) | |||
| 584 | cedf_domain_t *cluster = task_cpu_cluster(t); | 584 | cedf_domain_t *cluster = task_cpu_cluster(t); |
| 585 | 585 | ||
| 586 | /* unlink if necessary */ | 586 | /* unlink if necessary */ |
| 587 | raw_spin_lock_irqsave(&cluster->lock, flags); | 587 | raw_spin_lock_irqsave(&cluster->cedf_lock, flags); |
| 588 | unlink(t); | 588 | unlink(t); |
| 589 | if (tsk_rt(t)->scheduled_on != NO_CPU) { | 589 | if (tsk_rt(t)->scheduled_on != NO_CPU) { |
| 590 | cpu_entry_t *cpu; | 590 | cpu_entry_t *cpu; |
| @@ -592,7 +592,7 @@ static void cedf_task_exit(struct task_struct * t) | |||
| 592 | cpu->scheduled = NULL; | 592 | cpu->scheduled = NULL; |
| 593 | tsk_rt(t)->scheduled_on = NO_CPU; | 593 | tsk_rt(t)->scheduled_on = NO_CPU; |
| 594 | } | 594 | } |
| 595 | raw_spin_unlock_irqrestore(&cluster->lock, flags); | 595 | raw_spin_unlock_irqrestore(&cluster->cedf_lock, flags); |
| 596 | 596 | ||
| 597 | BUG_ON(!is_realtime(t)); | 597 | BUG_ON(!is_realtime(t)); |
| 598 | TRACE_TASK(t, "RIP\n"); | 598 | TRACE_TASK(t, "RIP\n"); |
| @@ -603,6 +603,578 @@ static long cedf_admit_task(struct task_struct* tsk) | |||
| 603 | return task_cpu(tsk) == tsk->rt_param.task_params.cpu ? 0 : -EINVAL; | 603 | return task_cpu(tsk) == tsk->rt_param.task_params.cpu ? 0 : -EINVAL; |
| 604 | } | 604 | } |
| 605 | 605 | ||
| 606 | |||
| 607 | |||
| 608 | |||
| 609 | |||
| 610 | |||
| 611 | |||
| 612 | |||
| 613 | |||
| 614 | |||
| 615 | |||
| 616 | |||
| 617 | |||
| 618 | #ifdef CONFIG_LITMUS_LOCKING | ||
| 619 | |||
| 620 | #include <litmus/fdso.h> | ||
| 621 | |||
| 622 | |||
| 623 | static void __set_priority_inheritance(struct task_struct* t, struct task_struct* prio_inh) | ||
| 624 | { | ||
| 625 | int linked_on; | ||
| 626 | int check_preempt = 0; | ||
| 627 | |||
| 628 | cedf_domain_t* cluster = task_cpu_cluster(t); | ||
| 629 | |||
| 630 | if(prio_inh != NULL) | ||
| 631 | TRACE_TASK(t, "inherits priority from %s/%d\n", prio_inh->comm, prio_inh->pid); | ||
| 632 | else | ||
| 633 | TRACE_TASK(t, "inherits priority from %p\n", prio_inh); | ||
| 634 | |||
| 635 | //sched_trace_eff_prio_change(t, prio_inh); | ||
| 636 | |||
| 637 | tsk_rt(t)->inh_task = prio_inh; | ||
| 638 | |||
| 639 | linked_on = tsk_rt(t)->linked_on; | ||
| 640 | |||
| 641 | /* If it is scheduled, then we need to reorder the CPU heap. */ | ||
| 642 | if (linked_on != NO_CPU) { | ||
| 643 | TRACE_TASK(t, "%s: linked on %d\n", | ||
| 644 | __FUNCTION__, linked_on); | ||
