Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lkl: host ops: fix jump buffer API and implementation #267

Merged
merged 1 commit into from
Nov 19, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions arch/lkl/include/asm/sched.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#ifndef _ASM_LKL_SCHED_H
#define _ASM_LKL_SCHED_H

#include <linux/sched.h>

static inline void thread_sched_jb(void)
{
set_ti_thread_flag(current_thread_info(), TIF_SCHED_JB);

if (test_ti_thread_flag(current_thread_info(), TIF_HOST_THREAD)) {
set_current_state(TASK_UNINTERRUPTIBLE);
lkl_ops->jmp_buf_set(&current_thread_info()->sched_jb,
schedule);
} else {
lkl_ops->jmp_buf_set(&current_thread_info()->sched_jb,
lkl_idle_tail_schedule);
}
}

static inline void thread_set_sched_exit(void)
{
set_ti_thread_flag(current_thread_info(), TIF_SCHED_EXIT);
}

void switch_to_host_task(struct task_struct *);

#endif /* _ASM_LKL_SCHED_H */
15 changes: 0 additions & 15 deletions arch/lkl/include/asm/thread_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,21 +63,6 @@ void threads_cnt_dec(void);
#define TIF_HOST_THREAD 9
#define TIF_IDLE 10

static inline void set_ti_thread_flag(struct thread_info *ti, int flag);

static inline int thread_set_sched_jmp(void)
{
set_ti_thread_flag(current_thread_info(), TIF_SCHED_JB);
return lkl_ops->jmp_buf_set(&current_thread_info()->sched_jb);
}

static inline void thread_set_sched_exit(void)
{
set_ti_thread_flag(current_thread_info(), TIF_SCHED_EXIT);
}

void switch_to_host_task(struct task_struct *);

#define __HAVE_THREAD_FUNCTIONS

#define task_thread_info(task) ((struct thread_info *)(task)->stack)
Expand Down
13 changes: 12 additions & 1 deletion arch/lkl/include/uapi/asm/host_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,17 @@ struct lkl_jmp_buf {
*
* @gettid - returns the host thread id of the caller, which need not
* be the same as the handle returned by thread_create
*
* @jmp_buf_set - runs the give function and setups a jump back point by saving
* the context in the jump buffer; jmp_buf_longjmp can be called from the give
* function or any callee in that function to return back to the jump back
* point
*
* NOTE: we can't return from jmp_buf_set before calling jmp_buf_longjmp or
* otherwise the saved context (stack) is not going to be valid, so we must pass
* the function that will eventually call longjmp here
*
* @jmp_buf_longjmp - perform a jump back to the saved jump buffer
*/
struct lkl_host_operations {
const char *virtio_devices;
Expand Down Expand Up @@ -114,7 +125,7 @@ struct lkl_host_operations {

long (*gettid)(void);

int (*jmp_buf_set)(struct lkl_jmp_buf *jmpb);
void (*jmp_buf_set)(struct lkl_jmp_buf *jmpb, void (*f)(void));
void (*jmp_buf_longjmp)(struct lkl_jmp_buf *jmpb, int val);
};

Expand Down
16 changes: 4 additions & 12 deletions arch/lkl/kernel/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <asm/cpu.h>
#include <asm/thread_info.h>
#include <asm/unistd.h>
#include <asm/sched.h>
#include <asm/syscalls.h>


Expand Down Expand Up @@ -137,14 +138,7 @@ void lkl_cpu_put(void)
if (in_interrupt())
lkl_bug("%s: in interrupt\n", __func__);
lkl_ops->mutex_unlock(cpu.lock);
if (test_thread_flag(TIF_HOST_THREAD)) {
set_current_state(TASK_UNINTERRUPTIBLE);
if (!thread_set_sched_jmp())
schedule();
} else {
if (!thread_set_sched_jmp())
lkl_idle_tail_schedule();
}
thread_sched_jb();
return;
}

Expand Down Expand Up @@ -242,10 +236,8 @@ void arch_cpu_idle_prepare(void)
* We hijack the idle loop here so that we can let the idle thread
* jump back to the beginning.
*/
while (1) {
if (!lkl_ops->jmp_buf_set(&cpu.idle_jb))
cpu_idle_loop();
}
while (1)
lkl_ops->jmp_buf_set(&cpu.idle_jb, cpu_idle_loop);
}

void lkl_cpu_wakeup_idle(void)
Expand Down
5 changes: 2 additions & 3 deletions arch/lkl/kernel/syscalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <asm/syscalls.h>
#include <asm/syscalls_32.h>
#include <asm/cpu.h>
#include <asm/sched.h>

static asmlinkage long sys_virtio_mmio_device_add(long base, long size,
unsigned int irq);
Expand Down Expand Up @@ -114,9 +115,7 @@ 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();
thread_sched_jb();
return ret;
}

Expand Down
11 changes: 2 additions & 9 deletions arch/lkl/kernel/threads.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <linux/sched.h>
#include <asm/host_ops.h>
#include <asm/cpu.h>
#include <asm/sched.h>

static volatile int threads_counter;

Expand Down Expand Up @@ -140,15 +141,7 @@ void switch_to_host_task(struct task_struct *task)
task_thread_info(task)->tid = lkl_ops->thread_self();

wake_up_process(task);
if (test_thread_flag(TIF_HOST_THREAD)) {
set_current_state(TASK_UNINTERRUPTIBLE);
if (!thread_set_sched_jmp())
schedule();
} else {
if (!thread_set_sched_jmp())
lkl_idle_tail_schedule();
}

thread_sched_jb();
lkl_ops->sem_down(task_thread_info(task)->sched_sem);
schedule_tail(abs_prev);
}
Expand Down
5 changes: 3 additions & 2 deletions tools/lkl/lib/jmp_buf.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#include <setjmp.h>
#include <lkl_host.h>

int jmp_buf_set(struct lkl_jmp_buf *jmpb)
void jmp_buf_set(struct lkl_jmp_buf *jmpb, void (*f)(void))
{
return setjmp(*((jmp_buf *)jmpb->buf));
if (!setjmp(*((jmp_buf *)jmpb->buf)))
f();
}

void jmp_buf_longjmp(struct lkl_jmp_buf *jmpb, int val)
Expand Down
2 changes: 1 addition & 1 deletion tools/lkl/lib/jmp_buf.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef _LKL_LIB_JMP_BUF_H
#define _LKL_LIB_JMP_BUF_H

int jmp_buf_set(struct lkl_jmp_buf *jmpb);
void jmp_buf_set(struct lkl_jmp_buf *jmpb, void (*f)(void));
void jmp_buf_longjmp(struct lkl_jmp_buf *jmpb, int val);

#endif