Fix to procfs read returns EIO
Refs: #1152 Change-Id: I48b330953fd7674ba1a3ac35744f9f50a5712730
This commit is contained in:
committed by
Masamichi Takagi
parent
1387c9687b
commit
14660a10c3
@ -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:
|
||||
|
||||
@ -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) */
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user