diff --git a/executer/include/uprotocol.h b/executer/include/uprotocol.h index b7e3020e..1e555733 100644 --- a/executer/include/uprotocol.h +++ b/executer/include/uprotocol.h @@ -79,6 +79,10 @@ struct program_image_section { #define SHELL_PATH_MAX_LEN 1024 #define MCK_RLIM_MAX 20 +#define PLD_CPU_SET_MAX_CPUS 1024 +typedef unsigned long __cpu_set_unit; +#define PLD_CPU_SET_SIZE (PLD_CPU_SET_MAX_CPUS / (8 * sizeof(__cpu_set_unit))) + struct program_load_desc { int num_sections; int status; @@ -108,6 +112,7 @@ struct program_load_desc { struct rlimit rlimit[MCK_RLIM_MAX]; unsigned long interp_align; char shell_path[SHELL_PATH_MAX_LEN]; + __cpu_set_unit cpu_set[PLD_CPU_SET_SIZE]; struct program_image_section sections[0]; }; diff --git a/kernel/host.c b/kernel/host.c index 25969544..b2ac26ab 100644 --- a/kernel/host.c +++ b/kernel/host.c @@ -393,7 +393,9 @@ static int process_msg_prepare_process(unsigned long rphys) memcpy_long(pn, p, sizeof(struct program_load_desc) + sizeof(struct program_image_section) * n); - if((thread = create_thread(p->entry)) == NULL){ + if ((thread = create_thread(p->entry, + (unsigned long *)&p->cpu_set, + sizeof(p->cpu_set))) == NULL) { kfree(pn); ihk_mc_unmap_virtual(p, npages, 1); ihk_mc_unmap_memory(NULL, phys, sz); diff --git a/kernel/include/process.h b/kernel/include/process.h index 7f0bc656..57acdb27 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -700,7 +700,8 @@ static inline int has_cap_sys_admin(struct thread *th) void hold_address_space(struct address_space *); void release_address_space(struct address_space *); -struct thread *create_thread(unsigned long user_pc); +struct thread *create_thread(unsigned long user_pc, + unsigned long *__cpu_set, size_t cpu_set_size); struct thread *clone_thread(struct thread *org, unsigned long pc, unsigned long sp, int clone_flags); void destroy_thread(struct thread *thread); diff --git a/kernel/include/syscall.h b/kernel/include/syscall.h index d60cac26..12fa8382 100644 --- a/kernel/include/syscall.h +++ b/kernel/include/syscall.h @@ -149,6 +149,10 @@ struct program_image_section { #define MCK_RLIMIT_SIGPENDING 14 #define MCK_RLIMIT_STACK 15 +#define PLD_CPU_SET_MAX_CPUS 1024 +typedef unsigned long __cpu_set_unit; +#define PLD_CPU_SET_SIZE (PLD_CPU_SET_MAX_CPUS / (8 * sizeof(__cpu_set_unit))) + struct program_load_desc { int num_sections; int status; @@ -178,6 +182,7 @@ struct program_load_desc { struct rlimit rlimit[MCK_RLIM_MAX]; unsigned long interp_align; char shell_path[SHELL_PATH_MAX_LEN]; + __cpu_set_unit cpu_set[PLD_CPU_SET_SIZE]; struct program_image_section sections[0]; }; diff --git a/kernel/process.c b/kernel/process.c index 6604ad1a..fcf7a0fd 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -233,13 +233,15 @@ init_process_vm(struct process *owner, struct address_space *asp, struct process return 0; } -struct thread * -create_thread(unsigned long user_pc) +struct thread *create_thread(unsigned long user_pc, + unsigned long *__cpu_set, size_t cpu_set_size) { struct thread *thread; struct process *proc; struct process_vm *vm = NULL; struct address_space *asp = NULL; + int cpu; + int cpu_set_empty = 1; thread = ihk_mc_alloc_pages(KERNEL_STACK_NR_PAGES, IHK_MC_AP_NOWAIT); if (!thread) @@ -255,7 +257,20 @@ create_thread(unsigned long user_pc) memset(vm, 0, sizeof(struct process_vm)); init_process(proc, cpu_local_var(resource_set)->pid1); - if (1) { + /* Use requested CPU cores */ + for_each_set_bit(cpu, __cpu_set, cpu_set_size * BITS_PER_BYTE) { + if (cpu >= num_processors) { + kprintf("%s: invalid CPU requested in initial cpu_set\n", + __FUNCTION__); + goto err; + } + + CPU_SET(cpu, &thread->cpu_set); + cpu_set_empty = 0; + } + + /* Default allows all cores */ + if (cpu_set_empty) { struct ihk_mc_cpu_info *infop; int i;