From 2698cb85c9cbaa25e7a63fc2da588a1aca412df8 Mon Sep 17 00:00:00 2001 From: "Masamichi Takagi m-takagi@ab.jp.nec.com" Date: Fri, 2 Nov 2012 20:53:02 +0900 Subject: [PATCH] add syscalls (pmc_init, pmc_start, pmc_stop, pmc_reset) for performance monitoring instructions --- kernel/init.c | 12 +++-- kernel/syscall.c | 113 ++++++++++++++++++++++++++++++++++++++-- linux/executer/mcexec.c | 42 ++++++++------- 3 files changed, 137 insertions(+), 30 deletions(-) diff --git a/kernel/init.c b/kernel/init.c index f52b4ddf..8d5e99f7 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -97,11 +97,13 @@ void pc_init(void) int imode = 1; char *p; - int x[2][4] = { { APT_TYPE_INSTRUCTIONS, - APT_TYPE_L1D_MISS, - APT_TYPE_L2_MISS, APT_TYPE_L1I_MISS, }, - { APT_TYPE_L1I_MISS, APT_TYPE_LLC_MISS, - APT_TYPE_STALL, APT_TYPE_CYCLE }, + int x[2][4] = { { APT_TYPE_INSTRUCTIONS_EXECUTED, + APT_TYPE_DATA_READ_MISS, + APT_TYPE_L2_CODE_READ_MISS_MEM_FILL, + APT_TYPE_CODE_CACHE_MISS, }, + { APT_TYPE_CODE_CACHE_MISS, + APT_TYPE_LLC_MISS, // not updated for KNC + APT_TYPE_STALL, APT_TYPE_CYCLE }, // not updated for KNC }; if (!(p = find_command_line("perfctr"))) { diff --git a/kernel/syscall.c b/kernel/syscall.c index a0ea8172..b74aa9b8 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -17,6 +17,7 @@ #include #include #include +#include /* Headers taken from kitten LWK */ #include @@ -979,6 +980,71 @@ SYSCALL_DECLARE(noop) return -EFAULT; } +#ifdef DCFA_KMOD + +extern int ibmic_cmd_syscall(char *uargs); +extern int dcfampi_cmd_syscall(char *uargs); + +static int (*mod_call_table[]) (char *) = { + [1] = ibmic_cmd_syscall, + [2] = dcfampi_cmd_syscall, +}; + +SYSCALL_DECLARE(mod_call) { + int mod_id; + unsigned long long uargs; + + mod_id = aal_mc_syscall_arg0(ctx); + uargs = aal_mc_syscall_arg1(ctx); + + dkprintf("mod_call id:%d, uargs=0x%llx, type=%s, command=%x\n", mod_id, uargs, mod_id==1?"ibmic":"dcfampi", *((uint32_t*)(((char*)uargs)+0))); + + if(mod_call_table[mod_id]) + return mod_call_table[mod_id]((char*)uargs); + + return -ENOSYS; +} +#endif + +SYSCALL_DECLARE(process_data_section) { + unsigned long s = cpu_local_var(current)->vm->region.data_start; + unsigned long e = cpu_local_var(current)->vm->region.data_end; + *((unsigned long*)aal_mc_syscall_arg0(ctx)) = s; + *((unsigned long*)aal_mc_syscall_arg1(ctx)) = e; + return 0; +} + +/* select counter type */ +SYSCALL_DECLARE(pmc_init) +{ + int counter = aal_mc_syscall_arg0(ctx); + + enum aal_perfctr_type type = (enum aal_perfctr_type)aal_mc_syscall_arg1(ctx); + /* see aal/manycore/generic/include/aal/perfctr.h */ + + int mode = PERFCTR_USER_MODE; + + return aal_mc_perfctr_init(counter, type, mode); +} + +SYSCALL_DECLARE(pmc_start) +{ + unsigned long counter = aal_mc_syscall_arg0(ctx); + return aal_mc_perfctr_start(1 << counter); +} + +SYSCALL_DECLARE(pmc_stop) +{ + unsigned long counter = aal_mc_syscall_arg0(ctx); + return aal_mc_perfctr_stop(1 << counter); +} + +SYSCALL_DECLARE(pmc_reset) +{ + int counter = aal_mc_syscall_arg0(ctx); + return aal_mc_perfctr_reset(counter); +} + static long (*syscall_table[])(int, aal_mc_user_context_t *) = { [0] = sys_read, [1] = sys_write, @@ -1025,6 +1091,14 @@ static long (*syscall_table[])(int, aal_mc_user_context_t *) = { [234] = sys_tgkill, [273] = sys_set_robust_list, [288] = NULL, +#ifdef DCFA_KMOD + [303] = sys_mod_call, +#endif + [502] = sys_process_data_section, + [601] = sys_pmc_init, + [602] = sys_pmc_start, + [603] = sys_pmc_stop, + [604] = sys_pmc_reset, }; static char *syscall_name[] = { @@ -1075,6 +1149,14 @@ static char *syscall_name[] = { [234] = "sys_tgkill", [273] = "sys_set_robust_list", [288] = "NULL", +#ifdef DCFA_KMOD + [303] = "sys_mod_call", +#endif + [502] = "process_data_section", + [601] = "sys_pmc_init", + [602] = "sys_pmc_start", + [603] = "sys_pmc_stop", + [604] = "sys_pmc_reset", }; #if 0 @@ -1098,11 +1180,32 @@ long syscall(int num, aal_mc_user_context_t *ctx) cpu_enable_interrupt(); - dkprintf("SC(%d)[%3d=%s](%lx, %lx) @ %lx | %lx = ", - aal_mc_get_processor_id(), - num, syscall_name[num], - aal_mc_syscall_arg0(ctx), aal_mc_syscall_arg1(ctx), - aal_mc_syscall_pc(ctx), aal_mc_syscall_sp(ctx)); +#if 0 + if(num != 24) // if not sched_yield +#endif + dkprintf("SC(%d:%d)[%3d=%s](%lx, %lx,%lx, %lx, %lx, %lx)@%lx,sp:%lx", + aal_mc_get_processor_id(), + aal_mc_get_hardware_processor_id(), + num, syscall_name[num], + aal_mc_syscall_arg0(ctx), aal_mc_syscall_arg1(ctx), + aal_mc_syscall_arg2(ctx), aal_mc_syscall_arg3(ctx), + aal_mc_syscall_arg4(ctx), aal_mc_syscall_arg5(ctx), + aal_mc_syscall_pc(ctx), aal_mc_syscall_sp(ctx)); +#if 1 +#if 0 + if(num != 24) // if not sched_yield +#endif + dkprintf(",*sp:%lx,*(sp+8):%lx,*(sp+16):%lx,*(sp+24):%lx", + *((unsigned long*)aal_mc_syscall_sp(ctx)), + *((unsigned long*)(aal_mc_syscall_sp(ctx)+8)), + *((unsigned long*)(aal_mc_syscall_sp(ctx)+16)), + *((unsigned long*)(aal_mc_syscall_sp(ctx)+24))); +#endif +#if 0 + if(num != 24) // if not sched_yield +#endif + dkprintf("\n"); + if (syscall_table[num]) { l = syscall_table[num](num, ctx); diff --git a/linux/executer/mcexec.c b/linux/executer/mcexec.c index 3df7342f..5682fe6d 100644 --- a/linux/executer/mcexec.c +++ b/linux/executer/mcexec.c @@ -203,7 +203,7 @@ void print_desc(struct program_load_desc *desc) desc->status, desc->cpu, desc->pid, desc->entry, desc->rprocess); for (i = 0; i < desc->num_sections; i++) { - __dprintf("vaddr: %lx, mem_len: %ld, remote_pa: %lx, files: %ld\n", + __dprintf("vaddr: %lx, mem_len: %lx, remote_pa: %lx, files: %lx\n", desc->sections[i].vaddr, desc->sections[i].len, desc->sections[i].remote_pa, desc->sections[i].filesz); } @@ -222,12 +222,12 @@ void print_flat(char *flat) { char **string; - printf("counter: %d\n", *((int *)flat)); + __dprintf("counter: %d\n", *((int *)flat)); string = (char **)(flat + sizeof(int)); while (*string) { - printf("%s\n", (flat + (unsigned long)(*string))); + __dprintf("%s\n", (flat + (unsigned long)(*string))); ++string; } @@ -376,13 +376,13 @@ int main(int argc, char **argv) dma_buf = mmap(0, PIN_SIZE, PROT_READ | PROT_WRITE, (MAP_ANONYMOUS | MAP_PRIVATE), -1, 0); if (!dma_buf) { - printf("error: allocating DMA area\n"); + __dprint("error: allocating DMA area\n"); exit(1); } /* PIN buffer */ if (mlock(dma_buf, (size_t)PIN_SIZE)) { - printf("ERROR: locking dma_buf\n"); + __dprint("ERROR: locking dma_buf\n"); exit(1); } @@ -495,7 +495,7 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock) break; case __NR_close: - printf("mcexec.c,close,fd=%lx\n", w.sr.args[0]); + __dprintf("mcexec.c,close,fd=%lx\n", w.sr.args[0]); ret = close(w.sr.args[0]); SET_ERR(ret); do_syscall_return(fd, cpu, ret, 0, 0, 0, 0); @@ -571,6 +571,7 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock) } case __NR_fstat: ret = fstat(w.sr.args[0], (void *)dma_buf); + __dprintf("mcexec.c:main_loop,arg[0]=%ld,ret=%d\n", w.sr.args[0], ret); if (ret == -1) { ret = -errno; } @@ -608,7 +609,7 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock) ret = time(NULL); } SET_ERR(ret); - printf("time=%ld\n", ret); + __dprintf("time=%ld\n", ret); do_syscall_return(fd, cpu, ret, 1, (unsigned long)dma_buf, w.sr.args[0], sizeof(time_t)); break; } @@ -616,6 +617,7 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock) case __NR_gettimeofday: ret = gettimeofday((struct timeval *)dma_buf, NULL); SET_ERR(ret); + __dprintf("gettimeofday=%016ld,%09ld\n", ((struct timeval *)dma_buf)->tv_sec, ((struct timeval *)dma_buf)->tv_usec); do_syscall_return(fd, cpu, ret, 1, (unsigned long)dma_buf, w.sr.args[0], sizeof(struct timeval)); break; @@ -666,7 +668,7 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock) // note that return type is different between glibc-getcwd and sys_getcwd char* c = getcwd((void *)dma_buf, w.sr.args[1]); ret = (c == 0) ? -errno : strnlen((const char*)dma_buf, w.sr.args[1]); - printf("getcwd result: %s\n", dma_buf); + __dprintf("getcwd result: %s\n", dma_buf); do_syscall_return(fd, cpu, ret, 1, (unsigned long)dma_buf, w.sr.args[0], c == 0 ? 0 : ret + 1); break; } @@ -674,7 +676,7 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock) case __NR_access: { dma_buf[256] = 0; do_syscall_load(fd, cpu, (unsigned long)dma_buf, w.sr.args[0], 256); - printf("access: %s\n", dma_buf); + __dprintf("access: %s\n", dma_buf); int c = access((void *)dma_buf, w.sr.args[1]); ret = (c < 0) ? -errno : c; do_syscall_return(fd, cpu, ret, 0, 0, 0, 0); @@ -685,7 +687,7 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock) switch(w.sr.args[1]) { case F_GETFD: c = fcntl(w.sr.args[0], w.sr.args[1]); - printf("fcntl,F_GETFD,c=%x\n", c); + __dprintf("fcntl,F_GETFD,c=%x\n", c); ret = (c < 0) ? -errno : c; break; default: @@ -704,7 +706,7 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock) case __NR_readlink: { dma_buf[256] = 0; do_syscall_load(fd, cpu, (unsigned long)dma_buf, w.sr.args[0], 256); - printf("readlink: %s\n", dma_buf); + __dprintf("readlink: %s\n", dma_buf); char* dup = strndup((char *)dma_buf, 256); int c = readlink(dup, (void *)dma_buf, w.sr.args[2]); free(dup); @@ -721,39 +723,39 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock) case __NR_mmap: { // w.sr.args[0] is converted to MIC physical address - printf("mcexec.c,mmap,MIC-paddr=%lx,len=%lx,prot=%lx,flags=%lx,fd=%lx,offset=%lx\n", + __dprintf("mcexec.c,mmap,MIC-paddr=%lx,len=%lx,prot=%lx,flags=%lx,fd=%lx,offset=%lx\n", w.sr.args[0], w.sr.args[1], w.sr.args[2], w.sr.args[3], w.sr.args[4], w.sr.args[5]); off_t old_off = lseek(w.sr.args[4], 0, SEEK_CUR); - if(old_off == -1) { printf("mcexec.c,mmap,lseek failed\n"); ret = -errno; goto mmap_out; } + if(old_off == -1) { __dprint("mcexec.c,mmap,lseek failed\n"); ret = -errno; goto mmap_out; } off_t rlseek = lseek(w.sr.args[4], w.sr.args[5], SEEK_SET); - if(rlseek == -1) { printf("mcexec.c,mmap,lseek failed\n"); ret = -errno; goto mmap_out; } + if(rlseek == -1) { __dprint("mcexec.c,mmap,lseek failed\n"); ret = -errno; goto mmap_out; } ssize_t toread = w.sr.args[1]; ret = 0; while(toread > 0) { - printf("mcexec.c,mmap,read,addr=%lx,len=%lx\n", (long int)((void *)dma_buf + w.sr.args[1] - toread), toread); + __dprintf("mcexec.c,mmap,read,addr=%lx,len=%lx\n", (long int)((void *)dma_buf + w.sr.args[1] - toread), toread); ssize_t rread = read(w.sr.args[4], (void *)dma_buf + w.sr.args[1] - toread, toread); if(rread == 0) { - printf("mcexec.c,mmap,read==0\n"); + __dprint("mcexec.c,mmap,read==0\n"); goto mmap_zero_out; } else if(rread < 0) { - printf("mcexec.c,mmap,read failed\n"); ret = -errno; break; + __dprint("mcexec.c,mmap,read failed\n"); ret = -errno; break; } toread -= rread; } mmap_zero_out: rlseek = lseek(w.sr.args[4], old_off, SEEK_SET); - if(rlseek == -1) { printf("mcexec.c,mmap,lseek failed\n"); ret = -errno; } + if(rlseek == -1) { __dprint("mcexec.c,mmap,lseek failed\n"); ret = -errno; } mmap_out: do_syscall_return(fd, cpu, ret, 1, (unsigned long)dma_buf, w.sr.args[0], w.sr.args[1]); break; } default: - printf("Unhandled system calls: %ld\n", w.sr.number); + __dprintf("Unhandled system calls: %ld\n", w.sr.number); break; } pthread_mutex_unlock(lock); } - printf("timed out.\n"); + __dprint("timed out.\n"); return 1; }