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