diff --git a/arch/x86_64/tools/mcreboot-smp-x86.sh.in b/arch/x86_64/tools/mcreboot-smp-x86.sh.in index 0e87e049..dd8eeafe 100644 --- a/arch/x86_64/tools/mcreboot-smp-x86.sh.in +++ b/arch/x86_64/tools/mcreboot-smp-x86.sh.in @@ -46,8 +46,9 @@ turbo="" ihk_irq="" umask_old=`umask` idle_halt="" +allow_oversubscribe="" -while getopts :tk:c:m:o:f:r:q:i:d:e:h OPT +while getopts :tk:c:m:o:f:r:q:i:d:e:hO OPT do case ${OPT} in f) facility=${OPTARG} @@ -74,6 +75,8 @@ do ;; h) idle_halt="idle_halt" ;; + O) allow_oversubscribe="allow_oversubscribe" + ;; *) echo "invalid option -${OPT}" >&2 exit 1 esac @@ -419,7 +422,7 @@ if ! ${SBINDIR}/ihkosctl 0 load ${KERNDIR}/mckernel.img; then fi # Set kernel arguments -if ! ${SBINDIR}/ihkosctl 0 kargs "hidos $turbo $idle_halt dump_level=${DUMP_LEVEL} $extra_kopts"; then +if ! ${SBINDIR}/ihkosctl 0 kargs "hidos $turbo $idle_halt dump_level=${DUMP_LEVEL} $extra_kopts $allow_oversubscribe"; then echo "error: setting kernel arguments" >&2 error_exit "os_created" fi diff --git a/kernel/include/process.h b/kernel/include/process.h index 8eb8142c..1bf8f275 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -278,6 +278,7 @@ struct resource_set { extern struct list_head resource_set_list; extern mcs_rwlock_lock_t resource_set_lock; extern int idle_halt; +extern int allow_oversubscribe; struct process_hash { struct list_head list[HASH_SIZE]; diff --git a/kernel/init.c b/kernel/init.c index 01c581e9..88d11682 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -150,6 +150,12 @@ static void parse_kargs(void) if (ptr) { idle_halt = 1; } + + /* allow_oversubscribe option */ + ptr = find_command_line("allow_oversubscribe"); + if (ptr) { + allow_oversubscribe = 1; + } } extern void ihk_mc_get_boot_time(unsigned long *tv_sec, unsigned long *tv_nsec); diff --git a/kernel/process.c b/kernel/process.c index 3a5da9f3..8d03bb2c 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -101,6 +101,7 @@ struct list_head resource_set_list; mcs_rwlock_lock_t resource_set_lock; int idle_halt = 0; +int allow_oversubscribe = 0; void init_process(struct process *proc, struct process *parent) diff --git a/kernel/syscall.c b/kernel/syscall.c index b8ea8142..d79d84e8 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -2343,6 +2343,7 @@ unsigned long do_fork(int clone_flags, unsigned long newsp, struct syscall_request request1 IHK_DMA_ALIGN; int ptrace_event = 0; int termsig = clone_flags & 0x000000ff; + const struct ihk_mc_cpu_info *cpu_info = ihk_mc_get_cpu_info(); dkprintf("do_fork,flags=%08x,newsp=%lx,ptidptr=%lx,ctidptr=%lx,tls=%lx,curpc=%lx,cursp=%lx", clone_flags, newsp, parent_tidptr, child_tidptr, tlsblock_base, curpc, cursp); @@ -2382,6 +2383,11 @@ unsigned long do_fork(int clone_flags, unsigned long newsp, return -EINVAL; } + if (!allow_oversubscribe && rusage->num_threads >= cpu_info->ncpus) { + kprintf("%s: ERROR: CPU oversubscription is not allowed. Specify -O option in mcreboot.sh to allow it.\n", __FUNCTION__); + return -EINVAL; + } + cpuid = obtain_clone_cpuid(&old->cpu_set); if (cpuid == -1) { kprintf("do_fork,core not available\n");