-
Notifications
You must be signed in to change notification settings - Fork 5
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
[kernel] Move Execution of Side Effect Kernel Calls to Dedicated Kernel Thread #413
Comments
I've thought of two potential solutions that I believe could address this issue. I'd appreciate some feedback on which approach might be more suitable. Additionally, I understand if neither of these solutions seems ideal and welcome any suggestions for improvement. Solution 1The first solution is straightforward, using a simple case NR_thread_create:
if (process_get_curr() != KERNEL_PROCESS) {
goto handle_side_effect;
}
ret = kcall_thread_create(
(void (*)())arg0, (void *)arg1, (void (*)(void))arg2);
break;
...
handle_side_effect:
default:
// Copy kernel call parameters.
scoreboard.kcall_nr = kcall_nr;
scoreboard.arg0 = arg0;
scoreboard.arg1 = arg1;
scoreboard.arg2 = arg2;
scoreboard.arg3 = arg3;
scoreboard.arg4 = arg4;
semaphore_up(kernel_semaphore);
semaphore_down(user_semaphore);
ret = scoreboard.ret;
break; Then, do_kcall() is called again within handle_syscall(), executed by a kernel thread: noreturn void handle_syscall(void)
{
while (true) {
semaphore_down(kernel_semaphore);
scoreboard.ret = do_kcall(scoreboard.arg0,
scoreboard.arg1,
scoreboard.arg2,
scoreboard.arg3,
scoreboard.arg4,
scoreboard.kcall_nr);
semaphore_up(user_semaphore);
}
} Solution 2The second solution proposes a restructuring of syscall handling using a table of syscall functions and an argument list. Here's a detailed explanation: In int do_kcall(word_t *args, word_t kcall_nr)
{
int ret = -1;
switch (kcall_nr) {
case NR_spawn:
...
case NR_thread_create:
// Copy kernel call parameters.
scoreboard.kcall_nr = kcall_nr;
scoreboard.args = args;
semaphore_up(kernel_semaphore);
semaphore_down(user_semaphore);
ret = scoreboard.ret;
break;
default:
ret = kcalltab[kcall_nr](args);
break;
}
return (ret);
} In noreturn void handle_syscall(void)
{
while (true) {
semaphore_down(kernel_semaphore);
scoreboard.ret = kcalltab[scoreborad.kcall_nr](scoreboard.args);
semaphore_up(user_semaphore);
}
} However, this approach needs a refactoring of tid_t kcall_thread_create(word_t *args)
{
return (thread_create(process_get_curr(),
(void (*)())args[0],
(void *)args[1],
(void (*)(void))args[2]));
} Furthermore, user-space syscall invocations would also require refactoring in |
@ravixr It is simpler than both solutions that were presented: if the number of the system call matches one within the set of system calls with side effects, you just fall through the default case. Check out legacy code for reference: https://github.com/nanvix/microkernel/blob/fa34cdc75a5ed2bef296f1b25b7f6126fafbb6ee/src/kernel/sys/syscalls.c |
Description
Nanvix embraces an asymmetric kernel design. That is, when a user-level thread invokes a kernel call, that call is dispatched for execution as follows:
We should change or implementation to meet this design. Currently, our implementation runs all kernel calls locally.
What should be done?
handle_syscall()
do_kcall()
accordinglyRelated Files
https://github.com/nanvix/microkernel/blob/17de3a67c131a2085738cab7e28de2302918ceeb/src/kernel/kcall/mod.c
The text was updated successfully, but these errors were encountered: