diff --git a/executer/include/uprotocol.h b/executer/include/uprotocol.h index dec38125..13ada852 100644 --- a/executer/include/uprotocol.h +++ b/executer/include/uprotocol.h @@ -172,6 +172,7 @@ struct program_load_desc { #ifdef ENABLE_TOFU int enable_tofu; #endif + unsigned long mcexec_flags; int nr_processes; int process_rank; __cpu_set_unit cpu_set[PLD_CPU_SET_SIZE]; diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c index 397e744f..9c78e2a6 100644 --- a/executer/user/mcexec.c +++ b/executer/user/mcexec.c @@ -207,6 +207,7 @@ static int enable_uti = 0; #ifdef ENABLE_TOFU static int enable_tofu = 0; #endif +static unsigned long mcexec_flags = 0; /* Partitioned execution (e.g., for MPI) */ static int nr_processes = 0; @@ -1803,6 +1804,12 @@ static struct option mcexec_options[] = { .flag = &debug, .val = 1, }, + { + .name = "flags", + .has_arg = required_argument, + .flag = NULL, + .val = 'f', + }, /* end */ { NULL, 0, NULL, 0, }, }; @@ -2184,10 +2191,10 @@ int main(int argc, char **argv) /* Parse options ("+" denotes stop at the first non-option) */ #ifdef ADD_ENVS_OPTION - while ((opt = getopt_long(argc, argv, "+c:n:t:M:h:e:s:m:u:S:", + while ((opt = getopt_long(argc, argv, "+c:n:t:M:h:e:s:m:u:S:f:", mcexec_options, NULL)) != -1) { #else /* ADD_ENVS_OPTION */ - while ((opt = getopt_long(argc, argv, "+c:n:t:M:h:s:m:u:S:", + while ((opt = getopt_long(argc, argv, "+c:n:t:M:h:s:m:u:S:f:", mcexec_options, NULL)) != -1) { #endif /* ADD_ENVS_OPTION */ switch (opt) { @@ -2262,6 +2269,10 @@ int main(int argc, char **argv) uti_thread_rank = atoi(optarg); break; + case 'f': + mcexec_flags = strtoul(optarg, NULL, 16); + break; + case 0: /* long opt */ break; @@ -2415,6 +2426,8 @@ int main(int argc, char **argv) return 1; } + desc->mcexec_flags = 0; + #ifdef ADD_ENVS_OPTION /* Collect environment variables */ for (i = 0; environ[i]; i++) { @@ -2827,6 +2840,14 @@ int main(int argc, char **argv) desc->enable_tofu = enable_tofu; #endif + /* + * Override mcexec_flags, if explicitly set. + * This must be right before prepare image. + */ + if (mcexec_flags) { + desc->mcexec_flags = mcexec_flags; + } + /* user_start and user_end are set by this call */ if (ioctl(fd, MCEXEC_UP_PREPARE_IMAGE, (unsigned long)desc) != 0) { perror("prepare"); diff --git a/kernel/host.c b/kernel/host.c index 88f9cd73..7241307e 100644 --- a/kernel/host.c +++ b/kernel/host.c @@ -589,6 +589,10 @@ static int process_msg_prepare_process(unsigned long rphys) } #endif + proc->mcexec_flags = pn->mcexec_flags; + dkprintf("%s: PID: %d, flags: 0x%lx\n", + __func__, proc->pid, proc->mcexec_flags); + #ifdef PROFILE_ENABLE proc->profile = pn->profile; thread->profile = pn->profile; diff --git a/kernel/include/process.h b/kernel/include/process.h index b5547de6..950a13fa 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -577,6 +577,7 @@ struct process { int enable_tofu; #endif size_t straight_map_threshold; + unsigned long mcexec_flags; // perf_event int perf_status; diff --git a/kernel/include/syscall.h b/kernel/include/syscall.h index e54d9306..474aac42 100644 --- a/kernel/include/syscall.h +++ b/kernel/include/syscall.h @@ -243,6 +243,7 @@ struct program_load_desc { #ifdef ENABLE_TOFU int enable_tofu; #endif + unsigned long mcexec_flags; int nr_processes; int process_rank; __cpu_set_unit cpu_set[PLD_CPU_SET_SIZE];