From 8f30e16976c6bddb213c00c526479cb708f45ed3 Mon Sep 17 00:00:00 2001 From: Tomoki Shirasawa Date: Thu, 27 Nov 2014 16:13:52 +0900 Subject: [PATCH] when mcexec is killed by SIGKILL, terminate mckernel process (BUG#259) --- arch/x86/kernel/syscall.c | 3 +- executer/include/uprotocol.h | 7 ++++ executer/kernel/control.c | 65 ++++++++++++++++++++++++++++++++++-- executer/kernel/driver.c | 9 +++-- executer/kernel/mcctrl.h | 3 ++ executer/user/mcexec.c | 4 +++ kernel/host.c | 10 ++++++ kernel/include/process.h | 1 + kernel/include/syscall.h | 3 ++ kernel/process.c | 26 +++++++++++++++ kernel/syscall.c | 41 ++++++++++++++++++++++- 11 files changed, 164 insertions(+), 8 deletions(-) diff --git a/arch/x86/kernel/syscall.c b/arch/x86/kernel/syscall.c index 4d0d25c4..0b3bb814 100644 --- a/arch/x86/kernel/syscall.c +++ b/arch/x86/kernel/syscall.c @@ -780,7 +780,8 @@ do_kill(int pid, int tid, int sig, siginfo_t *info) ihk_mc_spinlock_unlock_noirq(savelock); cpu_restore_interrupt(irqstate); - interrupt_syscall(pid, cpuid); + if(!tproc->nohost) + interrupt_syscall(pid, cpuid); if (status != PS_RUNNING) { switch(sig) { diff --git a/executer/include/uprotocol.h b/executer/include/uprotocol.h index 5c630362..fcc1aaa2 100644 --- a/executer/include/uprotocol.h +++ b/executer/include/uprotocol.h @@ -38,6 +38,7 @@ #define MCEXEC_UP_SEND_SIGNAL 0x30a02906 #define MCEXEC_UP_GET_CPU 0x30a02907 #define MCEXEC_UP_STRNCPY_FROM_USER 0x30a02908 +#define MCEXEC_UP_NEW_PROCESS 0x30a02909 #define MCEXEC_UP_PREPARE_DMA 0x30a02910 #define MCEXEC_UP_FREE_DMA 0x30a02911 @@ -45,6 +46,8 @@ #define MCEXEC_UP_OPEN_EXEC 0x30a02912 #define MCEXEC_UP_CLOSE_EXEC 0x30a02913 +#define MCEXEC_UP_DEBUG_LOG 0x40000000 + #define MCEXEC_UP_TRANSFER_TO_REMOTE 0 #define MCEXEC_UP_TRANSFER_FROM_REMOTE 1 @@ -156,4 +159,8 @@ struct signal_desc { char info[128]; }; +struct newprocess_desc { + int pid; +}; + #endif diff --git a/executer/kernel/control.c b/executer/kernel/control.c index 5857aeb7..230e44af 100644 --- a/executer/kernel/control.c +++ b/executer/kernel/control.c @@ -242,19 +242,71 @@ int mcexec_transfer_image(ihk_os_t os, struct remote_transfer *__user upt) //extern unsigned long last_thread_exec; +struct handlerinfo { + int pid; +}; + +static long mcexec_debug_log(ihk_os_t os, unsigned long arg) +{ + struct ikc_scd_packet isp; + struct mcctrl_channel *c; + + memset(&isp, '\0', sizeof isp); + isp.msg = SCD_MSG_DEBUG_LOG; + isp.arg = arg; + mcctrl_ikc_send(os, 0, &isp); + return 0; +} + +static void release_handler(ihk_os_t os, void *param) +{ + struct handlerinfo *info = param; + struct ikc_scd_packet isp; + struct mcctrl_channel *c; + + memset(&isp, '\0', sizeof isp); + isp.msg = SCD_MSG_CLEANUP_PROCESS; + isp.pid = info->pid; + + mcctrl_ikc_send(os, 0, &isp); + kfree(param); +} + +static long mcexec_newprocess(ihk_os_t os, + struct newprocess_desc *__user udesc, + struct file *file) +{ + struct newprocess_desc desc; + struct handlerinfo *info; + + if (copy_from_user(&desc, udesc, sizeof(struct newprocess_desc))) { + return -EFAULT; + } + info = kmalloc(sizeof(struct handlerinfo), GFP_KERNEL); + info->pid = desc.pid; + ihk_os_register_release_handler(file, release_handler, info); + return 0; +} + static long mcexec_start_image(ihk_os_t os, - struct program_load_desc * __user udesc) + struct program_load_desc * __user udesc, + struct file *file) { struct program_load_desc desc; struct ikc_scd_packet isp; struct mcctrl_channel *c; struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os); + struct handlerinfo *info; if (copy_from_user(&desc, udesc, sizeof(struct program_load_desc))) { return -EFAULT; } + info = kmalloc(sizeof(struct handlerinfo), GFP_KERNEL); + info->pid = desc.pid; + ihk_os_register_release_handler(file, release_handler, info); + c = usrdata->channels + desc.cpu; mcctrl_ikc_set_recv_cpu(os, desc.cpu); @@ -857,7 +909,8 @@ long mcexec_strncpy_from_user(ihk_os_t os, struct strncpy_from_user_desc * __use return 0; } -long __mcctrl_control(ihk_os_t os, unsigned int req, unsigned long arg) +long __mcctrl_control(ihk_os_t os, unsigned int req, unsigned long arg, + struct file *file) { switch (req) { case MCEXEC_UP_PREPARE_IMAGE: @@ -867,7 +920,7 @@ long __mcctrl_control(ihk_os_t os, unsigned int req, unsigned long arg) return mcexec_transfer_image(os, (struct remote_transfer *)arg); case MCEXEC_UP_START_IMAGE: - return mcexec_start_image(os, (struct program_load_desc *)arg); + return mcexec_start_image(os, (struct program_load_desc *)arg, file); case MCEXEC_UP_WAIT_SYSCALL: return mcexec_wait_syscall(os, (struct syscall_wait_desc *)arg); @@ -888,6 +941,10 @@ long __mcctrl_control(ihk_os_t os, unsigned int req, unsigned long arg) return mcexec_strncpy_from_user(os, (struct strncpy_from_user_desc *)arg); + case MCEXEC_UP_NEW_PROCESS: + return mcexec_newprocess(os, (struct newprocess_desc *)arg, + file); + case MCEXEC_UP_OPEN_EXEC: return mcexec_open_exec(os, (char *)arg); @@ -899,6 +956,8 @@ long __mcctrl_control(ihk_os_t os, unsigned int req, unsigned long arg) case MCEXEC_UP_FREE_DMA: return mcexec_free_region(os, (unsigned long *)arg); + case MCEXEC_UP_DEBUG_LOG: + return mcexec_debug_log(os, arg); } return -EINVAL; } diff --git a/executer/kernel/driver.c b/executer/kernel/driver.c index fc0f6af1..f529af60 100644 --- a/executer/kernel/driver.c +++ b/executer/kernel/driver.c @@ -29,7 +29,8 @@ #define OS_MAX_MINOR 64 -extern long __mcctrl_control(ihk_os_t, unsigned int, unsigned long); +extern long __mcctrl_control(ihk_os_t, unsigned int, unsigned long, + struct file *); extern int prepare_ikc_channels(ihk_os_t os); extern void destroy_ikc_channels(ihk_os_t os); #ifndef DO_USER_MODE @@ -40,9 +41,9 @@ extern void procfs_exit(int); static long mcctrl_ioctl(ihk_os_t os, unsigned int request, void *priv, - unsigned long arg) + unsigned long arg, struct file *file) { - return __mcctrl_control(os, request, arg); + return __mcctrl_control(os, request, arg, file); } static struct ihk_os_user_call_handler mcctrl_uchs[] = { @@ -55,10 +56,12 @@ static struct ihk_os_user_call_handler mcctrl_uchs[] = { { .request = MCEXEC_UP_SEND_SIGNAL, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_GET_CPU, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_STRNCPY_FROM_USER, .func = mcctrl_ioctl }, + { .request = MCEXEC_UP_NEW_PROCESS, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_PREPARE_DMA, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_FREE_DMA, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_OPEN_EXEC, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_CLOSE_EXEC, .func = mcctrl_ioctl }, + { .request = MCEXEC_UP_DEBUG_LOG, .func = mcctrl_ioctl }, }; static struct ihk_os_user_call mcctrl_uc_proto = { diff --git a/executer/kernel/mcctrl.h b/executer/kernel/mcctrl.h index 36e958d0..35e52a1b 100644 --- a/executer/kernel/mcctrl.h +++ b/executer/kernel/mcctrl.h @@ -48,12 +48,15 @@ #define SCD_MSG_SYSCALL_ONESIDE 0x4 #define SCD_MSG_SEND_SIGNAL 0x8 +#define SCD_MSG_CLEANUP_PROCESS 0x9 #define SCD_MSG_PROCFS_CREATE 0x10 #define SCD_MSG_PROCFS_DELETE 0x11 #define SCD_MSG_PROCFS_REQUEST 0x12 #define SCD_MSG_PROCFS_ANSWER 0x13 +#define SCD_MSG_DEBUG_LOG 0x20 + #define DMA_PIN_SHIFT 21 #define DO_USER_MODE diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c index 205b3123..0d727d74 100644 --- a/executer/user/mcexec.c +++ b/executer/user/mcexec.c @@ -1530,6 +1530,7 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock, int mcosid) case 0: { int i; int ret = 1; + struct newprocess_desc npdesc; ischild = 1; /* Reopen device fd */ @@ -1572,6 +1573,9 @@ fork_child_out: close(sync_pipe_fd[0]); close(sync_pipe_fd[1]); + npdesc.pid = getpid(); + ioctl(fd, MCEXEC_UP_NEW_PROCESS, &npdesc); + /* TODO: does the forked thread run in a pthread context? */ for (i = 0; i <= ncpu; ++i) { pthread_join(thread_data[i].thread_id, NULL); diff --git a/kernel/host.c b/kernel/host.c index f8cf1680..64dc8d04 100644 --- a/kernel/host.c +++ b/kernel/host.c @@ -474,6 +474,8 @@ extern void process_procfs_request(unsigned long rarg); extern int memcheckall(); extern int freecheck(int runcount); extern int runcount; +extern void terminate_host(int pid); +extern void debug_log(long); static int syscall_packet_handler(struct ihk_ikc_channel_desc *c, void *__packet, void *ihk_os) @@ -547,6 +549,14 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c, case SCD_MSG_PROCFS_REQUEST: process_procfs_request(packet->arg); return 0; + case SCD_MSG_CLEANUP_PROCESS: + dkprintf("SCD_MSG_CLEANUP_PROCESS pid=%d\n", packet->pid); + terminate_host(packet->pid); + return 0; + case SCD_MSG_DEBUG_LOG: + dkprintf("SCD_MSG_DEBUG_LOG code=%lx\n", packet->arg); + debug_log(packet->arg); + return 0; } return 0; } diff --git a/kernel/include/process.h b/kernel/include/process.h index 65b06c6b..35c86b0e 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -327,6 +327,7 @@ struct process { } thread; volatile int sigevent; + int nohost; sigset_t sigmask; stack_t sigstack; ihk_spinlock_t sigpendinglock; diff --git a/kernel/include/syscall.h b/kernel/include/syscall.h index 543ef47b..b9976d0a 100644 --- a/kernel/include/syscall.h +++ b/kernel/include/syscall.h @@ -34,12 +34,15 @@ #define SCD_MSG_SYSCALL_ONESIDE 0x4 #define SCD_MSG_SEND_SIGNAL 0x8 +#define SCD_MSG_CLEANUP_PROCESS 0x9 #define SCD_MSG_PROCFS_CREATE 0x10 #define SCD_MSG_PROCFS_DELETE 0x11 #define SCD_MSG_PROCFS_REQUEST 0x12 #define SCD_MSG_PROCFS_ANSWER 0x13 +#define SCD_MSG_DEBUG_LOG 0x20 + #define ARCH_SET_GS 0x1001 #define ARCH_SET_FS 0x1002 #define ARCH_GET_FS 0x1003 diff --git a/kernel/process.c b/kernel/process.c index 84771dc2..0d8f586e 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -2247,3 +2247,29 @@ process_unlock(void *savelock, unsigned long irqstate) { ihk_mc_spinlock_unlock((ihk_spinlock_t *)savelock, irqstate); } + +void +debug_log(unsigned long arg) +{ + struct cpu_local_var *v; + struct process *p; + int i; + extern int num_processors; + unsigned long irqstate; + + switch(arg){ + case 1: + for(i = 0; i < num_processors; i++){ + v = get_cpu_local_var(i); + irqstate = ihk_mc_spinlock_lock(&(v->runq_lock)); + list_for_each_entry(p, &(v->runq), sched_list){ + if(p->ftn->pid <= 0) + continue; + kprintf("cpu=%d pid=%d tid=%d status=%d\n", + i, p->ftn->pid, p->ftn->tid, p->ftn->status); + } + ihk_mc_spinlock_unlock(&(v->runq_lock), irqstate); + } + break; + } +} diff --git a/kernel/syscall.c b/kernel/syscall.c index e4e55ed8..e05c259c 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -546,7 +546,8 @@ terminate(int rc, int sig, ihk_mc_user_context_t *ctx) /* XXX: send SIGKILL to all threads in this process */ flush_process_memory(proc); /* temporary hack */ - do_syscall(&request, ctx, ihk_mc_get_processor_id(), 0); + if(!proc->nohost) + do_syscall(&request, ctx, ihk_mc_get_processor_id(), 0); #define IS_DETACHED_PROCESS(proc) (1) /* should be implemented in the future */ @@ -610,6 +611,44 @@ terminate(int rc, int sig, ihk_mc_user_context_t *ctx) schedule(); } +void terminate_host(int pid) +{ + struct cpu_local_var *v; + struct process *p; + int i; + unsigned long irqstate; + extern int num_processors; + int *tids; + int n; + siginfo_t info; + + memset(&info, '\0', sizeof info); + info.si_signo = SIGKILL; + info.si_code = SI_KERNEL; + + tids = kmalloc(sizeof(int) * num_processors, IHK_MC_AP_NOWAIT); + if(!tids) + return; + + for(n = 0, i = 0; i < num_processors; i++){ + v = get_cpu_local_var(i); + irqstate = ihk_mc_spinlock_lock(&(v->runq_lock)); + list_for_each_entry(p, &(v->runq), sched_list){ + if(p->ftn->pid == pid){ + p->nohost = 1; + tids[n] = p->ftn->tid; + n++; + } + } + ihk_mc_spinlock_unlock(&(v->runq_lock), irqstate); + } + for(i = 0; i < n; i++){ + do_kill(pid, tids[i], SIGKILL, &info); + } + + kfree(tids); +} + void interrupt_syscall(int pid, int cpuid) {