From c8dc75d3b57392c8b61465dc9a37916a278b854e Mon Sep 17 00:00:00 2001 From: mandersch <malte.k.andersch@gmail.com> Date: Mon, 12 Sep 2022 13:55:11 +0200 Subject: [PATCH] Fix a Bug where a preempted task would not be continued if stopped at a specific moment, Add l_entry field to plan_entry struct to keep track of the last finished task --- kernel/sched/pb.c | 16 +++++++++------- kernel/sched/sched.h | 1 + 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/kernel/sched/pb.c b/kernel/sched/pb.c index 6e328b2e33ef..3b6b5a87c13d 100644 --- a/kernel/sched/pb.c +++ b/kernel/sched/pb.c @@ -122,14 +122,14 @@ static void check_preempt_curr_pb(struct rq *rq, struct task_struct *p, int flag static struct task_struct * pick_next_task_pb(struct rq *rq, struct task_struct *prev, struct rq_flags *rf) { - + // contains task to be executed struct task_struct *picked = NULL; enum pb_mode current_mode, next_mode; struct pb_rq *pb = &(rq->pb); unsigned long flags; - + pb->l_entry = pb->c_entry; current_mode = pb->mode; next_mode = determine_next_mode_pb(rq); @@ -139,7 +139,7 @@ static struct task_struct * pick_next_task_pb(struct rq *rq, printk("SWITCHING MODES\n"); pb->count_admin_cycles = 0; pb->count_pb_cycles = 0; - // Push last onn-plan task back in its corresponding runqueue + // Push last non-plan task back in its corresponding runqueue if (next_mode == PB_EXEC_MODE) { // Necessary to manage the preempted task printk("PUT OLD TASK BACK IN RQ\n"); @@ -147,7 +147,7 @@ static struct task_struct * pick_next_task_pb(struct rq *rq, } } - if ((current_mode == PB_EXEC_MODE && !pb->is_preempted) || (pb->is_preempted && !pb->is_in_critical)) { + if (current_mode == PB_EXEC_MODE && !pb->is_preempted) { unsigned int c_entry_curr; u64 perf_counter; u64 counter_diff; @@ -196,8 +196,6 @@ static struct task_struct * pick_next_task_pb(struct rq *rq, pb->is_in_critical = false; printk("DONE"); } - pb->is_preempted = false; - // EXEC Mode is next, so we return our next task to be executed if (next_mode == PB_EXEC_MODE) { @@ -207,6 +205,7 @@ static struct task_struct * pick_next_task_pb(struct rq *rq, } else if (current_mode == PB_DISABLED_MODE) { printk("Switching from disabled to EXEC\n"); } + pb->is_preempted = false; picked = pb->plan[pb->c_entry].task_struct; } @@ -240,7 +239,10 @@ static void task_tick_pb(struct rq *rq, struct task_struct *p, int queued) if (determine_next_mode_pb(rq) != PB_EXEC_MODE && pb->mode == PB_EXEC_MODE && !pb->is_preempted && !pb->is_in_critical) { printk("Reschudling in task_tick_pb"); - pb->is_preempted = true; + if (pb->l_entry != pb->c_entry){ + // If the currrent task is not the last finished one, that means its unfinished and thus we set the preemtped flag + pb->is_preempted = true; + } resched_curr(rq); } } diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 94cc2f9d4d89..19406035c12e 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -545,6 +545,7 @@ struct pb_rq struct plan_entry *plan; // plan (used to be proxy_task) unsigned int size; // size of the plan unsigned int c_entry; // index of currently executed entry + unsigned int l_entry; // index of last finished task, neccessary or preemption management u64 n_pb_cycles; // amount of timer ticks before admin tasks are allowed to run u64 count_pb_cycles; // current timer tick count for PB tasks -- GitLab