From 2026cf8dad0b948b920352219203efbc71bba886 Mon Sep 17 00:00:00 2001 From: Balazs Gerofi Date: Tue, 21 Apr 2020 11:19:43 +0900 Subject: [PATCH] mcexec: explicit CPU list in partitoned execution (for Fujitsu's FLIB_AFFINITY_ON_PROCESS) Change-Id: I05c11f73553de8ccb5f79083ce2115ac57e62584 --- executer/include/uprotocol.h | 2 + executer/kernel/mcctrl/control.c | 72 ++++++++++++++++++++++++++++++++ executer/user/mcexec.c | 18 ++++++++ 3 files changed, 92 insertions(+) diff --git a/executer/include/uprotocol.h b/executer/include/uprotocol.h index 81e1dce3..a277162e 100644 --- a/executer/include/uprotocol.h +++ b/executer/include/uprotocol.h @@ -91,6 +91,8 @@ struct program_image_section { struct get_cpu_set_arg { int nr_processes; + char *req_cpu_list; // Requested by user-space + int req_cpu_list_len; // Lenght of request string int *process_rank; pid_t ppid; void *cpu_set; diff --git a/executer/kernel/mcctrl/control.c b/executer/kernel/mcctrl/control.c index d027f8dc..dac0d0de 100644 --- a/executer/kernel/mcctrl/control.c +++ b/executer/kernel/mcctrl/control.c @@ -620,6 +620,78 @@ static long mcexec_get_cpuset(ihk_os_t os, unsigned long arg) goto put_out; } + /* User requested CPU mask? */ + if (req.req_cpu_list && req.req_cpu_list_len) { + char *cpu_list = NULL; + + cpu_list = kmalloc(req.req_cpu_list_len, GFP_KERNEL); + if (!cpu_list) { + printk("%s: error: allocating CPU list\n", __FUNCTION__); + ret = -ENOMEM; + goto put_out; + } + + if (copy_from_user(cpu_list, + req.req_cpu_list, req.req_cpu_list_len)) { + printk("%s: error copying CPU list request\n", __FUNCTION__); + kfree(cpu_list); + ret = -EINVAL; + goto put_out; + } + + cpus_used = kmalloc(sizeof(cpumask_t), GFP_KERNEL); + cpus_to_use = kmalloc(sizeof(cpumask_t), GFP_KERNEL); + if (!cpus_to_use || !cpus_used) { + printk("%s: error: allocating CPU mask\n", __FUNCTION__); + ret = -ENOMEM; + kfree(cpu_list); + goto put_out; + } + memset(cpus_used, 0, sizeof(cpumask_t)); + memset(cpus_to_use, 0, sizeof(cpumask_t)); + + /* Parse CPU list */ + if (cpulist_parse(cpu_list, cpus_to_use) < 0) { + printk("%s: invalid CPUs requested: %s\n", + __FUNCTION__, cpu_list); + ret = -EINVAL; + kfree(cpu_list); + goto put_out; + } + + memcpy(cpus_used, cpus_to_use, sizeof(cpumask_t)); + + /* Copy mask to user-space */ + if (copy_to_user(req.cpu_set, cpus_used, + (req.cpu_set_size < sizeof(cpumask_t) ? + req.cpu_set_size : sizeof(cpumask_t)))) { + printk("%s: error copying mask to user\n", __FUNCTION__); + ret = -EINVAL; + kfree(cpu_list); + goto put_out; + } + + /* Copy IKC target core */ + cpu = cpumask_next(-1, cpus_used); + if (copy_to_user(req.target_core, &cpu, sizeof(cpu))) { + printk("%s: error copying target core to user\n", + __FUNCTION__); + ret = -EINVAL; + kfree(cpu_list); + goto put_out; + } + + /* Save in per-process structure */ + memcpy(&ppd->cpu_set, cpus_used, sizeof(cpumask_t)); + ppd->ikc_target_cpu = cpu; + printk("%s: %s -> target McKernel CPU: %d\n", + __func__, cpu_list, cpu); + + ret = 0; + kfree(cpu_list); + goto put_out; + } + mutex_lock(&udp->part_exec_lock); /* Find part_exec having same node_proxy */ list_for_each_entry_reverse(pe_itr, &udp->part_exec_list, chain) { diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c index 834b2304..4ce21fe7 100644 --- a/executer/user/mcexec.c +++ b/executer/user/mcexec.c @@ -2483,6 +2483,8 @@ int main(int argc, char **argv) CPU_ZERO(&mcexec_cpu_set); + cpu_set_arg.req_cpu_list = NULL; + cpu_set_arg.req_cpu_list_len = 0; cpu_set_arg.cpu_set = (void *)&desc->cpu_set; cpu_set_arg.cpu_set_size = sizeof(desc->cpu_set); cpu_set_arg.nr_processes = nr_processes; @@ -2494,6 +2496,16 @@ int main(int argc, char **argv) cpu_set_arg.mcexec_cpu_set_size = sizeof(mcexec_cpu_set); cpu_set_arg.ikc_mapped = &ikc_mapped; + /* Fugaku specific: Fujitsu CPU binding */ + if (getenv("FLIB_AFFINITY_ON_PROCESS")) { + cpu_set_arg.req_cpu_list = + getenv("FLIB_AFFINITY_ON_PROCESS"); + cpu_set_arg.req_cpu_list_len = + strlen(cpu_set_arg.req_cpu_list) + 1; + __dprintf("%s: requesting CPUs: %s\n", + __func__, cpu_set_arg.req_cpu_list); + } + if (ioctl(fd, MCEXEC_UP_GET_CPUSET, (void *)&cpu_set_arg) != 0) { perror("getting CPU set for partitioned execution"); close(fd); @@ -2502,6 +2514,12 @@ int main(int argc, char **argv) desc->cpu = target_core; desc->process_rank = process_rank; + /* Fugaku specific: Fujitsu node-local rank */ + if (getenv("PLE_RANK_ON_NODE")) { + desc->process_rank = atoi(getenv("PLE_RANK_ON_NODE")); + __dprintf("%s: rank: %d, target CPU: %d\n", + __func__, desc->process_rank, desc->cpu); + } /* Bind to CPU cores where the LWK process' IKC target maps to */ if (ikc_mapped && !no_bind_ikc_map) {