From 5ae786cd5fcaf1ec30f98dbf3a3e546f5f2cb9eb Mon Sep 17 00:00:00 2001 From: Nicola Manica Date: Mon, 6 Jul 2009 12:29:57 +0200 Subject: [PATCH] Now it works. BUG: check the accounting time --- kernel/sched.c | 4 +- kernel/sched_cbs.c | 183 +++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 131 insertions(+), 56 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index ba73d1e0..05c3501e 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1987,7 +1987,6 @@ static void activate_task(struct rq *rq, struct task_struct *p, int wakeup) { if (task_contributes_to_load(p)) rq->nr_uninterruptible--; - enqueue_task(rq, p, wakeup); inc_nr_running(rq); } @@ -2002,6 +2001,7 @@ static void deactivate_task(struct rq *rq, struct task_struct *p, int sleep) dequeue_task(rq, p, sleep); dec_nr_running(rq); + } /** @@ -6348,7 +6348,7 @@ recheck: if (policy == SCHED_CBS) { /* FIXME: Move to __setscheduler()? */ p->cbs_se.period = timespec_to_ns(&(param->sched_ss_repl_period)); p->cbs_se.max_budget = timespec_to_ns(¶m->sched_ss_init_budget); - p->cbs_se.budget = 0; + p->cbs_se.budget = p->cbs_se.max_budget; //now=cbs_rq_of(task_cbs_rq(p))->clock; p->cbs_se.deadline = 0; diff --git a/kernel/sched_cbs.c b/kernel/sched_cbs.c index e643b835..109abdd9 100644 --- a/kernel/sched_cbs.c +++ b/kernel/sched_cbs.c @@ -66,9 +66,14 @@ static inline u64 min_dl(u64 min_dl, u64 dl) return min_dl; } +static void +account_cbs_entity_dequeue(struct cbs_rq *cbs_rq, struct sched_cbs_entity *se); + +static void +account_cbs_entity_enqueue(struct cbs_rq *cbs_rq, struct sched_cbs_entity *se); -static inline void deadline_postpone(struct sched_cbs_entity *cbs_se); +static inline void deadline_postpone(struct sched_cbs_entity *cbs_se,u64 now); static void __enqueue_cbs_entity(struct cbs_rq *cbs_rq, struct sched_cbs_entity *se); @@ -78,12 +83,28 @@ static void enqueue_task_cbs(struct rq *rq, struct task_struct *p, int wakeup); static void cbs_deadline(struct sched_cbs_entity *se) { struct cbs_rq *cbs_rq=cbs_cbs_rq_of(se); - //printk("cbs_deadline! %p %p\n",cbs_rq, se); - deadline_postpone(se); - if (se != cbs_rq->curr){ - enqueue_task_cbs(cbs_rq_of(cbs_rq), cbs_task_of(se),0); + printk("cbs_deadline! %p %p %lld\n",cbs_rq,se, se->budget); + //deadline_postpone(se); + //se->budget=se->max_budget; + //if (se != cbs_rq->curr){ + //if (se->budget < 0) { + //deadline_postpone(se); + //set_current_state(TASK_RUNNING); + //se->state=TASK_RUNNING; + //printk("cbs_deadline->"); + while (se->budget<0) + se->budget+=se->max_budget; + + __enqueue_cbs_entity(cbs_rq, se); + //printk("Incremento i task runnanti in cbs_deadline\n"); + cbs_rq->nr_running++; + + //account_cbs_entity_enqueue(cbs_rq,se); + + se->on_rq=1; + //wake_up_process(cbs_task_of(se)); resched_task(cbs_task_of(se)); - } + //} //printk("cbs_deadline! %p %p\n",cbs_rq, se); }; @@ -117,9 +138,19 @@ static enum hrtimer_restart cbs_end_deadline(struct hrtimer *timer) static void init_cbs_timer(struct sched_cbs_entity *cbs_se){ //printk("init_cbs_timer %p\n",cbs_se); + struct cbs_rq *cbs_rq = cbs_cbs_rq_of(cbs_se); hrtimer_init(&cbs_se->cbs_deadline_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); cbs_se->cbs_deadline_timer.function = cbs_end_deadline; cbs_se->cbs_deadline_timer.irqsafe = 1; + static int warn; + + if (!hrtick_enabled(cbs_rq_of(cbs_rq))) { + if (!warn) { + warn = 1; + printk("Warning HRTICKs disabled!\n"); + } + //return; + } //printk("init_cbs_timer end %p\n",cbs_se); } @@ -130,6 +161,7 @@ static void start_cbs_timer(struct sched_cbs_entity *cbs_se) //printk("start_cbs_timer %p\n",cbs_se); u64 now; struct cbs_rq *cbs_rq = cbs_cbs_rq_of(cbs_se); + //ktime_t now; /* if (!rt_bandwidth_enabled() || rt_b->rt_runtime == RUNTIME_INF) @@ -142,8 +174,11 @@ static void start_cbs_timer(struct sched_cbs_entity *cbs_se) if (hrtimer_active(&cbs_se->cbs_deadline_timer)) return; - - spin_lock(&cbs_se->cbs_sleeptime_lock); + deadline_postpone(cbs_se,now); + + + WARN_ON(now>cbs_se->deadline); + //spin_lock(&cbs_se->cbs_sleeptime_lock); for (;;) { ktime_t hard; @@ -156,31 +191,33 @@ static void start_cbs_timer(struct sched_cbs_entity *cbs_se) // cbs_se->deadline=now+cbs_se->period; //printk("DEAD setted to set=%llu",(unsigned long long)cbs_se->deadline); //printk(" PERIOD %llu\n",(unsigned long long)cbs_se->period); + printk("At time %llu I set the new deadline %llu\n",now,cbs_se->deadline); //printk("Dati: %llu %llu %p\n",now,cbs_se->period, cbs_se); - printk("Timer settato a %llu\n",cbs_se->deadline-cbs_se->period); + //printk("Timer settato a %llu\n",cbs_se->deadline); // hrtimer_forward(&cbs_se->cbs_deadline_timer, now, ns_to_ktime(cbs_se->period)); //soft = hrtimer_get_softexpires(&cbs_se->cbs_deadline_timer); //hard = hrtimer_get_expires(&cbs_se->cbs_deadline_timer); //delta = ktime_to_ns(ktime_sub(hard, soft)); - hard=ns_to_ktime(cbs_se->deadline-cbs_se->period); - //__hrtimer_start_range_ns(&cbs_se->cbs_deadline_timer, soft, delta, HRTIMER_MODE_ABS, 0); - hrtimer_start(&cbs_se->cbs_deadline_timer, hard, HRTIMER_MODE_ABS); + hard=ns_to_ktime(cbs_se->deadline); + __hrtimer_start_range_ns(&cbs_se->cbs_deadline_timer, hard, 0, HRTIMER_MODE_ABS, 0); + //hrtimer_start(&cbs_se->cbs_deadline_timer, hard, HRTIMER_MODE_ABS); } - spin_unlock(&cbs_se->cbs_sleeptime_lock); + //spin_unlock(&cbs_se->cbs_sleeptime_lock); //printk("start_cbs_timer end%p\n",cbs_se); } -static inline void deadline_postpone(struct sched_cbs_entity *cbs_se) +static inline void deadline_postpone(struct sched_cbs_entity *cbs_se,u64 now) { //printk("deadline_postpone %p\n",cbs_se); - while (cbs_se->budget <= 0) { + //while (cbs_se->budget < 0) { + while (cbs_se->deadlinedeadline += cbs_se->period; - cbs_se->budget += cbs_se->max_budget; - } + //cbs_se->budget += cbs_se->max_budget; + //} //printk("deadline_postpone end %p\n",cbs_se); @@ -234,7 +271,8 @@ static void __enqueue_cbs_entity(struct cbs_rq *cbs_rq, struct sched_cbs_entity cbs_rq->min_deadline = max_dl(cbs_rq->min_deadline, se->deadline); } - + //printk("Prima di inserire il nodo %p %p %p\n",&se->run_node,parent,link); + BUG_ON(parent!=NULL); rb_link_node(&se->run_node, parent, link); rb_insert_color(&se->run_node, &cbs_rq->tasks_timeline); //printk("__enqueue_cbs_entity end %p %p\n",cbs_rq,se); @@ -272,6 +310,8 @@ static inline struct rb_node *earliest_deadline(struct cbs_rq *cbs_rq) static struct sched_cbs_entity *__pick_next_cbs_entity(struct cbs_rq *cbs_rq) { + //printk("Entro in pick_next_cbs_entity con %ld\n",cbs_rq->nr_running); + //printk("Ritorno l'entity cbs %p\n",rb_entry(earliest_deadline(cbs_rq), struct sched_cbs_entity, run_node)); return rb_entry(earliest_deadline(cbs_rq), struct sched_cbs_entity, run_node); } @@ -284,27 +324,45 @@ __update_curr_cbs(struct cbs_rq *cbs_rq, struct sched_cbs_entity *curr, unsigned long delta_exec) { //printk("__update_curr_cbs %p %p\n",cbs_rq,curr); - + //ktime_t t; + //struct task_struct *p=cbs_task_of(curr); //schedstat_set(curr->exec_max, max((u64)delta_exec, curr->exec_max)); // curr->sum_exec_runtime += delta_exec; //schedstat_add(cbs_rq, exec_clock, delta_exec); curr->budget -= delta_exec; - + //printk("budget del task %p is %lld\n",curr,curr->budget); /**Soft CBS: If budget < 0 recharge buffer and postpone deadline**/ /**Hard CBS: If budget < 0 start a timer until the deadline**/ #ifdef CBS_SOFT BUG_ON(cbs_rq->curr<=0); #endif - if (curr->budget <= 0) + if (curr->budget < 0) { - //printk("budget terminato per il task %p\n",curr); - deadline_postpone(curr); + printk("Budget ended for task %p\n",curr); + //deadline_postpone(curr); #ifndef CBS_SOFT - start_cbs_timer(curr); + start_cbs_timer(curr); +#else + deadline_postpone(curr); #endif - - //resched_task(cbs_task_of(curr)); + //printk("Provo a dormire %ld %d\n",cbs_rq->nr_running,curr->on_rq); + //sleeping_task = current; + //set_current_state(TASK_UNINTERRUPTIBLE); + //printk("Decremento i task runnanti in __update_curr_cbs\n"); + cbs_rq->nr_running--; + curr->on_rq=0; + + //account_cbs_entity_dequeue(cbs_rq,curr); + //schedule(); + + //rb_erase(&curr->run_node, &cbs_rq->tasks_timeline); + //p->state=TASK_UNINTERRUPTIBLE; + //t=ns_to_ktime(curr->deadline); + //schedule_hrtimeout(&t,HRTIMER_MODE_ABS); + //curr->on_rq = 0; + //printk("Current: %i\n",curr->on_rq); + resched_task(cbs_task_of(curr)); } //printk("__update_curr_cbs end %p %p\n",cbs_rq,curr); @@ -313,11 +371,11 @@ __update_curr_cbs(struct cbs_rq *cbs_rq, struct sched_cbs_entity *curr, static void update_curr_cbs(struct cbs_rq *cbs_rq) { //printk("update_curr_cbs %p\n",cbs_rq); - //printk("cbs_rq %p\n",cbs_rq); struct sched_cbs_entity *curr = cbs_rq->curr; u64 now = cbs_rq_of(cbs_rq)->clock; unsigned long delta_exec; + //BUG_ON(curr->on_rq==0); if (unlikely(!curr)) return; @@ -362,7 +420,7 @@ static void account_cbs_entity_enqueue(struct cbs_rq *cbs_rq, struct sched_cbs_entity *se) { //printk("account_cbs_entity_enqueue %p %p\n",cbs_rq,se); - + //printk("Incremento i task runnanti in account_cbs_entity_enqueue\n"); cbs_rq->nr_running++; se->on_rq = 1; //printk("account_cbs_entity_enqueue end %p %p\n",cbs_rq,se); @@ -372,6 +430,8 @@ account_cbs_entity_enqueue(struct cbs_rq *cbs_rq, struct sched_cbs_entity *se) static void account_cbs_entity_dequeue(struct cbs_rq *cbs_rq, struct sched_cbs_entity *se) { + //printk("Decremento i task runnanti in account_cbs_entity_dequeue\n"); + //printk("account_cbs_entity_dequeue %p %p\n",cbs_rq,se); BUG_ON(se->on_rq == 0); BUG_ON(cbs_rq->nr_running == 0); @@ -389,6 +449,7 @@ enqueue_cbs_entity(struct cbs_rq *cbs_rq, struct sched_cbs_entity *se) /* * Update run-time statistics of the 'current'. */ + //printk("from enqueue_cbs_entity\n"); update_curr_cbs(cbs_rq); account_cbs_entity_enqueue(cbs_rq, se); @@ -404,12 +465,10 @@ enqueue_cbs_entity(struct cbs_rq *cbs_rq, struct sched_cbs_entity *se) /**HARD: If budget < 0 does not enqueue the current task**/ /**SOFT: Enqueue the task beacuse budget can not be <= 0**/ //printk("Budget %lld\n",se->budget); -#ifdef CBS_SOFT - if (se != cbs_rq->curr) -#else - if ((se != cbs_rq->curr)&&(se->budget > 0)) -#endif + if ((se != cbs_rq->curr)&&(se->budget > 0)){ + //printk("Enqueue_cbs_entity->"); __enqueue_cbs_entity(cbs_rq, se); + } //printk("enqueue_cbs_entity end%p %p\n",cbs_rq,se); } @@ -420,11 +479,13 @@ dequeue_cbs_entity(struct cbs_rq *cbs_rq, struct sched_cbs_entity *se) /* * Update run-time statistics of the 'current'. */ - //printk("dequeue_cbs_entity %p\n",se); + //printk("from dequeue_cbs_entity\n"); update_curr_cbs(cbs_rq); - if (se != cbs_rq->curr) + if (se != cbs_rq->curr){ + //printk("dequeue_cbs_entity->"); __dequeue_cbs_entity(cbs_rq, se); + } account_cbs_entity_dequeue(cbs_rq, se); //printk("dequeue_cbs_entity end %p\n",se); @@ -435,6 +496,7 @@ set_next_cbs_entity(struct cbs_rq *cbs_rq, struct sched_cbs_entity *se) { /* 'current' is not kept within the tree. */ if (se->on_rq) { + //printk("set_next_cbs_entity->"); __dequeue_cbs_entity(cbs_rq, se); } @@ -460,7 +522,7 @@ static struct sched_cbs_entity *pick_next_cbs_entity(struct cbs_rq *cbs_rq) se = __pick_next_cbs_entity(cbs_rq); set_next_cbs_entity(cbs_rq, se); } - //printk("pick_next_cbs_entity end\n"); +// printk("pick_next_cbs_entity end %p\n",se); return se; } @@ -473,12 +535,16 @@ static void put_prev_cbs_entity(struct cbs_rq *cbs_rq, struct sched_cbs_entity * * If still on the runqueue then deactivate_task() * was not called and update_curr() has to be done: */ - if (prev->on_rq) + if (prev->on_rq) { + //printk("from put_prev_cbs_entity\n"); update_curr_cbs(cbs_rq); + } - if (prev->on_rq) { + if ((prev->on_rq)&&(prev->budget>0)) { /* Put 'current' back into the tree. */ + //printk("Put_prev_cbs_entity->"); __enqueue_cbs_entity(cbs_rq, prev); + //cbs_rq->nr_running++; } cbs_rq->curr = NULL; //printk("put_prev_cbs_entity end %p\n",prev); @@ -491,10 +557,12 @@ cbs_entity_tick(struct cbs_rq *cbs_rq, struct sched_cbs_entity *curr, int queued /* * Update run-time statistics of the 'current'. */ - update_curr_cbs(cbs_rq); + //printk("from cbs_entity_tick\n"); + if (curr->on_rq) + update_curr_cbs(cbs_rq); - if (cbs_rq->nr_running > 1) - resched_task(cbs_rq_of(cbs_rq)->curr); /* FIXME: Check! */ + //if (cbs_rq->nr_running > 1) + resched_task(cbs_rq_of(cbs_rq)->curr); /* FIXME: Check! */ } @@ -508,26 +576,32 @@ static void hrtick_start_cbs(struct rq *rq, struct task_struct *p) // int requeue = rq->curr == p; //printk("hrtick_start_cbs %p\n",p); struct sched_cbs_entity *se = &p->cbs_se; + //struct cbs_rq *cbs_rq = cbs_cbs_rq_of(se); s64 delta; WARN_ON(task_rq(p) != rq); - + BUG_ON(se->budget<=0); /*if (se->budget <= 0) { printk("budget terminato per il task %p\n",se); //se->budget=0; - deadline_postpone(se); - start_cbs_timer(se); - resched_task(p); + //deadline_postpone(se); + //start_cbs_timer(se); + //rq->curr=NULL; + if (rq->curr == p) + resched_task(p); + return; }*/ /* * Don't schedule timeouts shorter than 10000ns, that just * doesn't make sense. */ delta = max(10000LL, se->budget); - hrtick_start(rq, delta); - //printk("hrtick_start_cbs end%p\n",p); + //printk("hrtick start %p cn delta pari a %lld\n",p,delta); + hrtick_start(rq, delta); + //printk("hrtick_start_cbs end cn budget pari %lld\n",se->budget); + } #else static inline void @@ -555,7 +629,7 @@ static void enqueue_task_cbs(struct rq *rq, struct task_struct *p, int wakeup) enqueue_cbs_entity(cbs_rq, se); } - hrtick_start_cbs(rq, rq->curr); + //hrtick_start_cbs(rq, rq->curr); //printk("enqueue_task_cbs end%p\n",se); } @@ -578,7 +652,7 @@ static void dequeue_task_cbs(struct rq *rq, struct task_struct *p, int sleep) /* FIXME: Don't dequeue parent if it has other entities besides us */ } - hrtick_start_cbs(rq, rq->curr); + //hrtick_start_cbs(rq, rq->curr); //printk("dequeue_task_cbs end%p\n",se); } @@ -618,6 +692,7 @@ static void check_preempt_wakeup_cbs(struct rq *rq, struct task_struct *p,int sy if (unlikely(rt_prio(p->prio))) { update_rq_clock(rq); + //printk("from check_preempt_wakeup\n"); update_curr_cbs(cbs_rq); resched_task(curr); return; @@ -664,7 +739,7 @@ static struct task_struct *pick_next_task_cbs(struct rq *rq) struct task_struct *p; struct cbs_rq *cbs_rq = &rq->cbs; struct sched_cbs_entity *se; - //printk("pick_next_task_cbs %p\n",se); + //printk("pick_next_task_cbs %lu\n",cbs_rq->nr_running); if (unlikely(!cbs_rq->nr_running)) return NULL; @@ -718,9 +793,9 @@ static void task_new_cbs(struct rq *rq, struct task_struct *p) { //#warning Task New CBS is W R O N G ! ! ! struct cbs_rq *cbs_rq = task_cbs_rq(p); - //printk("task_new_cbs has been called!\n"); + //printk("from task_new_cbs \n"); sched_info_queued(p); - + update_curr_cbs(cbs_rq); //#ifndef CBS_SOFT init_cbs_timer(cbs_rq->curr); @@ -774,7 +849,7 @@ static const struct sched_class cbs_sched_class = { .dequeue_task = dequeue_task_cbs, .yield_task = yield_task_cbs, #ifdef CONFIG_SMP -//#error CBS SMP is still a No-No! +#error CBS SMP is still a No-No! .select_task_rq = , #endif /* CONFIG_SMP */ @@ -784,7 +859,7 @@ static const struct sched_class cbs_sched_class = { .put_prev_task = put_prev_task_cbs, #ifdef CONFIG_SMP -//#error CBS SMP is still a No-No! +#error CBS SMP is still a No-No! .load_balance = , .move_one_task = , #endif -- 2.11.4.GIT