From 84fe6787c0a251593d1ab5f311a203d114f9bf94 Mon Sep 17 00:00:00 2001 From: Namhoon Kim Date: Tue, 11 Apr 2017 00:17:56 -0400 Subject: Fix mode 0 overutilization bug --- include/litmus/sched_trace.h | 2 - include/trace/events/litmus.h | 8 ++++ litmus/cache_proc.c | 6 +-- litmus/jobs.c | 7 ++++ litmus/litmus.c | 2 +- litmus/mc2_common.c | 2 +- litmus/sched_mc2.c | 85 ++++++++++++++++++++++++------------------- litmus/sched_task_trace.c | 4 +- litmus/sync.c | 6 ++- 9 files changed, 74 insertions(+), 48 deletions(-) diff --git a/include/litmus/sched_trace.h b/include/litmus/sched_trace.h index c924716a0dbf..fb5d8f33aff5 100644 --- a/include/litmus/sched_trace.h +++ b/include/litmus/sched_trace.h @@ -96,7 +96,6 @@ typedef enum { * uninitialized records. */ ST_PARAM, ST_RELEASE, - ST_ASSIGNED, ST_SWITCH_TO, ST_SWITCH_AWAY, ST_COMPLETION, @@ -116,7 +115,6 @@ struct st_event_record { DATA(name); DATA(param); DATA(release); - DATA(assigned); DATA(switch_to); DATA(switch_away); DATA(completion); diff --git a/include/trace/events/litmus.h b/include/trace/events/litmus.h index fc89b23068b1..3094ddd2210b 100644 --- a/include/trace/events/litmus.h +++ b/include/trace/events/litmus.h @@ -235,10 +235,14 @@ TRACE_EVENT(litmus_enact_mode, TP_ARGS(t), TP_STRUCT__entry( + __field( pid_t, pid ) + __field( unsigned int, job ) __field( lt_t, when ) ), TP_fast_assign( + __entry->pid = t ? t->pid : 0; + __entry->job = t ? t->rt_param.job_params.job_no : 0; __entry->when = litmus_clock(); ), @@ -255,10 +259,14 @@ TRACE_EVENT(litmus_request_mode, TP_ARGS(t), TP_STRUCT__entry( + __field( pid_t, pid ) + __field( unsigned int, job ) __field( lt_t, when ) ), TP_fast_assign( + __entry->pid = t ? t->pid : 0; + __entry->job = t ? t->rt_param.job_params.job_no : 0; __entry->when = litmus_clock(); ), diff --git a/litmus/cache_proc.c b/litmus/cache_proc.c index 224ebef551fd..ddf3765834ea 100644 --- a/litmus/cache_proc.c +++ b/litmus/cache_proc.c @@ -1108,7 +1108,7 @@ out_free: return ret; } -void flush_cache(int all) +void flush_cache2(int all) { int way, color, cpu; unsigned long flags; @@ -1191,7 +1191,7 @@ asmlinkage long sys_run_test(int type, int size, cacheline_t *src, cacheline_t * v7_flush_kern_dcache_area(src, size*1024); } //preempt_enable(); - flush_cache(1); + //flush_cache(1); return ret; } @@ -1245,7 +1245,7 @@ asmlinkage long sys_run_test(int type, int size, cacheline_t *src, cacheline_t * v7_flush_kern_dcache_area(src, size*1024); } //preempt_enable(); - flush_cache(1); + //flush_cache(1); return ret; } diff --git a/litmus/jobs.c b/litmus/jobs.c index 0dd36b9343d6..f6614581dc25 100644 --- a/litmus/jobs.c +++ b/litmus/jobs.c @@ -8,6 +8,9 @@ #include #include +extern int num_sync_released; +int n_init_phase; + static inline void setup_release(struct task_struct *t, lt_t release) { /* prepare next release */ @@ -18,6 +21,7 @@ static inline void setup_release(struct task_struct *t, lt_t release) /* update job sequence number */ t->rt_param.job_params.job_no++; } +#define INIT_PHASE_LENGTH_NS (1000000000) void prepare_for_next_period(struct task_struct *t) { @@ -36,6 +40,9 @@ void prepare_for_next_period(struct task_struct *t) /* sporadic release */ setup_release(t, tsk_rt(t)->sporadic_release_time); tsk_rt(t)->sporadic_release = 0; + } else if (num_sync_released) { + TRACE_TASK(t, "num_sync_released = %d\n", num_sync_released); + setup_release(t, tsk_rt(t)->sporadic_release_time + INIT_PHASE_LENGTH_NS); } else { /* periodic release => add period */ setup_release(t, get_release(t) + get_rt_period(t)); diff --git a/litmus/litmus.c b/litmus/litmus.c index f9ad1f405518..4f7c6450b464 100644 --- a/litmus/litmus.c +++ b/litmus/litmus.c @@ -521,7 +521,7 @@ asmlinkage long sys_test_call(unsigned int param) } else if (param == 1) { int i; - flush_cache(1); + //flush_cache(1); for (i = 0; i < 4; i++) { lock_cache(i, 0x00003fff); } diff --git a/litmus/mc2_common.c b/litmus/mc2_common.c index 730f99bcab54..322cc6d18932 100644 --- a/litmus/mc2_common.c +++ b/litmus/mc2_common.c @@ -23,7 +23,7 @@ long mc2_task_client_init(struct task_client *tc, struct mc2_task *mc2_param, st (mc2_param->crit > CRIT_LEVEL_C)) return -EINVAL; - TRACE_TASK(tsk, "mc2_task_client_init: crit_level = %d\n", mc2_param->crit); + TRACE_TASK(tsk, "mc2_task_client_init: mode = %d, crit_level = %d\n", res->mode, mc2_param->crit); return 0; } diff --git a/litmus/sched_mc2.c b/litmus/sched_mc2.c index ec8a92440f2b..654380d0f104 100644 --- a/litmus/sched_mc2.c +++ b/litmus/sched_mc2.c @@ -38,6 +38,7 @@ #define BUDGET_ENFORCEMENT_AT_C 0 +extern int num_sync_released; extern void do_partition(enum crit_level lv, int cpu); /* _global_env - reservation container for level-C tasks*/ @@ -130,24 +131,25 @@ asmlinkage long sys_enact_mode(void) struct list_head *pos; unsigned long flags; //lt_t now = litmus_clock(); - TRACE_TASK(current, "ENACTING MODE TASK\n"); + TRACE_TASK(current, "ENACTING SYSCALL\n"); if (state->cpu == 0){ //preempt_disable(); mode_changed = false; local_irq_save(flags); - - raw_spin_lock(&global_lock); - raw_spin_lock(&mode_lock); if (pending){ //MCR has entered + raw_spin_lock(&state->lock); + raw_spin_lock(&global_lock); + raw_spin_lock(&mode_lock); + if (!seen_once){ - TRACE_TASK(current, "REQUEST = %llu\n", litmus_clock()); + TRACE_TASK(current, "REQUEST\n"); sched_trace_request_mode(current); - TS_MODE_CHANGE_START; + //TS_MODE_CHANGE_START; //clean up jobs that are already done //after this jobs report themselves list_for_each(pos, &_global_env->active_reservations){ res = list_entry(pos, struct reservation, list); - if (tsk_rt(res->tsk)->completed && res->mode == mode){ + if (tsk_rt(res->tsk)->completed && res->mode == mode && !res->reported){ res->reported = 1; TRACE_CUR("R%d RES_REPORTED_ACTIVE = %d mode %d\n", res->id, res_reported, res->mode); res_reported--; @@ -155,7 +157,7 @@ asmlinkage long sys_enact_mode(void) } list_for_each(pos, &_global_env->depleted_reservations){ res = list_entry(pos, struct reservation, list); - if (tsk_rt(res->tsk)->completed && res->mode == mode){ + if (tsk_rt(res->tsk)->completed && res->mode == mode && !res->reported){ res->reported = 1; TRACE_CUR("R%d RES_REPORTED_DEPLETED = %d mode %d\n",res->id, res_reported, res->mode); res_reported--; @@ -164,7 +166,7 @@ asmlinkage long sys_enact_mode(void) } list_for_each(pos, &_global_env->inactive_reservations){ res = list_entry(pos, struct reservation, list); - if (tsk_rt(res->tsk)->completed && res->mode == mode){ + if (tsk_rt(res->tsk)->completed && res->mode == mode && !res->reported){ res->reported = 1; //TRACE_CUR("R%d RES_REPORTED_INACTIVE = %d mode %d\n", res->id, res_reported, res->mode); res_reported--; @@ -174,7 +176,6 @@ asmlinkage long sys_enact_mode(void) } if( ready ){ //C is throttled lt_t new_mode_basetime = get_release(current); - lt_t t; //TRACE("Timer canceled\n"); hrtimer_cancel(&state->timer);//stop listening to old mode timers mode = requested_mode; @@ -213,17 +214,17 @@ asmlinkage long sys_enact_mode(void) res = list_entry(pos, struct reservation, list); release_at(res->tsk, new_mode_basetime); } + sup_update_time(state->sup_env, litmus_clock()); //raw_spin_unlock(&state->lock); - t=litmus_clock(); + //t=litmus_clock(); sched_trace_enact_mode(current); - TS_MODE_CHANGE_END; - TRACE(KERN_ALERT "ENACT = %llu\n", t); + //TS_MODE_CHANGE_END; + TRACE("ENACT\n"); } - - + raw_spin_unlock(&mode_lock); + raw_spin_unlock(&global_lock); + raw_spin_unlock(&state->lock); } - raw_spin_unlock(&mode_lock); - raw_spin_unlock(&global_lock); local_irq_restore(flags); cpu_0_spin_flag = !cpu_0_spin_flag; } @@ -243,13 +244,13 @@ asmlinkage long sys_enact_mode(void) udelay(1); } //TRACE("CPU%d flag check. %d\n",state->cpu, mode_changed); + local_irq_save(flags); if (mode_changed) { lt_t new_mode_basetime = get_release(current); //TRACE("CPU%d mode changed\n",state->cpu); hrtimer_cancel(&state->timer); //stop listening to old mode timers //preempt_disable(); - local_irq_save(flags); - + //local_irq_save(flags); raw_spin_lock(&state->lock); state->sup_env = &state->sup_env_modes[mode]; list_for_each(pos, &state->sup_env->active_reservations){ @@ -264,22 +265,23 @@ asmlinkage long sys_enact_mode(void) res = list_entry(pos, struct reservation, list); release_at(res->tsk, new_mode_basetime); } + sup_update_time(state->sup_env, litmus_clock()); raw_spin_unlock(&state->lock); - local_irq_restore(flags); + //local_irq_restore(flags); //preempt_enable(); } + local_irq_restore(flags); state->spin_flag = !state->spin_flag; } else { //TRACE("CPU%d no cpu_0_task_exist.%d\n",state->cpu, mode_changed); - local_irq_restore(flags); return 0; } - TRACE("CPU%d enact syscall ends m_c? %d\n",state->cpu, mode_changed); + TRACE("CPU%d enact syscall ends m_c? %d new_mode %d\n",state->cpu, mode_changed, mode); //if mode didn't change this has no effect on what's being scheduled //raw_spin_lock(&state->lock); - state->sup_env = &state->sup_env_modes[mode]; + //state->sup_env = &state->sup_env_modes[mode]; //raw_spin_unlock(&state->lock); //sup_update_time(state->sup_env, litmus_clock()); @@ -753,8 +755,9 @@ static enum hrtimer_restart on_scheduling_timer(struct hrtimer *timer) static long mc2_complete_job(void) { ktime_t next_release; + lt_t next_release_ns; long err; - + enum crit_level lv; raw_spin_lock(&mode_lock); @@ -767,12 +770,10 @@ static long mc2_complete_job(void) time to the next release time */ if (tsk_rt(current)->sporadic_release) { struct mc2_cpu_state *state; - //struct reservation_environment *env; struct mc2_task_state *tinfo; struct reservation *res = NULL; unsigned long flags; -// preempt_disable(); local_irq_save(flags); tinfo = get_mc2_state(current); @@ -804,7 +805,7 @@ static long mc2_complete_job(void) else BUG(); - /* set next_replenishtime to synchronous release time */ + /* set next_replenish to synchronous release time */ BUG_ON(!res); res->next_replenishment = tsk_rt(current)->sporadic_release_time; /* @@ -821,15 +822,11 @@ static long mc2_complete_job(void) // TRACE_CUR("CHANGE NEXT_REP = %llu NEXT_UPDATE = %llu\n", res->next_replenishment, state->sup_env->next_scheduler_update); - //if (lv < CRIT_LEVEL_C) -// raw_spin_unlock(&state->lock); - //else if (lv == CRIT_LEVEL_C) raw_spin_unlock(&global_lock); raw_spin_unlock(&state->lock); local_irq_restore(flags); -// preempt_enable(); } sched_trace_task_completion(current, 0); @@ -874,6 +871,7 @@ static long mc2_complete_job(void) /* sleep until next_release */ set_current_state(TASK_INTERRUPTIBLE); preempt_enable_no_resched(); + TRACE_CUR("Sleep until %llu\n", next_release); err = schedule_hrtimeout(&next_release, HRTIMER_MODE_ABS); } else { /* release the next job immediately */ @@ -900,6 +898,11 @@ struct task_struct* mc2_dispatch(struct sup_reservation_environment* sup_env, st enum crit_level lv; lt_t time_slice; + list_for_each_entry_safe(res, next, &sup_env->active_reservations, list) { + if (res->state == RESERVATION_ACTIVE) + TRACE_TASK(tsk, "ACT_LIST R%d mode = %d budget = %llu\n", res->id, res->mode, res->cur_budget); + } + list_for_each_entry_safe(res, next, &sup_env->active_reservations, list) { if (res->state == RESERVATION_ACTIVE) { tsk = res->ops->dispatch_client(res, &time_slice); @@ -1229,7 +1232,8 @@ static void mc2_task_resume(struct task_struct *tsk) if (tinfo->has_departed) { /* We don't want to consider jobs before synchronous releases */ - if (tsk_rt(tsk)->job_params.job_no > 3) { + if (tsk_rt(tsk)->job_params.job_no == 2) { +/* switch(get_task_crit_level(tsk)) { case CRIT_LEVEL_A: TS_RELEASE_LATENCY_A(get_release(tsk)); @@ -1243,8 +1247,12 @@ static void mc2_task_resume(struct task_struct *tsk) default: break; } +*/ // TRACE_CUR("INIT_FINISHED is SET\n"); tsk_mc2_data(tsk)->init_finished = 1; + raw_spin_lock(&global_lock); + num_sync_released--; + raw_spin_unlock(&global_lock); } raw_spin_lock(&state->lock); @@ -1434,7 +1442,7 @@ static long mc2_admit_task(struct task_struct *tsk) if (err) kfree(tinfo); - //TRACE_TASK(tsk, "MC2 task admitted %d\n", err); + TRACE_TASK(tsk, "MC2 task admitted %d\n", err); return err; } @@ -1489,8 +1497,6 @@ static void mc2_task_new(struct task_struct *tsk, int on_runqueue, //res = res_find_by_id(state, tinfo->mc2_param.res_id); BUG_ON(!res); - release = res->next_replenishment; - if (on_runqueue || is_running) { /* Assumption: litmus_clock() is synchronized across cores * [see comment in pres_task_resume()] */ @@ -1517,14 +1523,19 @@ static void mc2_task_new(struct task_struct *tsk, int on_runqueue, raw_spin_unlock(&state->lock); //raw_spin_unlock(&_global_env.lock); } + release = res->next_replenishment; local_irq_restore(flags); if (!release) { - TRACE_TASK(tsk, "mc2_task_new() next_release = %llu\n", release); + /*TRACE_TASK(tsk, "mc2_task_new() next_release = NULL\n"); + release = res->next_replenishment; + TRACE_TASK(tsk, "mc2_task_new() next_release SET! = %llu\n", release); release_at(tsk, release); + */ + BUG(); } else - TRACE_TASK(tsk, "mc2_task_new() next_release = NULL\n"); + TRACE_TASK(tsk, "mc2_task_new() next_release = %llu\n", release); } /* mc2_reservation_destroy - reservation_destroy system call backend diff --git a/litmus/sched_task_trace.c b/litmus/sched_task_trace.c index 1b61c60e791b..acf2b7dc0219 100644 --- a/litmus/sched_task_trace.c +++ b/litmus/sched_task_trace.c @@ -248,7 +248,7 @@ feather_callback void do_sched_trace_enact_mode(unsigned long id, struct task_struct *t = (struct task_struct*) _task; struct st_event_record* rec = get_record(ST_ENACT_MODE, t); - if (rec){ + if (rec) { rec->data.enact_mode.when = now(); put_record(rec); } @@ -260,7 +260,7 @@ feather_callback void do_sched_trace_request_mode(unsigned long id, struct task_struct *t = (struct task_struct*) _task; struct st_event_record* rec = get_record(ST_REQUEST_MODE, t); - if (rec){ + if (rec) { rec->data.request_mode.when = now(); put_record(rec); } diff --git a/litmus/sync.c b/litmus/sync.c index 5955c5777786..f066ea4219a8 100644 --- a/litmus/sync.c +++ b/litmus/sync.c @@ -16,6 +16,8 @@ #include +int num_sync_released; + struct ts_release_wait { struct list_head list; struct completion completion; @@ -52,7 +54,7 @@ static long do_wait_for_ts_release(void) if (!ret) { /* Completion succeeded, setup release time. */ ret = litmus->wait_for_release_at( - wait.ts_release_time + get_rt_phase(current)+1000000000); + wait.ts_release_time + get_rt_phase(current)); } else { /* We were interrupted, must cleanup list. */ mutex_lock(&task_release_lock); @@ -147,6 +149,6 @@ asmlinkage long sys_release_ts(lt_t __user *__delay) start_time *= ONE_MS; ret = do_release_ts(start_time + delay); } - + num_sync_released = ret; return ret; } -- cgit v1.2.2