From 2c56907829598886e58b2ae0c4e178d457fec091 Mon Sep 17 00:00:00 2001 From: Tobias Bouschen <tobias.bouschen@googlemail.com> Date: Wed, 20 Mar 2019 11:39:39 +0100 Subject: [PATCH] Fix reading performance counter and returning correct task --- kernel/sched/pb.c | 35 +++++++++++++++++++---------- kernel/sched/perf_error_detection.c | 15 +++++++------ kernel/sched/perf_error_detection.h | 4 +++- 3 files changed, 34 insertions(+), 20 deletions(-) diff --git a/kernel/sched/pb.c b/kernel/sched/pb.c index ef82c517a410..b2a559fd3a4f 100644 --- a/kernel/sched/pb.c +++ b/kernel/sched/pb.c @@ -122,17 +122,25 @@ static struct task_struct * pick_next_task_pb(struct rq *rq, if (next_mode == PB_EXEC_MODE) { if (current_mode == PB_EXEC_MODE){ - /* - * !!! perf_counter contains return value of perf_event_release_kernel(), not the event counter !!! - */ - // u64 pevent_cntval; - int perf_counter = terminate_perf_event(pb->pevent, pb->plan[pb->c_entry].task_id /*, &pevent_cntval */); - //error detection + u64 perf_counter; + u64 read_error = get_perf_counter(pb->pevent, &perf_counter); + + //TODO error handling + + terminate_perf_event(pb->pevent); if (perf_counter < pb->plan[pb->c_entry].n_instr){ - // if (pevent_cntval < pb->plan[pb->c_entry].n_instr){ - printk(KERN_WARNING "PB TASK %llu RAN TOO SHORT\n",pb->plan[pb->c_entry].task_id); + u64 under_time = pb->plan[pb->c_entry].n_instr - perf_counter; + + printk(KERN_WARNING "PB TASK %llu RAN %llu INSTRUCTIONS TOO SHORT\n", pb->plan[pb->c_entry].task_id, under_time); + + } else if (perf_counter > pb->plan[pb->c_entry].n_instr){ + u64 under_time = perf_counter - pb->plan[pb->c_entry].n_instr; + + printk(KERN_WARNING "PB TASK %llu RAN %llu INSTRUCTIONS TOO LONG\n", pb->plan[pb->c_entry].task_id, under_time); } + + pb->c_entry++; if (pb->c_entry >= pb->size){ printk(KERN_DEBUG "PLAN DONE\n"); @@ -149,7 +157,8 @@ static struct task_struct * pick_next_task_pb(struct rq *rq, } }else if(current_mode == PB_ADMIN_MODE){ printk(KERN_DEBUG "PB ADMIN,STOP,%u,%llu\n", pb->c_entry, sched_clock()); - }else{ // PB_DISABLED_MODE + }else{ + // PB_DISABLED_MODE int perf_init_res = init_perf_event(pb->plan[pb->c_entry], &pb->pevent); if(perf_init_res < 0){ @@ -160,9 +169,11 @@ static struct task_struct * pick_next_task_pb(struct rq *rq, } } - //TODO: pick next task from taskarray - picked = pb->proxy_task; - //TODO: call papi handler------------------------------------ + + if (pb->mode != PB_DISABLED_MODE){ + // Return current task from plan if plan is enabled + picked = pb->plan_entry[pb->c_entry]->task_struct; + } } if (current_mode != next_mode){ diff --git a/kernel/sched/perf_error_detection.c b/kernel/sched/perf_error_detection.c index 68b46e2776b6..e3b44eefd97e 100644 --- a/kernel/sched/perf_error_detection.c +++ b/kernel/sched/perf_error_detection.c @@ -42,17 +42,18 @@ int init_perf_event(struct plan_entry plan_entry, struct perf_event **pevent){ return 0; } -//terminate perf event - return performance counter value + /* - * TODO: return the event counter value - * + * Must not be called after the event is terminated. */ -long long terminate_perf_event(struct perf_event *pevent, u64 task_id /*, u64 *pevent_cntval */){ +u64 get_perf_counter(struct perf_event *pevent, u64 *perf_counter) +{ + return perf_event_read_local(pevent, perf_counter); +} - // TODO: - // *pevent_cntval = get the counter value here +u64 terminate_perf_event(struct perf_event *pevent) +{ return perf_event_release_kernel(pevent); - } diff --git a/kernel/sched/perf_error_detection.h b/kernel/sched/perf_error_detection.h index 06b0767616b0..ae6a341a4432 100644 --- a/kernel/sched/perf_error_detection.h +++ b/kernel/sched/perf_error_detection.h @@ -12,7 +12,9 @@ int init_perf_event(struct plan_entry, struct perf_event **pevent); -long long terminate_perf_event(struct perf_event *pevent, u64 task_id); +u64 get_perf_counter(struct perf_event *pevent, u64 *perf_counter); + +u64 terminate_perf_event(struct perf_event *pevent); void overflow_handler( struct perf_event *, -- GitLab