diff --git a/executer/kernel/mcctrl.h b/executer/kernel/mcctrl.h index 54bf54d6..1abe4550 100644 --- a/executer/kernel/mcctrl.h +++ b/executer/kernel/mcctrl.h @@ -164,6 +164,7 @@ 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 newcpu; /* migrated new cpu (answer) */ diff --git a/executer/kernel/procfs.c b/executer/kernel/procfs.c index ea4cb9dd..a9695d9d 100644 --- a/executer/kernel/procfs.c +++ b/executer/kernel/procfs.c @@ -254,8 +254,11 @@ 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); } @@ -274,6 +277,7 @@ 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); @@ -295,7 +299,7 @@ retry: r->pbuf = pbuf; r->eof = 0; - r->ret = -EIO; /* default to error */ + r->ret = PAGE_SIZE * 2; /* dummy answer */ r->offset = offset; r->count = count; strncpy((char *)r->fname, e->fname, PROCFS_NAME_MAX); @@ -310,7 +314,19 @@ retry: 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. ret: %d, eof: %d\n", r->ret, r->eof); + 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; + } + } + dprintk("ret: %d, eof: %d (wait loop count: %d)\n", r->ret, r->eof, i); if ((r->ret == 0) && (r->eof != 1)) { /* A miss-hit caused by migration has occurred. * We simply retry the query with a new CPU. @@ -324,6 +340,7 @@ retry: goto retry; } if (r->eof == 1) { + dprintk("reached end of file.\n"); *peof = 1; } *start = buffer; diff --git a/kernel/include/syscall.h b/kernel/include/syscall.h index d976e2a3..5960d221 100644 --- a/kernel/include/syscall.h +++ b/kernel/include/syscall.h @@ -251,6 +251,7 @@ 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 newcpu; /* migrated new cpu (answer) */ diff --git a/kernel/procfs.c b/kernel/procfs.c index 4897415e..b8a8f8c5 100644 --- a/kernel/procfs.c +++ b/kernel/procfs.c @@ -63,6 +63,9 @@ void create_proc_procfs_files(int pid, int cpuid) snprintf(fname, PROCFS_NAME_MAX, "mcos%d/%d/auxv", osnum, pid); create_proc_procfs_file(pid, fname, 0400, cpuid); + snprintf(fname, PROCFS_NAME_MAX, "mcos%d/%d/mem", osnum, pid); + create_proc_procfs_file(pid, fname, 0400, cpuid); + snprintf(fname, PROCFS_NAME_MAX, "mcos%d/%d/task/%d/mem", osnum, pid, pid); create_proc_procfs_file(pid, fname, 0400, cpuid); @@ -97,7 +100,7 @@ void delete_proc_procfs_files(int pid) { char fname[PROCFS_NAME_MAX]; - dprintf("delete procfs files\n"); + dprintf("delete procfs files for pid %d.\n", pid); snprintf(fname, PROCFS_NAME_MAX, "mcos%d/%d/task/%d/mem", osnum, pid, pid); delete_proc_procfs_file(pid, fname); @@ -110,18 +113,16 @@ void delete_proc_procfs_files(int pid) snprintf(fname, PROCFS_NAME_MAX, "mcos%d/%d/task", osnum, pid); delete_proc_procfs_file(pid, fname); + snprintf(fname, PROCFS_NAME_MAX, "mcos%d/%d/mem", osnum, pid); + delete_proc_procfs_file(pid, fname); + snprintf(fname, PROCFS_NAME_MAX, "mcos%d/%d/auxv", osnum, pid); delete_proc_procfs_file(pid, fname); snprintf(fname, PROCFS_NAME_MAX, "mcos%d/%d", osnum, pid); delete_proc_procfs_file(pid, fname); - /* CAVEAT: deleting mcos%d level procfs directory should be located - in delete_mckernel_procfs_files().*/ - snprintf(fname, PROCFS_NAME_MAX, "mcos%d", osnum); - delete_proc_procfs_file(pid, fname); - - dprintf("delete procfs files: done\n"); + dprintf("delete procfs files for pid %d: done\n", pid); } /** @@ -286,6 +287,32 @@ void process_procfs_request(unsigned long rarg) dprintf("matched PID: %d.\n", pid); p = strchr(p, '/') + 1; + /* + * mcos%d/PID/mem + * + * The offset is treated as the beginning of the virtual address area + * of the process. The count is the length of the area. + */ + if (strcmp(p, "mem") == 0) { + struct vm_range *range; + struct process_vm *vm = proc->vm; + + list_for_each_entry(range, &vm->vm_range_list, list) { + dprintf("range: %lx - %lx\n", range->start, range->end); + if ((range->start <= r->offset) && + (r->offset < range->end)) { + unsigned int len = r->count; + if (range->end < r->offset + r->count) { + len = range->end - r->offset; + } + memcpy((void *)buf, (void *)range->start, len); + ans = len; + break; + } + } + goto end; + } + /* * mcos%d/PID/auxv */ @@ -301,6 +328,9 @@ void process_procfs_request(unsigned long rarg) if (r->offset + len == limit) { eof = 1; } + } else if (r->offset == limit) { + ans = 0; + eof = 1; } goto end; } @@ -342,6 +372,9 @@ void process_procfs_request(unsigned long rarg) } if (!strcmp(p, "stat")) { + char tmp[1024]; + int len; + if ((proc = findthread_and_lock(pid, tid, &savelock, &irqstate))){ dprintf("thread found! pid=%d tid=%d\n", pid, tid); /* @@ -357,7 +390,7 @@ void process_procfs_request(unsigned long rarg) * cnswap exit_signal processor rt_priority * policy delayacct_blkio_ticks guest_time cguest_time */ - ans = sprintf((char *)buf, + ans = sprintf(tmp, "%d (%s) %c %d " // pid... "%d %d %d %d " // pgrp... "%u %lu %lu %lu " // flags... @@ -368,7 +401,7 @@ void process_procfs_request(unsigned long rarg) "%lu %lu %lu %lu " // kstkesp... "%lu %lu %lu %lu " // sigignore... "%lu %d %d %u " // cnswap... - "%u %llu %lu %ld", // policy... + "%u %llu %lu %ld\n", // policy... 0, "exe", 'R', 0, // pid... 0, 0, 0, 0, // pgrp... 0, 0L, 0L, 0L, // flags... @@ -381,11 +414,22 @@ void process_procfs_request(unsigned long rarg) 0L, 0, proc->cpu_id, 0, // cnswap... 0, 0LL, 0L, 0L // policy... ); - /* The target process has gone by migration. */ - r->newcpu = proc->cpu_id; process_unlock(savelock, irqstate); - eof = 1; - dprintf("buf=%s\n", buf); + dprintf("tmp=%s\n", tmp); + + len = strlen(tmp); + if (r->offset < len) { + if (r->offset + r->count < len) { + ans = r->count; + } else { + eof = 1; + ans = len; + } + strncpy(buf, tmp + r->offset, ans); + } else if (r->offset == len) { + ans = 0; + eof = 1; + } goto end; } else{