From 650a0ddc0aa02e3f000100977eac95cef5a695dd Mon Sep 17 00:00:00 2001 From: Ollrogge <nils-ollrogge@outlook.de> Date: Tue, 13 Sep 2022 17:18:25 +0200 Subject: [PATCH] code cleanup && working pb_submitter --- kernel/sched/pb.c | 39 ++++++++++-------- pb_utils/pb_submitter/example_plan | 10 ----- pb_utils/pb_submitter/example_run.sh | 2 +- pb_utils/pb_submitter/pb_submitter.c | 59 +++++++++++++++++++++------- pb_utils/pb_submitter/test_prog.c | 8 ++-- 5 files changed, 71 insertions(+), 47 deletions(-) diff --git a/kernel/sched/pb.c b/kernel/sched/pb.c index 7a180f593fc1..704c6f03da93 100644 --- a/kernel/sched/pb.c +++ b/kernel/sched/pb.c @@ -4,11 +4,11 @@ #include <linux/syscalls.h> #include <linux/spinlock.h> #include <linux/perf_event.h> +#include <linux/kthread.h> typedef struct pb_plan pb_plan_t; SYSCALL_DEFINE1(pb_set_plan, pb_plan_t __user*, plan) { - pb_plan_t _plan; struct task_struct* task; struct rq* rq; @@ -23,7 +23,6 @@ SYSCALL_DEFINE1(pb_set_plan, pb_plan_t __user*, plan) { copied = copy_from_user(&_plan, plan, sizeof(pb_plan_t)); if (copied != 0) { - printk("copy_from_user pb_plan failed \n"); return -1; } @@ -45,14 +44,13 @@ SYSCALL_DEFINE1(pb_set_plan, pb_plan_t __user*, plan) { task = find_task_by_vpid(_plan.pid); if (!task) { - printk("!task\n"); return -1; } - task->sched_class = &pb_sched_class; - rq = this_rq(); + task->sched_class = &pb_sched_class; + pb_rq = &rq->pb; set_pb_plan_size(pb_rq, _plan.num_tasks); @@ -67,6 +65,8 @@ SYSCALL_DEFINE1(pb_set_plan, pb_plan_t __user*, plan) { ); } + kfree(inst_cnt); + res = pb_submit_plan(rq); if (res == -1) { @@ -74,10 +74,6 @@ SYSCALL_DEFINE1(pb_set_plan, pb_plan_t __user*, plan) { return res; } - // TODO: - // - perf_event stuff - // - syscall for error message retrieval? - // - ... return 0; } @@ -96,7 +92,6 @@ int pb_submit_plan(struct rq *rq) return -1; } - int perf_init_res = init_perf_event(&pb->plan[i], &pb->pevent); if(perf_init_res < 0) { //initialization error detection/handling could happen here @@ -105,7 +100,6 @@ int pb_submit_plan(struct rq *rq) printk(KERN_DEBUG "PB INIT,%u\n", i); } - pb->c_entry = 0; pb->count_pb_cycles = 0; pb->count_admin_cycles = 0; @@ -143,7 +137,7 @@ EXPORT_SYMBOL(set_pb_plan_entry); // called by core.c sched_init void init_pb_rq(struct pb_rq *pb_rq) { - pb_rq->n_pb_cycles = 100; + pb_rq->n_pb_cycles = 20; pb_rq->count_pb_cycles = 0; pb_rq->n_admin_cycles = 20; pb_rq->count_admin_cycles = 0; @@ -189,6 +183,7 @@ static struct task_struct * pick_next_task_pb(struct rq *rq, struct task_struct *picked = NULL; enum pb_mode current_mode, next_mode; struct pb_rq *pb = &(rq->pb); + bool premature_finish = false; unsigned long flags; pb->l_entry = pb->c_entry; @@ -243,20 +238,30 @@ static struct task_struct * pick_next_task_pb(struct rq *rq, } pb->c_entry++; - - if (pb->c_entry >= pb->size) { + + /** + * Don't schedule a task that is dead. (e.g. plan was incorrect and program finished quicker) + * todo: if we have multiple tasks structs just try the next plan entry + */ + if (pb->plan[pb->c_entry].task_struct->state == TASK_DEAD) { + premature_finish = true; + } + + if (pb->c_entry >= pb->size || premature_finish) { raw_spin_lock_irqsave(pb->pb_lock, flags); terminate_perf_event(pb->pevent); raw_spin_unlock_irqrestore(pb->pb_lock, flags); pb->pevent = NULL; // TODO: Check if we have to free the memory or if perf takes care of it // see 'perf_event_release_kernel(struct perf_event *event)' in core.c - printk(KERN_DEBUG "PLAN DONE\n"); pb->mode = PB_DISABLED_MODE; + next_mode = PB_DISABLED_MODE; + picked = NULL; pb->is_initialized = 0; + printk(KERN_WARNING "PLAN DONE \n"); } pb->is_in_critical = false; - printk("DONE"); + printk("DONE"); } // EXEC Mode is next, so we return our next task to be executed @@ -300,7 +305,7 @@ static void task_tick_pb(struct rq *rq, struct task_struct *p, int queued) // printk("TICK #%d\n",pb->count_pb_cycles); 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"); + //printk("Reschudling in task_tick_pb"); 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; diff --git a/pb_utils/pb_submitter/example_plan b/pb_utils/pb_submitter/example_plan index d3a1ca1428a9..83181673a10b 100644 --- a/pb_utils/pb_submitter/example_plan +++ b/pb_utils/pb_submitter/example_plan @@ -98,13 +98,3 @@ 100000 100000 100000 -100000 -100000 -100000 -100000 -100000 -100000 -100000 -100000 -100000 -100000 diff --git a/pb_utils/pb_submitter/example_run.sh b/pb_utils/pb_submitter/example_run.sh index f4ebc4074e57..380e11c0c248 100755 --- a/pb_utils/pb_submitter/example_run.sh +++ b/pb_utils/pb_submitter/example_run.sh @@ -1,3 +1,3 @@ #!/bin/sh -./pb_submitter test example_plan +./pb_submitter test_prog example_plan diff --git a/pb_utils/pb_submitter/pb_submitter.c b/pb_utils/pb_submitter/pb_submitter.c index 3a677d3c30b6..023146b98c0c 100644 --- a/pb_utils/pb_submitter/pb_submitter.c +++ b/pb_utils/pb_submitter/pb_submitter.c @@ -45,7 +45,15 @@ int main(int argc, char** argv) FILE *fp; char *line = NULL; size_t len = 0; - ssize_t read; + ssize_t cnt; + int pipes[0x2]; + + ret = pipe(pipes); + + if (ret < 0) { + perror("pipe"); + return -1; + } fp = fopen(argv[2], "r"); if (fp == NULL) { @@ -64,9 +72,9 @@ int main(int argc, char** argv) } for (size_t i = 0; i < plan.num_tasks; i++) { - read = getline(&line, &len, fp); + cnt = getline(&line, &len, fp); - if (read < 0) { + if (cnt < 0) { perror("getline"); return -1; } @@ -83,20 +91,41 @@ int main(int argc, char** argv) plan.inst_cnt = inst_cnt; - plan.pid = getpid(); + printf("Execve: %s \n", argv[1]); - ret = syscall(PB_SET_PLAN, &plan); - if (ret < 0) { - puts("PB_SET_PLAN failed"); - return -1; - } + pid_t pid = fork(); - char *const args[] = {argv[1], NULL}; - char *const env[] = {NULL}; - ret = execve(argv[1], args, env); - if (ret < 0) { - perror("execve"); - return -1; + if (pid == 0x0) { + char *const args[] = {argv[1], NULL}; + char *const env[] = {NULL}; + + write(pipes[0x1], "a", sizeof("a")); + + ret = execve(argv[1], args, env); + if (ret < 0) { + perror("execve"); + return -1; + } + } + else { + /** + * Wait for execve of child to finish else pb cycles are wasted inside + * the execve function. + * + * todo: find better method to do this + */ + sleep(0x1); + char c; + read(pipes[0x0], &c, sizeof(char)); + + plan.pid = pid; + + ret = syscall(PB_SET_PLAN, &plan); + + if (ret < 0) { + puts("PB_SET_PLAN failed"); + return -1; + } } return 0; diff --git a/pb_utils/pb_submitter/test_prog.c b/pb_utils/pb_submitter/test_prog.c index 07e16b3618d0..3c28f823f380 100644 --- a/pb_utils/pb_submitter/test_prog.c +++ b/pb_utils/pb_submitter/test_prog.c @@ -1,18 +1,18 @@ #include <stdio.h> +#include <unistd.h> int main(void) { + sleep(1); unsigned int c = 0; - // printk(KERN_WARNING "Hello from Module.\n"); int a = 0; int b = 0; - // printk(KERN_WARNING "A.\n"); for (;b < 100; b++) { + // check if program runs && syscall to switch tasks + puts("loop"); for (;a < 100000; a++){asm("");} } - // printk(KERN_WARNING "B.\n"); c++; - // printk(KERN_WARNING "Bye from module.\n"); return 0; } -- GitLab