Fix to procfs read returns EIO

Refs: #1152
Change-Id: I48b330953fd7674ba1a3ac35744f9f50a5712730
This commit is contained in:
Tomoki Shirasawa
2018-07-11 11:13:01 +09:00
committed by Masamichi Takagi
parent 1387c9687b
commit 14660a10c3
6 changed files with 50 additions and 138 deletions

View File

@ -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:

View File

@ -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) */

View File

@ -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",

View File

@ -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;

View File

@ -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

View File

@ -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;
}