From 8e4ddea7b4c0fb67d8b22ba5a8f63797ee89dc6d Mon Sep 17 00:00:00 2001 From: Yuan Liu Date: Thu, 10 Nov 2016 19:20:16 -0800 Subject: [PATCH 1/2] lkl: Fix lkl_sys_halt Signed-off-by: Yuan Liu --- arch/lkl/include/asm/thread_info.h | 1 + arch/lkl/kernel/setup.c | 4 +++- arch/lkl/kernel/syscalls.c | 7 +++++++ arch/lkl/kernel/threads.c | 5 +++++ tools/lkl/lib/hijack/init.c | 5 ++++- 5 files changed, 20 insertions(+), 2 deletions(-) diff --git a/arch/lkl/include/asm/thread_info.h b/arch/lkl/include/asm/thread_info.h index 2202be67b7bce7..9ee0625c0f1fa5 100644 --- a/arch/lkl/include/asm/thread_info.h +++ b/arch/lkl/include/asm/thread_info.h @@ -49,6 +49,7 @@ void free_thread_stack(unsigned long *); void threads_init(void); void threads_cleanup(void); +void threads_cnt_dec(void); #define TIF_SYSCALL_TRACE 0 #define TIF_NOTIFY_RESUME 1 diff --git a/arch/lkl/kernel/setup.c b/arch/lkl/kernel/setup.c index 59add61bfb0eb6..c5593db5b16c0b 100644 --- a/arch/lkl/kernel/setup.c +++ b/arch/lkl/kernel/setup.c @@ -112,7 +112,8 @@ void machine_restart(char *unused) long lkl_sys_halt(void) { long err; - long params[6] = { 0, }; + long params[6] = {LINUX_REBOOT_MAGIC1, + LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART, }; err = lkl_syscall(__NR_reboot, params); if (err < 0) @@ -158,6 +159,7 @@ static int lkl_run_init(struct linux_binprm *bprm) init_pid_ns.child_reaper = 0; syscalls_init(); + threads_cnt_dec(); lkl_ops->sem_up(init_sem); lkl_ops->thread_exit(); diff --git a/arch/lkl/kernel/syscalls.c b/arch/lkl/kernel/syscalls.c index 2a818d4911865c..6db00f29061a16 100644 --- a/arch/lkl/kernel/syscalls.c +++ b/arch/lkl/kernel/syscalls.c @@ -113,6 +113,13 @@ long lkl_syscall(long no, long *params) ret = run_syscall(no, params); + if (no == __NR_reboot) { + set_current_state(TASK_UNINTERRUPTIBLE); + if (!thread_set_sched_jmp()) + schedule(); + return ret; + } + out: lkl_cpu_put(); diff --git a/arch/lkl/kernel/threads.c b/arch/lkl/kernel/threads.c index bac96f5a23c59e..c217e89750104f 100644 --- a/arch/lkl/kernel/threads.c +++ b/arch/lkl/kernel/threads.c @@ -225,6 +225,11 @@ void threads_init(void) ti->tid = lkl_ops->thread_self(); } +void threads_cnt_dec(void) +{ + __sync_fetch_and_sub(&threads_counter, 1); +} + void threads_cleanup(void) { struct task_struct *p; diff --git a/tools/lkl/lib/hijack/init.c b/tools/lkl/lib/hijack/init.c index 46f3b49b64b984..43fc8b9e987ae4 100644 --- a/tools/lkl/lib/hijack/init.c +++ b/tools/lkl/lib/hijack/init.c @@ -433,6 +433,7 @@ hijack_fini(void) { int i; char *dump = getenv("LKL_HIJACK_DUMP"); + int err; /* The following pauses the kernel before exiting allowing one * to debug or collect stattistics/diagnosis info from it. @@ -453,5 +454,7 @@ hijack_fini(void) if (nd) lkl_netdev_free(nd); - lkl_sys_halt(); + err = lkl_sys_halt(); + if (err) + fprintf(stderr, "lkl_sys_halt: %s\n", lkl_strerror(err)); } From c167ea8f3c262c4de05420293ad229f940a7dd53 Mon Sep 17 00:00:00 2001 From: Yuan Liu Date: Fri, 11 Nov 2016 11:28:29 -0800 Subject: [PATCH 2/2] lkl: Fix memory leak of TIF_HOST_THREAD threads Now the TIF_HOST_THREAD threads are not properly killed. Signed-off-by: Yuan Liu --- arch/lkl/kernel/setup.c | 1 + arch/lkl/kernel/threads.c | 16 ++++++++-------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/arch/lkl/kernel/setup.c b/arch/lkl/kernel/setup.c index c5593db5b16c0b..501d32175dc426 100644 --- a/arch/lkl/kernel/setup.c +++ b/arch/lkl/kernel/setup.c @@ -75,6 +75,7 @@ int __init lkl_start_kernel(struct lkl_host_operations *ops, } lkl_ops->sem_down(init_sem); + lkl_ops->sem_free(init_sem); current_thread_info()->tid = lkl_ops->thread_self(); lkl_cpu_change_owner(current_thread_info()->tid); diff --git a/arch/lkl/kernel/threads.c b/arch/lkl/kernel/threads.c index c217e89750104f..67deea0c245602 100644 --- a/arch/lkl/kernel/threads.c +++ b/arch/lkl/kernel/threads.c @@ -232,16 +232,16 @@ void threads_cnt_dec(void) void threads_cleanup(void) { - struct task_struct *p; + struct task_struct *p, *t; - for_each_process(p) { - struct thread_info *ti = task_thread_info(p); + for_each_process_thread(p, t) { + struct thread_info *ti = task_thread_info(t); - if (p->pid != 1) - WARN(!(p->flags & PF_KTHREAD), - "non kernel thread task %p\n", p->comm); - WARN(p->state == TASK_RUNNING, - "thread %s still running while halting\n", p->comm); + if (t->pid != 1 && !test_ti_thread_flag(ti, TIF_HOST_THREAD)) + WARN(!(t->flags & PF_KTHREAD), + "non kernel thread task %s\n", t->comm); + WARN(t->state == TASK_RUNNING, + "thread %s still running while halting\n", t->comm); kill_thread(ti); }