diff --git a/arch/x86/kernel/gencore.c b/arch/x86/kernel/gencore.c index 9bde3b62..5cb4baa6 100644 --- a/arch/x86/kernel/gencore.c +++ b/arch/x86/kernel/gencore.c @@ -9,7 +9,7 @@ #define align32(x) ((((x) + 3) / 4) * 4) #define alignpage(x) ((((x) + (PAGE_SIZE) - 1) / (PAGE_SIZE)) * (PAGE_SIZE)) -#define DEBUG_PRINT_GENCORE +//#define DEBUG_PRINT_GENCORE #ifdef DEBUG_PRINT_GENCORE #define dkprintf(...) kprintf(__VA_ARGS__) diff --git a/arch/x86/kernel/syscall.c b/arch/x86/kernel/syscall.c index 92b8be1e..b9059f9f 100644 --- a/arch/x86/kernel/syscall.c +++ b/arch/x86/kernel/syscall.c @@ -207,6 +207,7 @@ do_signal(unsigned long rc, void *regs0, struct process *proc, struct sig_pendin int irqstate; for(w = pending->sigmask.__val[0], sig = 0; w; sig++, w >>= 1); + dkprintf("do_signal,pid=%d,sig=%d\n", proc->pid, sig); if(regs == NULL){ /* call from syscall */ asm("movq %%gs:132, %0" : "=r" (regs)); @@ -313,13 +314,10 @@ do_signal(unsigned long rc, void *regs0, struct process *proc, struct sig_pendin /* Wake up the parent who tried wait4 and sleeping */ waitq_wakeup(&proc->ftn->parent->waitpid_q); - dkprintf("do_signal,SIGTRAP,sleeping\n"); /* Sleep */ + dkprintf("do_signal,SIGTRAP,sleeping\n"); proc->status = PS_TRACED; - //struct cpu_local_var *v = get_this_cpu_local_var(); - //v->flags |= CPU_FLAG_NEED_RESCHED; - schedule(); dkprintf("SIGTRAP(): woken up\n"); break; } @@ -357,6 +355,8 @@ static int ptrace_report_signal(struct process *proc, struct sig_pending *pendin __sigset_t w; long rc; + dkprintf("ptrace_report_signal,pid=%d\n", proc->pid); + /* Save reason why stopped and process state for wait to reap */ for (w = pending->sigmask.__val[0], sig = 0; w; sig++, w >>= 1); ihk_mc_spinlock_lock_noirq(&proc->ftn->lock); @@ -673,10 +673,10 @@ do_kill(int pid, int tid, int sig, siginfo_t *info) if(doint && !(mask & tproc->sigmask.__val[0])){ switch(sig) { + case SIGKILL: case SIGCONT: break; case SIGSTOP: - case SIGKILL: default: if(proc != tproc){ dkprintf("do_kill,ipi,pid=%d,cpu_id=%d\n", @@ -697,6 +697,13 @@ do_kill(int pid, int tid, int sig, siginfo_t *info) tproc->pid, tproc->cpu_id); interrupt_syscall(tproc->pid, tproc->cpu_id); #endif + /* Wake up the target only when stopped by ptrace-reporting */ + sched_wakeup_process(tproc, PS_TRACED); + ihk_mc_spinlock_lock_noirq(&tproc->ftn->lock); + if (tproc->ftn->status & PS_TRACED) { + xchg4((int *)(&tproc->ftn->status), PS_RUNNING); + } + ihk_mc_spinlock_unlock_noirq(&tproc->ftn->lock); break; case SIGCONT: /* Wake up the target only when stopped by SIGSTOP */ diff --git a/kernel/init.c b/kernel/init.c index 39deea57..66a808e2 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -141,7 +141,7 @@ void pc_init(void) osnum += *p++ - '0'; } } - kprintf("osnum: %d\n", osnum); + dkprintf("osnum: %d\n", osnum); if (!(p = find_command_line("perfctr"))) { diff --git a/kernel/process.c b/kernel/process.c index 4ae6473c..abfaf748 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -48,6 +48,11 @@ static void insert_vm_range_list(struct process_vm *vm, static int copy_user_ranges(struct process *proc, struct process *org); void settid(struct process *proc, int mode, int newcpuid, int oldcpuid); +int refcount_fork_tree_node(struct fork_tree_node *ftn) +{ + return ihk_atomic_read(&ftn->refcount); +} + void hold_fork_tree_node(struct fork_tree_node *ftn) { ihk_atomic_inc(&ftn->refcount); @@ -318,23 +323,48 @@ err_free_proc: } int ptrace_traceme(void){ + int error = 0; struct process *proc = cpu_local_var(current); - struct fork_tree_node *ftn = proc->ftn, *parent; + struct fork_tree_node *child, *next; + dkprintf("ptrace_traceme,pid=%d,proc->ftn->parent=%p\n", proc->pid, proc->ftn->parent); - ftn->ptrace = PT_TRACED; - - parent = ftn->parent; - if (parent != NULL) { - ftn->ppid_parent = parent; - - ihk_mc_spinlock_lock_noirq(&parent->lock); - list_add_tail(&ftn->ptrace_siblings_list, &parent->ptrace_children); - ihk_mc_spinlock_unlock_noirq(&parent->lock); + if (proc->ftn->parent == NULL) { + error = -EPERM; + goto out; } - return 0; -} + dkprintf("ptrace_traceme,parent->pid=%d\n", proc->ftn->parent->pid); + + ihk_mc_spinlock_lock_noirq(&proc->ftn->lock); + + proc->ftn->ptrace = PT_TRACED; + proc->ftn->ppid_parent = proc->ftn->parent; + + ihk_mc_spinlock_lock_noirq(&proc->ftn->parent->lock); + list_for_each_entry_safe(child, next, &proc->ftn->parent->children, siblings_list) { + if(child == proc->ftn) { + list_del(&child->siblings_list); + goto found; + } + } + kprintf("ptrace_traceme,not found\n"); + error = -EPERM; + goto out_notfound; + found: + list_add_tail(&proc->ftn->ptrace_siblings_list, &proc->ftn->parent->ptrace_children); + + ihk_mc_spinlock_unlock_noirq(&proc->ftn->parent->lock); + + ihk_mc_spinlock_unlock_noirq(&proc->ftn->lock); + out: + dkprintf("ptrace_traceme,returning,error=%d\n", error); + return error; + out_notfound: + ihk_mc_spinlock_unlock_noirq(&proc->ftn->parent->lock); + ihk_mc_spinlock_unlock_noirq(&proc->ftn->lock); + goto out; +} static int copy_user_ranges(struct process *proc, struct process *org) { diff --git a/kernel/syscall.c b/kernel/syscall.c index 7575111a..c0ae4880 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -301,16 +301,12 @@ static int wait_zombie(struct process *proc, struct fork_tree_node *child, int * int ret; struct syscall_request request IHK_DMA_ALIGN; - dkprintf("wait: found PS_ZOMBIE process: %d\n", child->pid); - - list_del(&child->siblings_list); + dkprintf("wait_zombie,found PS_ZOMBIE process: %d\n", child->pid); if (status) { *status = child->exit_status; } - release_fork_tree_node(child); - /* Ask host to clean up exited child */ request.number = __NR_wait4; request.args[0] = child->pid; @@ -401,7 +397,6 @@ SYSCALL_DECLARE(wait4) pid = (int)ihk_mc_syscall_arg0(ctx); ihk_mc_spinlock_lock_noirq(&proc->ftn->lock); - list_for_each_entry(child_iter, &proc->ftn->children, siblings_list) { ihk_mc_spinlock_lock_noirq(&child_iter->lock); @@ -416,6 +411,8 @@ SYSCALL_DECLARE(wait4) if(child_iter->status == PS_ZOMBIE) { ret = wait_zombie(proc, child_iter, status, ctx); if(ret) { + list_del(&child_iter->siblings_list); + release_fork_tree_node(child_iter); goto out_found; } } @@ -440,7 +437,6 @@ SYSCALL_DECLARE(wait4) ihk_mc_spinlock_unlock_noirq(&child_iter->lock); } - list_for_each_entry(child_iter, &proc->ftn->ptrace_children, ptrace_siblings_list) { ihk_mc_spinlock_lock_noirq(&child_iter->lock); @@ -455,6 +451,8 @@ SYSCALL_DECLARE(wait4) if(child_iter->status == PS_ZOMBIE) { ret = wait_zombie(proc, child_iter, status, ctx); if(ret) { + list_del(&child_iter->ptrace_siblings_list); + release_fork_tree_node(child_iter); goto out_found; } } @@ -510,8 +508,10 @@ SYSCALL_DECLARE(wait4) exit: return ret; out_found: + dkprintf("wait4,out_found\n"); ihk_mc_spinlock_unlock_noirq(&child_iter->lock); out_notfound: + dkprintf("wait4,out_notfound\n"); ihk_mc_spinlock_unlock_noirq(&proc->ftn->lock); goto exit; } @@ -526,6 +526,7 @@ terminate(int rc, int sig, ihk_mc_user_context_t *ctx) struct process *parent_owner; int error; + dkprintf("terminate,pid=%d\n", proc->pid); request.number = __NR_exit_group; request.args[0] = ((rc & 0x00ff) << 8) | (sig & 0xff); @@ -546,10 +547,14 @@ terminate(int rc, int sig, ihk_mc_user_context_t *ctx) list_del(&child->siblings_list); release_fork_tree_node(child); } + list_for_each_entry_safe(child, next, &ftn->ptrace_children, ptrace_siblings_list) { + list_del(&child->ptrace_siblings_list); + release_fork_tree_node(child); + } ftn->owner = NULL; ihk_mc_spinlock_unlock_noirq(&ftn->lock); - /* Send SIGCHILD to parent */ + /* Send SIGCHLD to parent */ if (ftn->parent) { int parent_owner_pid; @@ -584,19 +589,18 @@ terminate(int rc, int sig, ihk_mc_user_context_t *ctx) /* sigchld_parent(ftn->parent->owner, 0); */ - dkprintf("terminate,klll SIGCHILD,error=%d\n", + dkprintf("terminate,klll SIGCHLD,error=%d\n", error); } - + release_fork_tree_node(ftn->parent); } else { ihk_mc_spinlock_lock_noirq(&ftn->lock); ftn->status = PS_EXITED; ihk_mc_spinlock_unlock_noirq(&ftn->lock); } - release_fork_tree_node(ftn); - + proc->status = PS_EXITED; release_process(proc); @@ -1565,6 +1569,7 @@ unsigned long do_fork(int clone_flags, unsigned long newsp, cpuid = obtain_clone_cpuid(); if (cpuid == -1) { + kprintf("do_fork,core not available\n"); return -EAGAIN; }