procfs: add support for <pid>/mem files and ad hoc fix for memory incoherency.
This commit is contained in:
@@ -164,6 +164,7 @@ struct procfs_read {
|
|||||||
unsigned long pbuf; /* physical address of the host buffer (request) */
|
unsigned long pbuf; /* physical address of the host buffer (request) */
|
||||||
unsigned long offset; /* offset to read (request) */
|
unsigned long offset; /* offset to read (request) */
|
||||||
int count; /* bytes 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 eof; /* if eof is detected, 1 otherwise 0. (answer)*/
|
||||||
int ret; /* read bytes (answer) */
|
int ret; /* read bytes (answer) */
|
||||||
int newcpu; /* migrated new cpu (answer) */
|
int newcpu; /* migrated new cpu (answer) */
|
||||||
|
|||||||
@@ -254,8 +254,11 @@ void procfs_delete(void *__os, int osnum, unsigned long arg)
|
|||||||
|
|
||||||
void procfs_answer(unsigned int arg, int err)
|
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);
|
dprintk("procfs: received SCD_MSG_PROCFS_ANSWER message(err = %d).\n", err);
|
||||||
procfsq_channel = arg;
|
procfsq_channel = arg;
|
||||||
|
r->error = err;
|
||||||
wake_up_interruptible(&procfsq);
|
wake_up_interruptible(&procfsq);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,6 +277,7 @@ int mckernel_procfs_read(char *buffer, char **start, off_t offset,
|
|||||||
struct ikc_scd_packet isp;
|
struct ikc_scd_packet isp;
|
||||||
int ret, retrycount = 0;
|
int ret, retrycount = 0;
|
||||||
unsigned long pbuf;
|
unsigned long pbuf;
|
||||||
|
int i;
|
||||||
|
|
||||||
dprintk("mckernel_procfs_read: invoked for %s\n", e->fname);
|
dprintk("mckernel_procfs_read: invoked for %s\n", e->fname);
|
||||||
|
|
||||||
@@ -295,7 +299,7 @@ retry:
|
|||||||
|
|
||||||
r->pbuf = pbuf;
|
r->pbuf = pbuf;
|
||||||
r->eof = 0;
|
r->eof = 0;
|
||||||
r->ret = -EIO; /* default to error */
|
r->ret = PAGE_SIZE * 2; /* dummy answer */
|
||||||
r->offset = offset;
|
r->offset = offset;
|
||||||
r->count = count;
|
r->count = count;
|
||||||
strncpy((char *)r->fname, e->fname, PROCFS_NAME_MAX);
|
strncpy((char *)r->fname, e->fname, PROCFS_NAME_MAX);
|
||||||
@@ -310,7 +314,19 @@ retry:
|
|||||||
dprintk("now wait for a relpy\n");
|
dprintk("now wait for a relpy\n");
|
||||||
wait_event_interruptible(procfsq, procfsq_channel == virt_to_phys(r));
|
wait_event_interruptible(procfsq, procfsq_channel == virt_to_phys(r));
|
||||||
/* Wake up and check the result. */
|
/* 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)) {
|
if ((r->ret == 0) && (r->eof != 1)) {
|
||||||
/* A miss-hit caused by migration has occurred.
|
/* A miss-hit caused by migration has occurred.
|
||||||
* We simply retry the query with a new CPU.
|
* We simply retry the query with a new CPU.
|
||||||
@@ -324,6 +340,7 @@ retry:
|
|||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
if (r->eof == 1) {
|
if (r->eof == 1) {
|
||||||
|
dprintk("reached end of file.\n");
|
||||||
*peof = 1;
|
*peof = 1;
|
||||||
}
|
}
|
||||||
*start = buffer;
|
*start = buffer;
|
||||||
|
|||||||
@@ -251,6 +251,7 @@ struct procfs_read {
|
|||||||
unsigned long pbuf; /* physical address of the host buffer (request) */
|
unsigned long pbuf; /* physical address of the host buffer (request) */
|
||||||
unsigned long offset; /* offset to read (request) */
|
unsigned long offset; /* offset to read (request) */
|
||||||
int count; /* bytes 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 eof; /* if eof is detected, 1 otherwise 0. (answer)*/
|
||||||
int ret; /* read bytes (answer) */
|
int ret; /* read bytes (answer) */
|
||||||
int newcpu; /* migrated new cpu (answer) */
|
int newcpu; /* migrated new cpu (answer) */
|
||||||
|
|||||||
@@ -63,6 +63,9 @@ void create_proc_procfs_files(int pid, int cpuid)
|
|||||||
snprintf(fname, PROCFS_NAME_MAX, "mcos%d/%d/auxv", osnum, pid);
|
snprintf(fname, PROCFS_NAME_MAX, "mcos%d/%d/auxv", osnum, pid);
|
||||||
create_proc_procfs_file(pid, fname, 0400, cpuid);
|
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);
|
snprintf(fname, PROCFS_NAME_MAX, "mcos%d/%d/task/%d/mem", osnum, pid, pid);
|
||||||
create_proc_procfs_file(pid, fname, 0400, cpuid);
|
create_proc_procfs_file(pid, fname, 0400, cpuid);
|
||||||
|
|
||||||
@@ -97,7 +100,7 @@ void delete_proc_procfs_files(int pid)
|
|||||||
{
|
{
|
||||||
char fname[PROCFS_NAME_MAX];
|
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);
|
snprintf(fname, PROCFS_NAME_MAX, "mcos%d/%d/task/%d/mem", osnum, pid, pid);
|
||||||
delete_proc_procfs_file(pid, fname);
|
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);
|
snprintf(fname, PROCFS_NAME_MAX, "mcos%d/%d/task", osnum, pid);
|
||||||
delete_proc_procfs_file(pid, fname);
|
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);
|
snprintf(fname, PROCFS_NAME_MAX, "mcos%d/%d/auxv", osnum, pid);
|
||||||
delete_proc_procfs_file(pid, fname);
|
delete_proc_procfs_file(pid, fname);
|
||||||
|
|
||||||
snprintf(fname, PROCFS_NAME_MAX, "mcos%d/%d", osnum, pid);
|
snprintf(fname, PROCFS_NAME_MAX, "mcos%d/%d", osnum, pid);
|
||||||
delete_proc_procfs_file(pid, fname);
|
delete_proc_procfs_file(pid, fname);
|
||||||
|
|
||||||
/* CAVEAT: deleting mcos%d level procfs directory should be located
|
dprintf("delete procfs files for pid %d: done\n", pid);
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -286,6 +287,32 @@ void process_procfs_request(unsigned long rarg)
|
|||||||
dprintf("matched PID: %d.\n", pid);
|
dprintf("matched PID: %d.\n", pid);
|
||||||
p = strchr(p, '/') + 1;
|
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
|
* mcos%d/PID/auxv
|
||||||
*/
|
*/
|
||||||
@@ -301,6 +328,9 @@ void process_procfs_request(unsigned long rarg)
|
|||||||
if (r->offset + len == limit) {
|
if (r->offset + len == limit) {
|
||||||
eof = 1;
|
eof = 1;
|
||||||
}
|
}
|
||||||
|
} else if (r->offset == limit) {
|
||||||
|
ans = 0;
|
||||||
|
eof = 1;
|
||||||
}
|
}
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@@ -342,6 +372,9 @@ void process_procfs_request(unsigned long rarg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(p, "stat")) {
|
if (!strcmp(p, "stat")) {
|
||||||
|
char tmp[1024];
|
||||||
|
int len;
|
||||||
|
|
||||||
if ((proc = findthread_and_lock(pid, tid, &savelock, &irqstate))){
|
if ((proc = findthread_and_lock(pid, tid, &savelock, &irqstate))){
|
||||||
dprintf("thread found! pid=%d tid=%d\n", pid, tid);
|
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
|
* cnswap exit_signal processor rt_priority
|
||||||
* policy delayacct_blkio_ticks guest_time cguest_time
|
* policy delayacct_blkio_ticks guest_time cguest_time
|
||||||
*/
|
*/
|
||||||
ans = sprintf((char *)buf,
|
ans = sprintf(tmp,
|
||||||
"%d (%s) %c %d " // pid...
|
"%d (%s) %c %d " // pid...
|
||||||
"%d %d %d %d " // pgrp...
|
"%d %d %d %d " // pgrp...
|
||||||
"%u %lu %lu %lu " // flags...
|
"%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 " // kstkesp...
|
||||||
"%lu %lu %lu %lu " // sigignore...
|
"%lu %lu %lu %lu " // sigignore...
|
||||||
"%lu %d %d %u " // cnswap...
|
"%lu %d %d %u " // cnswap...
|
||||||
"%u %llu %lu %ld", // policy...
|
"%u %llu %lu %ld\n", // policy...
|
||||||
0, "exe", 'R', 0, // pid...
|
0, "exe", 'R', 0, // pid...
|
||||||
0, 0, 0, 0, // pgrp...
|
0, 0, 0, 0, // pgrp...
|
||||||
0, 0L, 0L, 0L, // flags...
|
0, 0L, 0L, 0L, // flags...
|
||||||
@@ -381,11 +414,22 @@ void process_procfs_request(unsigned long rarg)
|
|||||||
0L, 0, proc->cpu_id, 0, // cnswap...
|
0L, 0, proc->cpu_id, 0, // cnswap...
|
||||||
0, 0LL, 0L, 0L // policy...
|
0, 0LL, 0L, 0L // policy...
|
||||||
);
|
);
|
||||||
/* The target process has gone by migration. */
|
|
||||||
r->newcpu = proc->cpu_id;
|
|
||||||
process_unlock(savelock, irqstate);
|
process_unlock(savelock, irqstate);
|
||||||
eof = 1;
|
dprintf("tmp=%s\n", tmp);
|
||||||
dprintf("buf=%s\n", buf);
|
|
||||||
|
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;
|
goto end;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
|||||||
Reference in New Issue
Block a user