From 6dd5407b5f5c8ff3539172198e53fabc0e6ce6bc Mon Sep 17 00:00:00 2001 From: Masamichi Takagi Date: Thu, 31 Jul 2014 19:45:11 +0900 Subject: [PATCH] Return error when no core is available clone returns -EAGAIN when there is no vacant core. In addition, clone tries to use the next vacant hyper-threading core instead of trying to use next vacant hyper-threading core of the next vacant physical core. --- arch/x86/kernel/syscall.c | 24 +++++++++++++++++------- kernel/syscall.c | 3 +++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/arch/x86/kernel/syscall.c b/arch/x86/kernel/syscall.c index 2a1ba8cc..705f5f2f 100644 --- a/arch/x86/kernel/syscall.c +++ b/arch/x86/kernel/syscall.c @@ -72,21 +72,31 @@ int obtain_clone_cpuid() { retry: /* Try to obtain next physical core */ cpuid = cpuid_head; - cpuid_head += 4; + + /* A hyper-threading core on the same physical core as + the parent process might be chosen. Use sched_setaffinity + if you want to skip that kind of busy physical core for + performance reason. */ + cpuid_head += 1; if(cpuid_head >= cpu_info->ncpus) { - cpuid_head = ((cpuid_head % 4) + 1) % 4; + cpuid_head = 0; } - /* Don't use a physical core with a system process (e.g. MPI) - because using it degrades performance */ - if((cpu_info->ncpus - 3 <= cpuid && cpuid <= cpu_info->ncpus - 1) || - get_cpu_local_var(cpuid)->status != CPU_STATUS_IDLE) { + + /* A hyper-threading core whose parent physical core has a + process on one of its hyper-threading core might + be chosen. Use sched_setaffinity if you want to skip that + kind of busy physical core for performance reason. */ + if(get_cpu_local_var(cpuid)->status != CPU_STATUS_IDLE) { nretry++; if(nretry >= cpu_info->ncpus) { - panic("there is no cpu with empty runq\n"); + cpuid = -1; + ihk_mc_spinlock_unlock_noirq(&cpuid_head_lock); + goto out; } goto retry; } ihk_mc_spinlock_unlock_noirq(&cpuid_head_lock); + out: return cpuid; } diff --git a/kernel/syscall.c b/kernel/syscall.c index aa453800..f1678fbb 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -1290,6 +1290,9 @@ SYSCALL_DECLARE(clone) (unsigned long)ihk_mc_syscall_sp(ctx)); cpuid = obtain_clone_cpuid(); + if (cpuid == -1) { + return -EAGAIN; + } new = clone_process(cpu_local_var(current), ihk_mc_syscall_pc(ctx), ihk_mc_syscall_arg1(ctx) ? ihk_mc_syscall_arg1(ctx) :