diff --git a/arch/x86/kernel/include/syscall_list.h b/arch/x86/kernel/include/syscall_list.h index cdf514a9..e868ee10 100644 --- a/arch/x86/kernel/include/syscall_list.h +++ b/arch/x86/kernel/include/syscall_list.h @@ -150,8 +150,8 @@ SYSCALL_HANDLED(602, pmc_start) SYSCALL_HANDLED(603, pmc_stop) SYSCALL_HANDLED(604, pmc_reset) SYSCALL_HANDLED(700, get_cpu_id) -#ifdef TRACK_SYSCALLS -SYSCALL_HANDLED(__NR_track_syscalls, track_syscalls) -#endif // TRACK_SYSCALLS +#ifdef PROFILE_ENABLE +SYSCALL_HANDLED(__NR_profile, profile) +#endif // PROFILE_ENABLE /**** End of File ****/ diff --git a/executer/include/uprotocol.h b/executer/include/uprotocol.h index c3fbe6b4..22199f76 100644 --- a/executer/include/uprotocol.h +++ b/executer/include/uprotocol.h @@ -132,6 +132,7 @@ struct program_load_desc { int nr_processes; char shell_path[SHELL_PATH_MAX_LEN]; __cpu_set_unit cpu_set[PLD_CPU_SET_SIZE]; + int profile; struct program_image_section sections[0]; }; diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c index f454e6da..ae237dde 100644 --- a/executer/user/mcexec.c +++ b/executer/user/mcexec.c @@ -159,6 +159,7 @@ static int mpol_no_stack = 0; static int mpol_no_bss = 0; static int no_bind_ikc_map = 0; static unsigned long mpol_threshold = 0; +static int profile = 0; /* Partitioned execution (e.g., for MPI) */ static int nr_processes = 0; @@ -1284,6 +1285,12 @@ static struct option mcexec_options[] = { .flag = &enable_vdso, .val = 1, }, + { + .name = "profile", + .has_arg = no_argument, + .flag = &profile, + .val = 1, + }, { .name = "mpol-no-heap", .has_arg = no_argument, @@ -1738,6 +1745,7 @@ int main(int argc, char **argv) } } + desc->profile = profile; desc->nr_processes = nr_processes; desc->mpol_flags = 0; if (mpol_no_heap) { diff --git a/kernel/host.c b/kernel/host.c index 7663627f..2a8aed6d 100644 --- a/kernel/host.c +++ b/kernel/host.c @@ -431,6 +431,10 @@ static int process_msg_prepare_process(unsigned long rphys) proc->mpol_flags = pn->mpol_flags; proc->mpol_threshold = pn->mpol_threshold; proc->nr_processes = pn->nr_processes; +#ifdef PROFILE_ENABLE + proc->profile = pn->profile; + thread->profile = pn->profile; +#endif vm->region.user_start = pn->user_start; vm->region.user_end = pn->user_end; diff --git a/kernel/include/process.h b/kernel/include/process.h index 5dc44596..f51ea09b 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -546,6 +546,7 @@ struct process { #define PP_STOP 3 struct mc_perf_event *monitoring_event; #ifdef PROFILE_ENABLE + int profile; mcs_lock_node_t profile_lock; struct profile_event *profile_events; #endif // PROFILE_ENABLE diff --git a/kernel/include/syscall.h b/kernel/include/syscall.h index b8f1d53f..c12e6114 100644 --- a/kernel/include/syscall.h +++ b/kernel/include/syscall.h @@ -197,6 +197,7 @@ struct program_load_desc { int nr_processes; char shell_path[SHELL_PATH_MAX_LEN]; __cpu_set_unit cpu_set[PLD_CPU_SET_SIZE]; + int profile; struct program_image_section sections[0]; }; diff --git a/kernel/process.c b/kernel/process.c index 97b21fe4..ebbb888f 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -414,6 +414,9 @@ clone_thread(struct thread *org, unsigned long pc, unsigned long sp, goto err_free_proc; memset(proc, '\0', sizeof(struct process)); init_process(proc, org->proc); +#ifdef PROFILE_ENABLE + proc->profile = org->proc->profile; +#endif proc->termsig = termsig; asp = create_address_space(cpu_local_var(resource_set), 1); @@ -522,7 +525,7 @@ clone_thread(struct thread *org, unsigned long pc, unsigned long sp, #endif #ifdef PROFILE_ENABLE - thread->profile = org->profile; + thread->profile = org->profile | proc->profile; #endif return thread; @@ -2218,11 +2221,13 @@ release_process(struct process *proc) if (proc->tids) kfree(proc->tids); #ifdef PROFILE_ENABLE - if (proc->nr_processes) { - profile_accumulate_and_print_job_events(proc); - } - else { - profile_print_proc_stats(proc); + if (proc->profile) { + if (proc->nr_processes) { + profile_accumulate_and_print_job_events(proc); + } + else { + profile_print_proc_stats(proc); + } } profile_dealloc_proc_events(proc); #endif // PROFILE_ENABLE diff --git a/kernel/profile.c b/kernel/profile.c index 7025de6b..7da15ed8 100644 --- a/kernel/profile.c +++ b/kernel/profile.c @@ -44,6 +44,17 @@ extern char *syscall_name[]; #ifdef PROFILE_ENABLE +//#define DEBUG_PRINT_PROFILE + +#ifdef DEBUG_PRINT_PROFILE +#define dkprintf(...) kprintf(__VA_ARGS__) +#define ekprintf(...) kprintf(__VA_ARGS__) +#else +#define dkprintf(...) do { if (0) kprintf(__VA_ARGS__); } while (0) +#define ekprintf(...) kprintf(__VA_ARGS__) +#endif + + char *profile_event_names[] = { "page_fault", @@ -101,7 +112,7 @@ void profile_print_thread_stats(struct thread *thread) !thread->profile_events[i + PROFILE_SYSCALL_MAX].cnt) continue; - __kprintf("TID: %4d (%3d,%20s): %6u %6lukC offl: %6u %6lukC\n", + __kprintf("TID: %4d (%3d,%20s): %6u %6luk offl: %6u %6luk\n", thread->tid, i, syscall_name[i], @@ -123,9 +134,8 @@ void profile_print_thread_stats(struct thread *thread) if (!thread->profile_events[i].cnt) continue; - __kprintf("TID: %4d (%3d,%20s): %6u %6lukC \n", + __kprintf("TID: %4d (%24s): %6u %6luk \n", thread->tid, - i, profile_event_names[i - PROFILE_EVENT_MIN], thread->profile_events[i].cnt, (thread->profile_events[i].tsc / @@ -152,7 +162,7 @@ void profile_print_proc_stats(struct process *proc) !proc->profile_events[i + PROFILE_SYSCALL_MAX].cnt) continue; - __kprintf("PID: %4d (%3d,%20s): %6u %6lukC offl: %6u %6lukC\n", + __kprintf("PID: %4d (%3d,%20s): %6u %6luk offl: %6u %6luk\n", proc->pid, i, syscall_name[i], @@ -174,9 +184,8 @@ void profile_print_proc_stats(struct process *proc) if (!proc->profile_events[i].cnt) continue; - __kprintf("PID: %4d (%3d,%20s): %6u %6lukC \n", + __kprintf("PID: %4d (%24s): %6u %6luk \n", proc->pid, - i, profile_event_names[i - PROFILE_EVENT_MIN], proc->profile_events[i].cnt, (proc->profile_events[i].tsc / @@ -240,7 +249,7 @@ int profile_accumulate_and_print_job_events(struct process *proc) !job_profile_events[i + PROFILE_SYSCALL_MAX].cnt) continue; - __kprintf("JOB: (%2d) (%3d,%20s): %6u %6lukC offl: %6u %6lukC\n", + __kprintf("JOB: (%2d) (%3d,%20s): %6u %6luk offl: %6u %6luk\n", job_nr_processes, i, syscall_name[i], @@ -265,9 +274,8 @@ int profile_accumulate_and_print_job_events(struct process *proc) if (!job_profile_events[i].cnt) continue; - __kprintf("JOB: (%2d) (%3d,%20s): %6u %6lukC \n", + __kprintf("JOB: (%2d) (%24s): %6u %6luk \n", job_nr_processes, - i, profile_event_names[i - PROFILE_EVENT_MIN], job_profile_events[i].cnt, (job_profile_events[i].tsc / @@ -376,6 +384,8 @@ int do_profile(int flag) /* Job level? */ if (flag & PROF_JOB) { + dkprintf("%s: JOB %d, flag: 0x%lx\n", + __FUNCTION__, proc->nr_processes, flag); if (flag & PROF_PRINT) { struct mcs_rwlock_node lock; struct thread *_thread; @@ -397,6 +407,8 @@ int do_profile(int flag) struct mcs_rwlock_node lock; struct thread *_thread; + dkprintf("%s: PID %d, flag: 0x%lx\n", + __FUNCTION__, proc->pid, flag); /* Accumulate events from all threads */ mcs_rwlock_reader_lock_noirq(&proc->threads_lock, &lock); @@ -420,12 +432,22 @@ int do_profile(int flag) mcs_rwlock_reader_unlock_noirq(&proc->threads_lock, &lock); + /* Make sure future threads profile as well */ + if (flag & PROF_ON) { + proc->profile = 1; + } + else if (flag & PROF_OFF) { + proc->profile = 0; + } + if (flag & PROF_PRINT) { profile_print_proc_stats(proc); } } /* Thread level */ else { + dkprintf("%s: TID %d, flag: 0x%lx\n", + __FUNCTION__, thread->tid, flag); if (flag & PROF_PRINT) { profile_print_thread_stats(thread); } diff --git a/kernel/syscall.c b/kernel/syscall.c index 4129a4c6..803cbc0d 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -8510,7 +8510,6 @@ long syscall(int num, ihk_mc_user_context_t *ctx) dkprintf("\n"); #ifdef PROFILE_ENABLE - if (num == __NR_clone) cpu_local_var(current)->profile = 1; t_s = rdtsc(); #endif // PROFILE_ENABLE