Skip to content

Commit

Permalink
Merge pull request #553 from rodionov/new_tgid
Browse files Browse the repository at this point in the history
Enable creation of host tasks with new tgid in LKL.
  • Loading branch information
thehajime authored Jan 13, 2025
2 parents 2bc46f7 + b0159f0 commit 74da3bd
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 3 deletions.
1 change: 1 addition & 0 deletions arch/lkl/include/asm/unistd.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <uapi/asm/unistd.h>

__SYSCALL(__NR_virtio_mmio_device_add, sys_virtio_mmio_device_add)
__SYSCALL(__NR_new_thread_group_leader, sys_new_thread_group_leader)

#define __SC_ASCII(t, a) #t "," #a

Expand Down
1 change: 1 addition & 0 deletions arch/lkl/include/uapi/asm/unistd.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@
#include <asm-generic/unistd.h>

#define __NR_virtio_mmio_device_add (__NR_arch_specific_syscall + 0)
#define __NR_new_thread_group_leader (__NR_arch_specific_syscall + 1)
31 changes: 28 additions & 3 deletions arch/lkl/kernel/syscalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
static asmlinkage long sys_virtio_mmio_device_add(long base, long size,
unsigned int irq);

static asmlinkage long sys_new_thread_group_leader(void);

typedef long (*syscall_handler_t)(long arg1, ...);

#undef __SYSCALL
Expand Down Expand Up @@ -55,13 +57,17 @@ static long run_syscall(long no, long *params)
static int host_task_id;
static struct task_struct *host0;

static int new_host_task(struct task_struct **task)
static int new_host_task(struct task_struct **task, int new_tg_leader)
{
pid_t pid;
unsigned long flags = CLONE_FLAGS;

switch_to_host_task(host0);

pid = kernel_thread(host_task_stub, NULL, NULL, CLONE_FLAGS);
if (new_tg_leader)
flags &= ~CLONE_THREAD;

pid = kernel_thread(host_task_stub, NULL, NULL, flags);
if (pid < 0)
return pid;

Expand Down Expand Up @@ -108,7 +114,7 @@ long lkl_syscall(long no, long *params)
if (lkl_ops->tls_get) {
task = lkl_ops->tls_get(task_key);
if (!task) {
ret = new_host_task(&task);
ret = new_host_task(&task, no == __NR_new_thread_group_leader);
if (ret)
goto out;
lkl_ops->tls_set(task_key, task);
Expand Down Expand Up @@ -164,6 +170,15 @@ int syscalls_init(void)
set_thread_flag(TIF_HOST_THREAD);
host0 = current;

// Reap zombie host tasks spawned as new thread group leaders via
// new_thread_group_leader syscall (otherwise the dead task resources
// such as `struct task_struct` won't be reclaimed by kernel).
// TODO: currently LKL doesn't support thread signal handling in
// user-space, thus, it's safe to ignore this signal here. However,
// if user-space signal handling is implemented in future we might want
// to remove the line of code below to let user-space handle SIGCHLD.
kernel_sigaction(SIGCHLD, SIG_IGN);

if (lkl_ops->tls_alloc) {
task_key = lkl_ops->tls_alloc(del_host_task);
if (!task_key)
Expand Down Expand Up @@ -239,3 +254,13 @@ SYSCALL_DEFINE3(virtio_mmio_device_add, long, base, long, size, unsigned int,

return ret;
}


SYSCALL_DEFINE0(new_thread_group_leader)
{
// No-op here -- actual handling is done in lkl_syscall routine.
if (current->tgid == current->pid)
return 0;
else
return -1;
}
68 changes: 68 additions & 0 deletions tools/lkl/tests/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,73 @@ static int lkl_test_many_syscall_threads(void)

return TEST_SUCCESS;
}

struct lkl_test_tgid {
long tgid;
long parent_pid;
int new_thread_group_leader_result;
};

static void thread_get_tgid(void *arg)
{
struct lkl_test_tgid *tgid_arg = (struct lkl_test_tgid *)arg;

int ret = lkl_sys_new_thread_group_leader();

tgid_arg->new_thread_group_leader_result = ret;
if (!ret) {
tgid_arg->tgid = lkl_sys_getpid();
tgid_arg->parent_pid = lkl_sys_getppid();
}
}

static int lkl_test_new_tgid_threads(void)
{
lkl_thread_t tid;
long current_pid;
int count = 65, ret;
struct lkl_test_tgid test_tgid;

current_pid = lkl_sys_getpid();
if (current_pid < 0) {
lkl_test_logf("failed to get pid\n");
return TEST_FAILURE;
}

while (--count > 0) {
tid = lkl_host_ops.thread_create(thread_get_tgid, &test_tgid);
if (!tid) {
lkl_test_logf("failed to create thread\n");
return TEST_FAILURE;
}

ret = lkl_host_ops.thread_join(tid);
if (ret) {
lkl_test_logf("failed to join thread\n");
return TEST_FAILURE;
}

if (test_tgid.new_thread_group_leader_result) {
lkl_test_logf("failed to set new thread group leader %x\n",
test_tgid.new_thread_group_leader_result);
return TEST_FAILURE;
}

if (test_tgid.tgid == current_pid) {
lkl_test_logf("child tgid %lx == current pid %lx\n",
test_tgid.tgid, current_pid);
return TEST_FAILURE;
}

if (test_tgid.parent_pid != current_pid) {
lkl_test_logf("ppid of the child %lx != current pid %lx\n",
test_tgid.parent_pid, current_pid);
return TEST_FAILURE;
}
}

return TEST_SUCCESS;
}
#endif

static void thread_quit_immediately(void *unused)
Expand Down Expand Up @@ -694,6 +761,7 @@ struct lkl_test tests[] = {
*/
#ifndef __MINGW32__
LKL_TEST(many_syscall_threads),
LKL_TEST(new_tgid_threads),
#endif
#ifdef LKL_HOST_CONFIG_MMU
LKL_TEST(shared_mmap),
Expand Down

0 comments on commit 74da3bd

Please sign in to comment.