diff --git a/arch/x86/kernel/include/syscall_list.h b/arch/x86/kernel/include/syscall_list.h index 275e1e5a..cdf514a9 100644 --- a/arch/x86/kernel/include/syscall_list.h +++ b/arch/x86/kernel/include/syscall_list.h @@ -151,7 +151,7 @@ SYSCALL_HANDLED(603, pmc_stop) SYSCALL_HANDLED(604, pmc_reset) SYSCALL_HANDLED(700, get_cpu_id) #ifdef TRACK_SYSCALLS -SYSCALL_HANDLED(701, syscall_offload_clr_cntrs) +SYSCALL_HANDLED(__NR_track_syscalls, track_syscalls) #endif // TRACK_SYSCALLS /**** End of File ****/ diff --git a/kernel/include/process.h b/kernel/include/process.h index a948ce86..d712af44 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -232,8 +232,6 @@ enum mpol_rebind_step { #include #include -//#define TRACK_SYSCALLS - struct resource_set; struct process_hash; struct thread_hash; @@ -244,6 +242,28 @@ struct process_vm; struct vm_regions; struct vm_range; +//#define TRACK_SYSCALLS + +#ifdef TRACK_SYSCALLS +#define TRACK_SYSCALLS_MAX 300 +#define __NR_track_syscalls 701 + +#define TRACK_SYSCALLS_CLEAR 0x01 +#define TRACK_SYSCALLS_ON 0x02 +#define TRACK_SYSCALLS_OFF 0x04 +#define TRACK_SYSCALLS_PRINT 0x08 +#define TRACK_SYSCALLS_PRINT_PROC 0x10 + +void track_syscalls_print_thread_stats(struct thread *thread); +void track_syscalls_print_proc_stats(struct process *proc); +void track_syscalls_accumulate_counters(struct thread *thread, + struct process *proc); +void track_syscalls_alloc_counters(struct thread *thread); +void track_syscalls_dealloc_thread_counters(struct thread *thread); +void track_syscalls_dealloc_proc_counters(struct process *proc); +#endif // TRACK_SYSCALLS + + #define HASH_SIZE 73 struct resource_set { @@ -539,6 +559,13 @@ struct process { #define PP_COUNT 2 #define PP_STOP 3 struct mc_perf_event *monitoring_event; +#ifdef TRACK_SYSCALLS + mcs_lock_node_t st_lock; + uint64_t *syscall_times; + uint32_t *syscall_cnts; + uint64_t *offload_times; + uint32_t *offload_cnts; +#endif // TRACK_SYSCALLS }; void hold_thread(struct thread *ftn); @@ -612,7 +639,7 @@ struct thread { int in_syscall_offload; #ifdef TRACK_SYSCALLS - int socc_enabled; + int track_syscalls; uint64_t *syscall_times; uint32_t *syscall_cnts; uint64_t *offload_times; diff --git a/kernel/process.c b/kernel/process.c index 1dae876d..449845bb 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -101,6 +101,13 @@ init_process(struct process *proc, struct process *parent) waitq_init(&proc->waitpid_q); ihk_atomic_set(&proc->refcount, 2); proc->monitoring_event = NULL; +#ifdef TRACK_SYSCALLS + mcs_lock_init(&proc->st_lock); + proc->syscall_times = NULL; + proc->syscall_cnts = NULL; + proc->offload_times = NULL; + proc->offload_cnts = NULL; +#endif } void @@ -468,6 +475,9 @@ clone_thread(struct thread *org, unsigned long pc, unsigned long sp, ihk_mc_spinlock_init(&thread->spin_sleep_lock); thread->spin_sleep = 0; +#ifdef TRACK_SYSCALLS + thread->track_syscalls = org->track_syscalls; +#endif return thread; @@ -2155,6 +2165,10 @@ release_process(struct process *proc) } if (proc->tids) kfree(proc->tids); +#ifdef TRACK_SYSCALLS + track_syscalls_print_proc_stats(proc); + track_syscalls_dealloc_proc_counters(proc); +#endif // TRACK_SYSCALLS kfree(proc); } @@ -2338,6 +2352,11 @@ void release_thread(struct thread *thread) vm = thread->vm; +#ifdef TRACK_SYSCALLS + track_syscalls_accumulate_counters(thread, thread->proc); + //track_syscalls_print_thread_stats(thread); + track_syscalls_dealloc_thread_counters(thread); +#endif // TRACK_SYSCALLS procfs_delete_thread(thread); destroy_thread(thread); diff --git a/kernel/syscall.c b/kernel/syscall.c index 201453d1..5e75d112 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -94,8 +94,8 @@ static long (*syscall_table[])(int, ihk_mc_user_context_t *) = { #define MCKERNEL_UNUSED __attribute__ ((unused)) static char *syscall_name[] MCKERNEL_UNUSED = { #define DECLARATOR(number,name) [number] = #name, -#define SYSCALL_HANDLED(number,name) DECLARATOR(number,sys_##name) -#define SYSCALL_DELEGATED(number,name) DECLARATOR(number,sys_##name) +#define SYSCALL_HANDLED(number,name) DECLARATOR(number,#name) +#define SYSCALL_DELEGATED(number,name) DECLARATOR(number,#name) #include #undef DECLARATOR #undef SYSCALL_HANDLED @@ -132,24 +132,20 @@ static void do_mod_exit(int status); #ifdef TRACK_SYSCALLS -#define SOCC_CLEAR 1 -#define SOCC_ON 2 -#define SOCC_OFF 4 -#define SOCC_PRINT 8 - -void print_syscall_stats(struct thread *thread) +void track_syscalls_print_thread_stats(struct thread *thread) { int i; unsigned long flags; flags = kprintf_lock(); - for (i = 0; i < 300; ++i) { + for (i = 0; i < TRACK_SYSCALLS_MAX; ++i) { if (!thread->syscall_cnts[i] && !thread->offload_cnts[i]) continue; //__kprintf("(%20s): sys.cnt: %3lu (%15lukC)\n", - __kprintf("(%3d,%20s): sys.cnt: %5lu (%10lukC), offl.cnt: %5lu (%10lukC)\n", + __kprintf("TID: %4d (%3d,%20s): sys: %6u %6lukC offl: %6u %6lukC\n", + thread->tid, i, syscall_name[i], thread->syscall_cnts[i], @@ -166,38 +162,150 @@ void print_syscall_stats(struct thread *thread) kprintf_unlock(flags); } -void alloc_syscall_counters(struct thread *thread) +void track_syscalls_print_proc_stats(struct process *proc) { - thread->syscall_times = kmalloc(sizeof(*thread->syscall_times) * 300, IHK_MC_AP_NOWAIT); - thread->syscall_cnts = kmalloc(sizeof(*thread->syscall_cnts) * 300, IHK_MC_AP_NOWAIT); - thread->offload_times = kmalloc(sizeof(*thread->offload_times) * 300, IHK_MC_AP_NOWAIT); - thread->offload_cnts = kmalloc(sizeof(*thread->offload_cnts) * 300, IHK_MC_AP_NOWAIT); + int i; + unsigned long flags; + + flags = kprintf_lock(); + + for (i = 0; i < TRACK_SYSCALLS_MAX; ++i) { + if (!proc->syscall_cnts[i] && + !proc->offload_cnts[i]) continue; + + //__kprintf("(%20s): sys.cnt: %3lu (%15lukC)\n", + __kprintf("PID: %4d (%3d,%20s): sys: %6u %6lukC offl: %6u %6lukC\n", + proc->pid, + i, + syscall_name[i], + proc->syscall_cnts[i], + (proc->syscall_times[i] / + (proc->syscall_cnts[i] ? proc->syscall_cnts[i] : 1)) + / 1000, + proc->offload_cnts[i], + (proc->offload_times[i] / + (proc->offload_cnts[i] ? proc->offload_cnts[i] : 1)) + / 1000 + ); + } + + kprintf_unlock(flags); +} + +void track_syscalls_accumulate_counters(struct thread *thread, + struct process *proc) +{ + int i; + struct mcs_lock_node mcs_node; + + mcs_lock_lock(&proc->st_lock, &mcs_node); + for (i = 0; i < TRACK_SYSCALLS_MAX; ++i) { + if (thread->syscall_cnts[i]) { + proc->syscall_times[i] += thread->syscall_times[i]; + proc->syscall_cnts[i] += thread->syscall_cnts[i]; + } + + if (thread->offload_cnts[i]) { + proc->offload_times[i] += thread->offload_times[i]; + proc->offload_cnts[i] += thread->offload_cnts[i]; + } + } + mcs_lock_unlock(&proc->st_lock, &mcs_node); +} + +void track_syscalls_alloc_counters(struct thread *thread) +{ + struct process *proc = thread->proc; + struct mcs_lock_node mcs_node; + + thread->syscall_times = kmalloc(sizeof(*thread->syscall_times) * + TRACK_SYSCALLS_MAX, IHK_MC_AP_NOWAIT); + thread->syscall_cnts = kmalloc(sizeof(*thread->syscall_cnts) * + TRACK_SYSCALLS_MAX, IHK_MC_AP_NOWAIT); + thread->offload_times = kmalloc(sizeof(*thread->offload_times) * + TRACK_SYSCALLS_MAX, IHK_MC_AP_NOWAIT); + thread->offload_cnts = kmalloc(sizeof(*thread->offload_cnts) * + TRACK_SYSCALLS_MAX, IHK_MC_AP_NOWAIT); if (!thread->syscall_times || !thread->syscall_cnts || !thread->offload_times || !thread->offload_cnts) { - kprintf("ERROR: allocating counters\n"); + kprintf("%s: ERROR: allocating thread private counters\n", + __FUNCTION__); panic(""); } - memset(thread->syscall_times, 0, sizeof(*thread->syscall_times) * 300); - memset(thread->syscall_cnts, 0, sizeof(*thread->syscall_cnts) * 300); - memset(thread->offload_times, 0, sizeof(*thread->offload_times) * 300); - memset(thread->offload_cnts, 0, sizeof(*thread->offload_cnts) * 300); + memset(thread->syscall_times, 0, sizeof(*thread->syscall_times) * + TRACK_SYSCALLS_MAX); + memset(thread->syscall_cnts, 0, sizeof(*thread->syscall_cnts) * + TRACK_SYSCALLS_MAX); + memset(thread->offload_times, 0, sizeof(*thread->offload_times) * + TRACK_SYSCALLS_MAX); + memset(thread->offload_cnts, 0, sizeof(*thread->offload_cnts) * + TRACK_SYSCALLS_MAX); + + mcs_lock_lock(&proc->st_lock, &mcs_node); + if (!proc->syscall_times) { + proc->syscall_times = kmalloc(sizeof(*proc->syscall_times) * + TRACK_SYSCALLS_MAX, IHK_MC_AP_NOWAIT); + proc->syscall_cnts = kmalloc(sizeof(*proc->syscall_cnts) * + TRACK_SYSCALLS_MAX, IHK_MC_AP_NOWAIT); + proc->offload_times = kmalloc(sizeof(*proc->offload_times) * + TRACK_SYSCALLS_MAX, IHK_MC_AP_NOWAIT); + proc->offload_cnts = kmalloc(sizeof(*proc->offload_cnts) * + TRACK_SYSCALLS_MAX, IHK_MC_AP_NOWAIT); + + if (!proc->syscall_times || + !proc->syscall_cnts || + !proc->offload_times || + !proc->offload_cnts) { + kprintf("%s: ERROR: allocating process private counters\n", + __FUNCTION__); + panic(""); + } + + memset(proc->syscall_times, 0, sizeof(*proc->syscall_times) * + TRACK_SYSCALLS_MAX); + memset(proc->syscall_cnts, 0, sizeof(*proc->syscall_cnts) * + TRACK_SYSCALLS_MAX); + memset(proc->offload_times, 0, sizeof(*proc->offload_times) * + TRACK_SYSCALLS_MAX); + memset(proc->offload_cnts, 0, sizeof(*proc->offload_cnts) * + TRACK_SYSCALLS_MAX); + } + mcs_lock_unlock(&proc->st_lock, &mcs_node); } -SYSCALL_DECLARE(syscall_offload_clr_cntrs) +void track_syscalls_dealloc_thread_counters(struct thread *thread) +{ + kfree(thread->syscall_times); + kfree(thread->syscall_cnts); + kfree(thread->offload_times); + kfree(thread->offload_cnts); +} + +void track_syscalls_dealloc_proc_counters(struct process *proc) +{ + kfree(proc->syscall_times); + kfree(proc->syscall_cnts); + kfree(proc->offload_times); + kfree(proc->offload_cnts); +} + +int do_track_syscalls(int flag) { - int flag = (int)ihk_mc_syscall_arg0(ctx); struct thread *thread = cpu_local_var(current); int i; - if (flag & SOCC_PRINT) - print_syscall_stats(thread); + if (flag & TRACK_SYSCALLS_PRINT) + track_syscalls_print_thread_stats(thread); - if (flag & SOCC_CLEAR) { - for (i = 0; i < 300; ++i) { + if (flag & TRACK_SYSCALLS_PRINT_PROC) + track_syscalls_print_proc_stats(thread->proc); + + if (flag & TRACK_SYSCALLS_CLEAR) { + for (i = 0; i < TRACK_SYSCALLS_MAX; ++i) { if (!thread->syscall_cnts[i] && !thread->offload_cnts[i]) continue; @@ -208,15 +316,21 @@ SYSCALL_DECLARE(syscall_offload_clr_cntrs) } } - if (flag & SOCC_ON) { - thread->socc_enabled = 1; + if (flag & TRACK_SYSCALLS_ON) { + thread->track_syscalls = 1; } - else if (flag & SOCC_OFF) { - thread->socc_enabled = 0; + else if (flag & TRACK_SYSCALLS_OFF) { + thread->track_syscalls = 0; } return 0; } + +SYSCALL_DECLARE(track_syscalls) +{ + int flag = (int)ihk_mc_syscall_arg0(ctx); + return do_track_syscalls(flag); +} #endif // TRACK_SYSCALLS static void send_syscall(struct syscall_request *req, int cpu, int pid, struct syscall_response *res) @@ -390,18 +504,19 @@ long do_syscall(struct syscall_request *req, int cpu, int pid) } #ifdef TRACK_SYSCALLS - if (req->number < 300) { + if (req->number < TRACK_SYSCALLS_MAX) { if (!cpu_local_var(current)->offload_cnts) { - alloc_syscall_counters(cpu_local_var(current)); + track_syscalls_alloc_counters(cpu_local_var(current)); } - if (cpu_local_var(current)->socc_enabled) { + if (cpu_local_var(current)->track_syscalls) { cpu_local_var(current)->offload_times[req->number] += (rdtsc() - t_s); - cpu_local_var(current)->offload_cnts[req->number]++; + cpu_local_var(current)->offload_cnts[req->number] += 1; } } else { - dkprintf("offload syscall > 300?? : %d\n", req->number); + dkprintf("%s: offload syscall > %d ?? : %d\n", + __FUNCTION__, TRACK_SYSCALLS_MAX, req->number); } #endif // TRACK_SYSCALLS @@ -8523,6 +8638,7 @@ long syscall(int num, ihk_mc_user_context_t *ctx) dkprintf("\n"); #ifdef TRACK_SYSCALLS + if (num == __NR_clone) cpu_local_var(current)->track_syscalls = 1; t_s = rdtsc(); #endif // TRACK_SYSCALLS @@ -8547,18 +8663,20 @@ long syscall(int num, ihk_mc_user_context_t *ctx) } #ifdef TRACK_SYSCALLS - if (num < 300) { + if (num < TRACK_SYSCALLS_MAX) { if (!cpu_local_var(current)->syscall_cnts) { - alloc_syscall_counters(cpu_local_var(current)); + track_syscalls_alloc_counters(cpu_local_var(current)); } - if (cpu_local_var(current)->socc_enabled) { + if (cpu_local_var(current)->track_syscalls) { cpu_local_var(current)->syscall_times[num] += (rdtsc() - t_s); cpu_local_var(current)->syscall_cnts[num]++; } } else { - if (num != 701) - kprintf("syscall > 300?? : %d\n", num); + if (num != __NR_track_syscalls) { + dkprintf("%s: syscall > %d ?? : %d\n", + __FUNCTION__, TRACK_SYSCALLS_MAX, num); + } } #endif // TRACK_SYSCALLS