diff --git a/executer/kernel/mcctrl/ikc.c b/executer/kernel/mcctrl/ikc.c index 50fdead8..a7cb0271 100644 --- a/executer/kernel/mcctrl/ikc.c +++ b/executer/kernel/mcctrl/ikc.c @@ -182,6 +182,7 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c, case SCD_MSG_PREPARE_PROCESS_ACKED: case SCD_MSG_PERF_ACK: case SCD_MSG_SEND_SIGNAL_ACK: + case SCD_MSG_PROCFS_ANSWER: mcctrl_wakeup_cb(__os, pisp); break; @@ -189,11 +190,6 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c, mcexec_syscall(usrdata, pisp); break; - case SCD_MSG_PROCFS_ANSWER: - procfs_answer(usrdata, pisp->pid); - break; - - case SCD_MSG_SYSFS_REQ_CREATE: case SCD_MSG_SYSFS_REQ_MKDIR: case SCD_MSG_SYSFS_REQ_SYMLINK: diff --git a/executer/kernel/mcctrl/mcctrl.h b/executer/kernel/mcctrl/mcctrl.h index 1761861b..c1386659 100644 --- a/executer/kernel/mcctrl/mcctrl.h +++ b/executer/kernel/mcctrl/mcctrl.h @@ -455,7 +455,6 @@ struct procfs_read { int count; /* bytes to read (request) */ int eof; /* if eof is detected, 1 otherwise 0. (answer)*/ int ret; /* read bytes (answer) */ - int status; /* non-zero if done (answer) */ int newcpu; /* migrated new cpu (answer) */ int readwrite; /* 0:read, 1:write */ char fname[PROCFS_NAME_MAX]; /* procfs filename (request) */ diff --git a/executer/kernel/mcctrl/procfs.c b/executer/kernel/mcctrl/procfs.c index 0f27d9e4..4a148e7b 100644 --- a/executer/kernel/mcctrl/procfs.c +++ b/executer/kernel/mcctrl/procfs.c @@ -103,33 +103,6 @@ getpath(struct procfs_list_entry *e, char *buf, int bufsize) } } -/** - * \brief Process SCD_MSG_PROCFS_ANSWER message. - * - * \param ud mcctrl_usrdata pointer - * \param pid PID of the requesting process - */ -void procfs_answer(struct mcctrl_usrdata *ud, int pid) -{ - struct mcctrl_per_proc_data *ppd = NULL; - - if (pid > 0) { - ppd = mcctrl_get_per_proc_data(ud, pid); - - if (unlikely(!ppd)) { - kprintf("%s: ERROR: no per-process structure for PID %d\n", - __FUNCTION__, pid); - return; - } - } - - wake_up_all(pid > 0 ? &ppd->wq_procfs : &ud->wq_procfs); - - if (pid > 0) { - mcctrl_put_per_proc_data(ppd); - } -} - static struct procfs_list_entry * find_procfs_entry(struct procfs_list_entry *parent, const char *name) { @@ -520,7 +493,7 @@ static ssize_t __mckernel_procfs_read_write( int order = 0; volatile struct procfs_read *r = NULL; struct ikc_scd_packet isp; - int ret, osnum, pid, retw; + int ret, osnum, pid; unsigned long pbuf; size_t count = nbytes; size_t copy_size = 0; @@ -615,11 +588,11 @@ static ssize_t __mckernel_procfs_read_write( while (count > 0) { int this_len = min_t(ssize_t, count, copy_size); + int do_free; r->pbuf = pbuf; r->eof = 0; r->ret = -EIO; /* default */ - r->status = 0; r->offset = offset; r->count = this_len; r->readwrite = read_write; @@ -629,50 +602,26 @@ static ssize_t __mckernel_procfs_read_write( isp.arg = virt_to_phys(r); isp.pid = pid; - ret = mcctrl_ikc_send(osnum_to_os(e->osnum), - (pid > 0) ? ppd->ikc_target_cpu : 0, &isp); + ret = mcctrl_ikc_send_wait(osnum_to_os(e->osnum), + (pid > 0) ? ppd->ikc_target_cpu : 0, + &isp, HZ, NULL, &do_free, 1, r); + + if (!do_free && ret >= 0) { + ret = -EIO; + } if (ret < 0) { - goto out; /* error */ - } - - /* Wait for a reply. */ - ret = -EIO; /* default exit code */ - dprintk("%s: waiting for reply\n", __FUNCTION__); - -retry_wait: - /* Wait for the status field of the procfs_read structure, - * wait on per-process or OS specific data depending on - * who the request is for. - */ - if (pid > 0) { - retw = wait_event_interruptible_timeout(ppd->wq_procfs, - r->status != 0, HZ); - } - else { - retw = wait_event_interruptible_timeout(udp->wq_procfs, - r->status != 0, HZ); - } - - /* Timeout? */ - if (retw == 0 && r->status == 0) { - printk("%s: error: timeout (1 sec)\n", __FUNCTION__); + if (ret == -ETIME) { + pr_info("%s: error: timeout (1 sec)\n", + __func__); + } + else if (ret == -ERESTARTSYS) { + ret = -ERESTART; + } + if (!do_free) + r = NULL; goto out; } - /* Interrupted? */ - else if (retw == -ERESTARTSYS) { - ret = -ERESTART; - goto out; - } - /* Were we woken up by a reply to another procfs request? */ - else if (r->status == 0) { - /* TODO: r->status is not set atomically, we could be woken - * up with status == 0 and it could change to 1 while in this - * code, we could potentially miss the wake_up()... - */ - printk("%s: stale wake-up, retrying\n", __FUNCTION__); - goto retry_wait; - } /* Wake up and check the result. */ dprintk("%s: woke up. ret: %d, eof: %d\n", @@ -728,7 +677,7 @@ static ssize_t __mckernel_procfs_read_write( int order = 0; volatile struct procfs_read *r = NULL; struct ikc_scd_packet isp; - int ret, osnum, pid, retw; + int ret, osnum, pid; unsigned long pbuf; unsigned long count = nbytes; #if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) @@ -743,6 +692,7 @@ static ssize_t __mckernel_procfs_read_write( ihk_os_t os = NULL; struct mcctrl_usrdata *udp = NULL; struct mcctrl_per_proc_data *ppd = NULL; + int do_free; if (count <= 0 || offset < 0) { return 0; @@ -822,7 +772,6 @@ static ssize_t __mckernel_procfs_read_write( r->pbuf = pbuf; r->eof = 0; r->ret = -EIO; /* default */ - r->status = 0; r->offset = offset; r->count = count; r->readwrite = read_write; @@ -832,50 +781,26 @@ static ssize_t __mckernel_procfs_read_write( isp.arg = virt_to_phys(r); isp.pid = pid; - ret = mcctrl_ikc_send(osnum_to_os(e->osnum), - (pid > 0) ? ppd->ikc_target_cpu : 0, &isp); + ret = mcctrl_ikc_send_wait(osnum_to_os(e->osnum), + (pid > 0) ? ppd->ikc_target_cpu : 0, + &isp, 5 * HZ, NULL, &do_free, 1, r); + + if (!do_free && ret >= 0) { + ret = -EIO; + } if (ret < 0) { - goto out; /* error */ - } - - /* Wait for a reply. */ - ret = -EIO; /* default exit code */ - dprintk("%s: waiting for reply\n", __FUNCTION__); - -retry_wait: - /* Wait for the status field of the procfs_read structure, - * wait on per-process or OS specific data depending on - * who the request is for. - */ - if (pid > 0) { - retw = wait_event_interruptible_timeout(ppd->wq_procfs, - r->status != 0, 5 * HZ); - } - else { - retw = wait_event_interruptible_timeout(udp->wq_procfs, - r->status != 0, 5 * HZ); - } - - /* Timeout? */ - if (retw == 0 && r->status == 0) { - printk("%s: error: timeout (1 sec)\n", __FUNCTION__); + if (ret == -ETIME) { + pr_info("%s: error: timeout (1 sec)\n", + __func__); + } + else if (ret == -ERESTARTSYS) { + ret = -ERESTART; + } + if (!do_free) + r = NULL; goto out; } - /* Interrupted? */ - else if (retw == -ERESTARTSYS) { - ret = -ERESTART; - goto out; - } - /* Were we woken up by a reply to another procfs request? */ - else if (r->status == 0) { - /* TODO: r->status is not set atomically, we could be woken - * up with status == 0 and it could change to 1 while in this - * code, we could potentially miss the wake_up()... - */ - printk("%s: stale wake-up, retrying\n", __FUNCTION__); - goto retry_wait; - } /* Wake up and check the result. */ dprintk("%s: woke up. ret: %d, eof: %d\n", diff --git a/kernel/host.c b/kernel/host.c index 0942b240..cfedb483 100644 --- a/kernel/host.c +++ b/kernel/host.c @@ -562,7 +562,6 @@ static void syscall_channel_send(struct ihk_ikc_channel_desc *c, } extern unsigned long do_kill(struct thread *, int, int, int, struct siginfo *, int ptracecont); -extern void process_procfs_request(struct ikc_scd_packet *rpacket); extern void terminate_host(int pid); extern void debug_log(long); @@ -668,7 +667,13 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c, break; case SCD_MSG_PROCFS_REQUEST: - process_procfs_request(packet); + pckt.msg = SCD_MSG_PROCFS_ANSWER; + pckt.ref = packet->ref; + pckt.arg = packet->arg; + pckt.err = process_procfs_request(packet); + pckt.reply = packet->reply; + pckt.pid = packet->pid; + syscall_channel_send(resp_channel, &pckt); ret = 0; break; diff --git a/kernel/include/syscall.h b/kernel/include/syscall.h index b0764558..8d08549a 100644 --- a/kernel/include/syscall.h +++ b/kernel/include/syscall.h @@ -383,7 +383,6 @@ struct procfs_read { int count; /* bytes to read (request) */ int eof; /* if eof is detected, 1 otherwise 0. (answer)*/ int ret; /* read bytes (answer) */ - int status; /* non-zero if done (answer) */ int newcpu; /* migrated new cpu (answer) */ int readwrite; /* 0:read, 1:write */ char fname[PROCFS_NAME_MAX]; /* procfs filename (request) */ @@ -395,6 +394,8 @@ struct procfs_file { char fname[PROCFS_NAME_MAX]; /* procfs filename (request) */ }; +int process_procfs_request(struct ikc_scd_packet *rpacket); + #define RUSAGE_SELF 0 #define RUSAGE_CHILDREN -1 #define RUSAGE_THREAD 1 diff --git a/kernel/procfs.c b/kernel/procfs.c index 651ac227..0fdea252 100644 --- a/kernel/procfs.c +++ b/kernel/procfs.c @@ -75,7 +75,7 @@ procfs_delete_thread(struct thread *thread) * * \param rarg returned argument */ -void process_procfs_request(struct ikc_scd_packet *rpacket) +int process_procfs_request(struct ikc_scd_packet *rpacket) { unsigned long rarg = rpacket->arg; unsigned long parg, pbuf; @@ -83,28 +83,24 @@ void process_procfs_request(struct ikc_scd_packet *rpacket) struct process *proc = NULL; struct process_vm *vm = NULL; struct procfs_read *r; - struct ikc_scd_packet packet; int osnum = ihk_mc_get_osnum(); int rosnum, ret, pid, tid, ans = -EIO, eof = 0; char *buf, *p; - struct ihk_ikc_channel_desc *syscall_channel; struct mcs_rwlock_node_irqsave lock; unsigned long offset; int count; int npages; int readwrite = 0; + int err = -EIO; dprintf("process_procfs_request: invoked.\n"); - syscall_channel = get_cpu_local_var(0)->ikc2linux; - dprintf("rarg: %x\n", rarg); parg = ihk_mc_map_memory(NULL, rarg, sizeof(struct procfs_read)); dprintf("parg: %x\n", parg); r = ihk_mc_map_virtual(parg, 1, PTATTR_WRITABLE | PTATTR_ACTIVE); if (r == NULL) { kprintf("ERROR: process_procfs_request: got a null procfs_read structure.\n"); - packet.err = -EIO; goto dataunavail; } dprintf("r: %p\n", r); @@ -118,7 +114,6 @@ void process_procfs_request(struct ikc_scd_packet *rpacket) dprintf("buf: %p\n", buf); if (buf == NULL) { kprintf("ERROR: process_procfs_request: got a null buffer.\n"); - packet.err = -EIO; goto bufunavail; } @@ -695,28 +690,19 @@ end: dprintf("ret: %d, eof: %d\n", ans, eof); r->ret = ans; r->eof = eof; - r->status = 1; /* done */ - packet.err = 0; + err = 0; bufunavail: ihk_mc_unmap_memory(NULL, pbuf, r->count); ihk_mc_unmap_virtual(r, 1); dataunavail: ihk_mc_unmap_memory(NULL, parg, sizeof(struct procfs_read)); - packet.msg = SCD_MSG_PROCFS_ANSWER; - packet.arg = rarg; - packet.pid = rpacket->pid; - - ret = ihk_ikc_send(syscall_channel, &packet, 0); - if (ret < 0) { - kprintf("ERROR: sending IKC msg, ret: %d\n", ret); - } if(proc) release_process(proc); if(thread) release_thread(thread); if(vm) release_process_vm(vm); - return; + return err; }