From 43e54dcf854623f7374f16645c928c227ba00abe Mon Sep 17 00:00:00 2001 From: Naoki Hamada Date: Mon, 22 Sep 2014 10:46:33 +0900 Subject: [PATCH 1/3] procfs: fix for http://postpeta.pccluster.org/redmine/issues/119#note-30 --- executer/kernel/mcctrl.h | 2 +- executer/kernel/procfs.c | 35 ++++++++++++----------------------- kernel/include/syscall.h | 2 +- kernel/procfs.c | 1 + 4 files changed, 15 insertions(+), 25 deletions(-) diff --git a/executer/kernel/mcctrl.h b/executer/kernel/mcctrl.h index 1abe4550..8c00b58f 100644 --- a/executer/kernel/mcctrl.h +++ b/executer/kernel/mcctrl.h @@ -164,9 +164,9 @@ struct procfs_read { unsigned long pbuf; /* physical address of the host buffer (request) */ unsigned long offset; /* offset to read (request) */ int count; /* bytes to read (request) */ - int error; /* non-zero if below fields are invalid. (answer) */ 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) */ char fname[PROCFS_NAME_MAX]; /* procfs filename (request) */ }; diff --git a/executer/kernel/procfs.c b/executer/kernel/procfs.c index a9695d9d..62785931 100644 --- a/executer/kernel/procfs.c +++ b/executer/kernel/procfs.c @@ -26,7 +26,6 @@ #endif static DECLARE_WAIT_QUEUE_HEAD(procfsq); -static unsigned long procfsq_channel; int mckernel_procfs_read(char *buffer, char **start, off_t offset, int count, int *peof, void *dat); @@ -254,11 +253,7 @@ void procfs_delete(void *__os, int osnum, unsigned long arg) void procfs_answer(unsigned int arg, int err) { - volatile struct procfs_read *r = phys_to_virt(arg); - dprintk("procfs: received SCD_MSG_PROCFS_ANSWER message(err = %d).\n", err); - procfsq_channel = arg; - r->error = err; wake_up_interruptible(&procfsq); } @@ -277,7 +272,6 @@ int mckernel_procfs_read(char *buffer, char **start, off_t offset, struct ikc_scd_packet isp; int ret, retrycount = 0; unsigned long pbuf; - int i; dprintk("mckernel_procfs_read: invoked for %s\n", e->fname); @@ -299,7 +293,8 @@ retry: r->pbuf = pbuf; r->eof = 0; - r->ret = PAGE_SIZE * 2; /* dummy answer */ + r->ret = -EIO; /* default */ + r->status = 0; r->offset = offset; r->count = count; strncpy((char *)r->fname, e->fname, PROCFS_NAME_MAX); @@ -308,32 +303,25 @@ retry: isp.arg = virt_to_phys(r); ret = mcctrl_ikc_send(e->os, e->cpu, &isp); if (ret < 0) { - return ret; /* error */ + goto out; /* error */ } /* Wait for a reply. */ + ret = -EIO; /* default exit code */ dprintk("now wait for a relpy\n"); - wait_event_interruptible(procfsq, procfsq_channel == virt_to_phys(r)); - /* Wake up and check the result. */ - dprintk("mckernel_procfs_read: woke up.\n"); - if (r->error != 0) { - kprintf("ERROR: mckernel_procfs_read: failed to get valid answer.\n"); - return -EIO; - } - for (i = 0; r->ret == PAGE_SIZE * 2; i++) { - /* FIXME: busy wait for the real answer to reach*/; - if (i > 1000000) { - kprintf("ERROR: mckernel_procfs_read: answer unavailable.\n"); - return -EIO; - } + /* Wait for the status field of the procfs_read structure set ready. */ + if (wait_event_interruptible_timeout(procfsq, r->status != 0, HZ) == 0) { + kprintf("ERROR: mckernel_procfs_read: timeout (1 sec).\n"); + goto out; } - dprintk("ret: %d, eof: %d (wait loop count: %d)\n", r->ret, r->eof, i); + /* Wake up and check the result. */ + dprintk("mckernel_procfs_read: woke up. ret: %d, eof: %d\n", r->ret, r->eof); if ((r->ret == 0) && (r->eof != 1)) { /* A miss-hit caused by migration has occurred. * We simply retry the query with a new CPU. */ if (retrycount++ > 10) { kprintf("ERROR: mckernel_procfs_read: excessive retry.\n"); - return -EIO; + goto out; } e->cpu = r->newcpu; dprintk("retry\n"); @@ -345,6 +333,7 @@ retry: } *start = buffer; ret = r->ret; +out: kfree((void *)r); return ret; diff --git a/kernel/include/syscall.h b/kernel/include/syscall.h index 5960d221..284930aa 100644 --- a/kernel/include/syscall.h +++ b/kernel/include/syscall.h @@ -251,9 +251,9 @@ struct procfs_read { unsigned long pbuf; /* physical address of the host buffer (request) */ unsigned long offset; /* offset to read (request) */ int count; /* bytes to read (request) */ - int error; /* non-zero if below fields are invalid. (answer) */ 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) */ char fname[PROCFS_NAME_MAX]; /* procfs filename (request) */ }; diff --git a/kernel/procfs.c b/kernel/procfs.c index b8a8f8c5..e7ddb73d 100644 --- a/kernel/procfs.c +++ b/kernel/procfs.c @@ -449,6 +449,7 @@ end: dprintf("ret: %d, eof: %d\n", ans, eof); r->ret = ans; r->eof = eof; + r->status = 1; /* done */ packet.err = 0; bufunavail: ihk_mc_unmap_memory(NULL, pbuf, r->count); From 434597e6296e77d935bab48e171d2a84fe26f08e Mon Sep 17 00:00:00 2001 From: Masamichi Takagi Date: Tue, 23 Sep 2014 11:52:00 +0900 Subject: [PATCH 2/3] Make lock/unlock in lock.c accord with arch-lock.h Make both of the lock/unlock function pairs use the same interfaces. --- arch/x86/kernel/lock.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/arch/x86/kernel/lock.c b/arch/x86/kernel/lock.c index ee8a7369..b9a7efdb 100644 --- a/arch/x86/kernel/lock.c +++ b/arch/x86/kernel/lock.c @@ -19,12 +19,14 @@ void ihk_mc_spinlock_init(ihk_spinlock_t *lock) *lock = 0; } -void ihk_mc_spinlock_lock(ihk_spinlock_t *lock, unsigned long *flags) +unsigned long ihk_mc_spinlock_lock(ihk_spinlock_t *lock) { int inc = 0x00010000; int tmp; - - cpu_disable_interrupt_save(flags); + unsigned long flags; + + flags = cpu_disable_interrupt_save(); + asm volatile("lock ; xaddl %0, %1\n" "movzwl %w0, %2\n\t" "shrl $16, %0\n\t" @@ -36,12 +38,13 @@ void ihk_mc_spinlock_lock(ihk_spinlock_t *lock, unsigned long *flags) "jmp 1b\n" "2:" : "+Q" (inc), "+m" (*lock), "=r" (tmp) : : "memory", "cc"); + return flags; } -void ihk_mc_spinlock_unlock(ihk_spinlock_t *lock, unsigned long *flags) +void ihk_mc_spinlock_unlock(ihk_spinlock_t *lock, unsigned long flags) { asm volatile ("lock incw %0" : "+m"(*lock) : : "memory", "cc"); - cpu_restore_interrupt(*flags); + cpu_restore_interrupt(flags); } #endif From a7b0880a8d4d87a78eb247330d28d9ff6b54da0f Mon Sep 17 00:00:00 2001 From: Masamichi Takagi Date: Tue, 23 Sep 2014 12:01:51 +0900 Subject: [PATCH 3/3] Make findthread_and_lock take ihk_spinlock_t ** --- kernel/include/process.h | 2 +- kernel/process.c | 6 +++--- kernel/procfs.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/kernel/include/process.h b/kernel/include/process.h index 9d0c743e..b3f5f7a1 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -282,7 +282,7 @@ void check_need_resched(void); void cpu_set(int cpu, cpu_set_t *cpu_set, ihk_spinlock_t *lock); void cpu_clear(int cpu, cpu_set_t *cpu_set, ihk_spinlock_t *lock); -struct process *findthread_and_lock(int pid, int tid, void *savelock, unsigned long *irqstate); +struct process *findthread_and_lock(int pid, int tid, ihk_spinlock_t **savelock, unsigned long *irqstate); void process_unlock(void *savelock, unsigned long irqstate); #endif diff --git a/kernel/process.c b/kernel/process.c index c6430c43..012a809e 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -2066,7 +2066,7 @@ void runq_del_proc(struct process *proc, int cpu_id) } struct process * -findthread_and_lock(int pid, int tid, void *savelock, unsigned long *irqstate) +findthread_and_lock(int pid, int tid, ihk_spinlock_t **savelock, unsigned long *irqstate) { struct cpu_local_var *v; struct process *p; @@ -2075,11 +2075,11 @@ findthread_and_lock(int pid, int tid, void *savelock, unsigned long *irqstate) for(i = 0; i < num_processors; i++){ v = get_cpu_local_var(i); - *(ihk_spinlock_t **)savelock = &(v->runq_lock); + *savelock = &(v->runq_lock); *irqstate = ihk_mc_spinlock_lock(&(v->runq_lock)); list_for_each_entry(p, &(v->runq), sched_list){ if(p->pid == pid && - p->tid == tid){ + (tid == -1 || p->tid == tid)){ return p; } } diff --git a/kernel/procfs.c b/kernel/procfs.c index e7ddb73d..08acf7c0 100644 --- a/kernel/procfs.c +++ b/kernel/procfs.c @@ -200,7 +200,7 @@ void process_procfs_request(unsigned long rarg) int rosnum, ret, pid, tid, ans = -EIO, eof = 0; char *buf, *p; struct ihk_ikc_channel_desc *syscall_channel; - void *savelock; + ihk_spinlock_t *savelock; unsigned long irqstate; dprintf("process_procfs_request: invoked.\n");