From b53c479a0f44b8990ce106622412a3bf54809944 Mon Sep 17 00:00:00 2001 From: Glenn Elliott Date: Mon, 16 Jul 2012 20:20:52 -0400 Subject: New Feature: Arbitrary deadlines. Added support for arbitrary deadlines. Constraint: Relative deadline must be >= exec cost. Use: Set relative deadline in rt_task::rdeadline. Set value to 0 to default to implicit deadlines. Limitations: PFAIR not supported by this patch. PFAIR updated to reject tasks that do not have implicit deadlines. --- include/litmus/litmus.h | 13 +++++++++---- include/litmus/rt_param.h | 1 + litmus/jobs.c | 18 ++++++++++++------ litmus/litmus.c | 27 +++++++++++++++++---------- litmus/rt_domain.c | 8 +++++--- litmus/sched_pfair.c | 7 +++++++ 6 files changed, 51 insertions(+), 23 deletions(-) diff --git a/include/litmus/litmus.h b/include/litmus/litmus.h index aa56eeef7e7d..338245abd6ed 100644 --- a/include/litmus/litmus.h +++ b/include/litmus/litmus.h @@ -47,18 +47,23 @@ void litmus_exit_task(struct task_struct *tsk); /* Realtime utility macros */ #define get_rt_flags(t) (tsk_rt(t)->flags) #define set_rt_flags(t,f) (tsk_rt(t)->flags=(f)) +#define is_priority_boosted(t) (tsk_rt(t)->priority_boosted) +#define get_boost_start(t) (tsk_rt(t)->boost_start_time) + +/* task_params macros */ #define get_exec_cost(t) (tsk_rt(t)->task_params.exec_cost) -#define get_exec_time(t) (tsk_rt(t)->job_params.exec_time) #define get_rt_period(t) (tsk_rt(t)->task_params.period) +#define get_rt_relative_deadline(t) (tsk_rt(t)->task_params.relative_deadline) #define get_rt_phase(t) (tsk_rt(t)->task_params.phase) #define get_partition(t) (tsk_rt(t)->task_params.cpu) #define get_priority(t) (tsk_rt(t)->task_params.priority) +#define get_class(t) (tsk_rt(t)->task_params.cls) + +/* job_param macros */ +#define get_exec_time(t) (tsk_rt(t)->job_params.exec_time) #define get_deadline(t) (tsk_rt(t)->job_params.deadline) #define get_release(t) (tsk_rt(t)->job_params.release) -#define get_class(t) (tsk_rt(t)->task_params.cls) -#define is_priority_boosted(t) (tsk_rt(t)->priority_boosted) -#define get_boost_start(t) (tsk_rt(t)->boost_start_time) #define is_hrt(t) \ (tsk_rt(t)->task_params.cls == RT_CLASS_HARD) diff --git a/include/litmus/rt_param.h b/include/litmus/rt_param.h index c4669a276e6f..89ac0dda7d3d 100644 --- a/include/litmus/rt_param.h +++ b/include/litmus/rt_param.h @@ -56,6 +56,7 @@ typedef enum { struct rt_task { lt_t exec_cost; lt_t period; + lt_t relative_deadline; lt_t phase; unsigned int cpu; unsigned int priority; diff --git a/litmus/jobs.c b/litmus/jobs.c index 36e314625d86..bc8246572e54 100644 --- a/litmus/jobs.c +++ b/litmus/jobs.c @@ -6,13 +6,13 @@ #include #include -void prepare_for_next_period(struct task_struct *t) +static inline void setup_release(struct task_struct *t, lt_t release) { - BUG_ON(!t); /* prepare next release */ - t->rt_param.job_params.release = t->rt_param.job_params.deadline; - t->rt_param.job_params.deadline += get_rt_period(t); + t->rt_param.job_params.release = release; + t->rt_param.job_params.deadline = release + get_rt_relative_deadline(t); t->rt_param.job_params.exec_time = 0; + /* update job sequence number */ t->rt_param.job_params.job_no++; @@ -20,10 +20,16 @@ void prepare_for_next_period(struct task_struct *t) t->rt.time_slice = 1; } +void prepare_for_next_period(struct task_struct *t) +{ + BUG_ON(!t); + setup_release(t, get_release(t) + get_rt_period(t)); +} + void release_at(struct task_struct *t, lt_t start) { - t->rt_param.job_params.deadline = start; - prepare_for_next_period(t); + BUG_ON(!t); + setup_release(t, start); set_rt_flags(t, RT_F_RUNNING); } diff --git a/litmus/litmus.c b/litmus/litmus.c index 301390148d02..81384327e850 100644 --- a/litmus/litmus.c +++ b/litmus/litmus.c @@ -102,21 +102,25 @@ asmlinkage long sys_set_rt_task_param(pid_t pid, struct rt_task __user * param) goto out_unlock; } + /* set relative deadline to be implicit if left unspecified */ + if (tp.relative_deadline == 0) + tp.relative_deadline = tp.period; + if (tp.exec_cost <= 0) goto out_unlock; if (tp.period <= 0) goto out_unlock; if (!cpu_online(tp.cpu)) goto out_unlock; - if (tp.period < tp.exec_cost) + if (min(tp.relative_deadline, tp.period) < tp.exec_cost) /*density check*/ { printk(KERN_INFO "litmus: real-time task %d rejected " - "because wcet > period\n", pid); + "because task density > 1.0\n", pid); goto out_unlock; } - if ( tp.cls != RT_CLASS_HARD && - tp.cls != RT_CLASS_SOFT && - tp.cls != RT_CLASS_BEST_EFFORT) + if (tp.cls != RT_CLASS_HARD && + tp.cls != RT_CLASS_SOFT && + tp.cls != RT_CLASS_BEST_EFFORT) { printk(KERN_INFO "litmus: real-time task %d rejected " "because its class is invalid\n", pid); @@ -321,11 +325,14 @@ long litmus_admit_task(struct task_struct* tsk) BUG_ON(is_realtime(tsk)); - if (get_rt_period(tsk) == 0 || - get_exec_cost(tsk) > get_rt_period(tsk)) { - TRACE_TASK(tsk, "litmus admit: invalid task parameters " - "(%lu, %lu)\n", - get_exec_cost(tsk), get_rt_period(tsk)); + if (get_rt_relative_deadline(tsk) == 0 || + get_exec_cost(tsk) > + min(get_rt_relative_deadline(tsk), get_rt_period(tsk)) ) { + TRACE_TASK(tsk, + "litmus admit: invalid task parameters " + "(e = %lu, p = %lu, d = %lu)\n", + get_exec_cost(tsk), get_rt_period(tsk), + get_rt_relative_deadline(tsk)); retval = -EINVAL; goto out; } diff --git a/litmus/rt_domain.c b/litmus/rt_domain.c index d405854cd39c..d0b796611bea 100644 --- a/litmus/rt_domain.c +++ b/litmus/rt_domain.c @@ -300,9 +300,11 @@ void rt_domain_init(rt_domain_t *rt, */ void __add_ready(rt_domain_t* rt, struct task_struct *new) { - TRACE("rt: adding %s/%d (%llu, %llu) rel=%llu to ready queue at %llu\n", - new->comm, new->pid, get_exec_cost(new), get_rt_period(new), - get_release(new), litmus_clock()); + TRACE("rt: adding %s/%d (%llu, %llu, %llu) rel=%llu " + "to ready queue at %llu\n", + new->comm, new->pid, + get_exec_cost(new), get_rt_period(new), get_rt_relative_deadline(new), + get_release(new), litmus_clock()); BUG_ON(bheap_node_in_heap(tsk_rt(new)->heap_node)); diff --git a/litmus/sched_pfair.c b/litmus/sched_pfair.c index 16f1065bbdca..72c06a492ef9 100644 --- a/litmus/sched_pfair.c +++ b/litmus/sched_pfair.c @@ -850,6 +850,13 @@ static long pfair_admit_task(struct task_struct* t) cpu_cluster(pstate[task_cpu(t)])) return -EINVAL; + if (get_rt_period(t) != get_rt_relative_deadline(t)) { + printk(KERN_INFO "%s: Admission rejected. " + "Only implicit deadlines are currently supported.\n", + litmus->plugin_name); + return -EINVAL; + } + /* Pfair is a tick-based method, so the time * of interest is jiffies. Calculate tick-based * times for everything. -- cgit v1.2.2