From ecc850dfefea7bda0b2ff0c5c4db7cada7411cb6 Mon Sep 17 00:00:00 2001 From: Dominique Martinet Date: Thu, 30 Aug 2018 14:13:38 +0900 Subject: [PATCH] procfs/do_fork: wait until procfs entries are registered Do not return from fork() until mcctrl side has created mckernel's procfs entries for the child PID. This fixes programs doing fork() immediately followed by opening /proc//something, and would get some error Refs: #1189 Change-Id: Ie10ea56b65c55f59e96a1ab6ef83a1070e36048d --- executer/kernel/mcctrl/ikc.c | 3 ++- executer/kernel/mcctrl/mcctrl.h | 3 ++- executer/kernel/mcctrl/procfs.c | 38 +++++++++++++++++++++++---------- kernel/procfs.c | 6 ++++++ 4 files changed, 37 insertions(+), 13 deletions(-) diff --git a/executer/kernel/mcctrl/ikc.c b/executer/kernel/mcctrl/ikc.c index 916b2d2e..e07d67a2 100644 --- a/executer/kernel/mcctrl/ikc.c +++ b/executer/kernel/mcctrl/ikc.c @@ -207,7 +207,8 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c, case SCD_MSG_PROCFS_TID_CREATE: case SCD_MSG_PROCFS_TID_DELETE: - procfsm_packet_handler(__os, pisp->msg, pisp->pid, pisp->arg); + procfsm_packet_handler(__os, pisp->msg, pisp->pid, pisp->arg, + pisp->resp_pa); break; case SCD_MSG_GET_VDSO_INFO: diff --git a/executer/kernel/mcctrl/mcctrl.h b/executer/kernel/mcctrl/mcctrl.h index c3b47662..f9f9956a 100644 --- a/executer/kernel/mcctrl/mcctrl.h +++ b/executer/kernel/mcctrl/mcctrl.h @@ -507,7 +507,8 @@ struct procfs_file { }; void procfs_answer(struct mcctrl_usrdata *ud, int pid); -int procfsm_packet_handler(void *os, int msg, int pid, unsigned long arg); +int procfsm_packet_handler(void *os, int msg, int pid, unsigned long arg, + unsigned long resp_pa); void add_tid_entry(int osnum, int pid, int tid); void add_pid_entry(int osnum, int pid); void delete_tid_entry(int osnum, int pid, int tid); diff --git a/executer/kernel/mcctrl/procfs.c b/executer/kernel/mcctrl/procfs.c index d36c2900..3feafc37 100644 --- a/executer/kernel/mcctrl/procfs.c +++ b/executer/kernel/mcctrl/procfs.c @@ -700,33 +700,48 @@ struct procfs_work { int msg; int pid; unsigned long arg; + unsigned long resp_pa; struct work_struct work; }; static void procfsm_work_main(struct work_struct *work0) { struct procfs_work *work = container_of(work0, struct procfs_work, work); + unsigned long phys; + int *done; switch (work->msg) { - case SCD_MSG_PROCFS_TID_CREATE: - add_tid_entry(ihk_host_os_get_index(work->os), work->pid, work->arg); - break; + case SCD_MSG_PROCFS_TID_CREATE: + add_tid_entry(ihk_host_os_get_index(work->os), + work->pid, work->arg); + phys = ihk_device_map_memory(ihk_os_to_dev(work->os), + work->resp_pa, sizeof(int)); + done = ihk_device_map_virtual(ihk_os_to_dev(work->os), + phys, sizeof(int), NULL, 0); + *done = 1; + ihk_device_unmap_virtual(ihk_os_to_dev(work->os), + done, sizeof(int)); + ihk_device_unmap_memory(ihk_os_to_dev(work->os), + phys, sizeof(int)); + break; - case SCD_MSG_PROCFS_TID_DELETE: - delete_tid_entry(ihk_host_os_get_index(work->os), work->pid, work->arg); - break; + case SCD_MSG_PROCFS_TID_DELETE: + delete_tid_entry(ihk_host_os_get_index(work->os), + work->pid, work->arg); + break; - default: - printk("%s: unknown work: msg: %d, pid: %d, arg: %lu)\n", - __FUNCTION__, work->msg, work->pid, work->arg); - break; + default: + pr_warn("%s: unknown work: msg: %d, pid: %d, arg: %lu)\n", + __func__, work->msg, work->pid, work->arg); + break; } kfree(work); return; } -int procfsm_packet_handler(void *os, int msg, int pid, unsigned long arg) +int procfsm_packet_handler(void *os, int msg, int pid, unsigned long arg, + unsigned long resp_pa) { struct procfs_work *work = NULL; @@ -740,6 +755,7 @@ int procfsm_packet_handler(void *os, int msg, int pid, unsigned long arg) work->msg = msg; work->pid = pid; work->arg = arg; + work->resp_pa = resp_pa; INIT_WORK(&work->work, &procfsm_work_main); schedule_work(&work->work); diff --git a/kernel/procfs.c b/kernel/procfs.c index bf1b2879..71ae751b 100644 --- a/kernel/procfs.c +++ b/kernel/procfs.c @@ -117,6 +117,7 @@ procfs_thread_ctl(struct thread *thread, int msg) { struct ihk_ikc_channel_desc *syscall_channel; struct ikc_scd_packet packet; + int done = 0; syscall_channel = cpu_local_var(ikc2linux); memset(&packet, '\0', sizeof packet); @@ -125,9 +126,14 @@ procfs_thread_ctl(struct thread *thread, int msg) packet.osnum = ihk_mc_get_osnum(); packet.ref = thread->cpu_id; packet.pid = thread->proc->pid; + packet.resp_pa = virt_to_phys(&done); packet.err = 0; ihk_ikc_send(syscall_channel, &packet, 0); + if (msg == SCD_MSG_PROCFS_TID_CREATE) { + while (!done) + cpu_pause(); + } } void