From c0edb6fe6f47cbed7fa4ea19def16ac8adb22601 Mon Sep 17 00:00:00 2001 From: Tomoki Shirasawa Date: Wed, 18 Feb 2015 13:46:08 +0900 Subject: [PATCH] add new cpu state CPU_STATUS_RESERVED --- arch/x86/kernel/syscall.c | 1 + kernel/include/cls.h | 1 + kernel/include/process.h | 1 + kernel/process.c | 31 +++++++++++++++---------------- kernel/syscall.c | 3 +++ 5 files changed, 21 insertions(+), 16 deletions(-) diff --git a/arch/x86/kernel/syscall.c b/arch/x86/kernel/syscall.c index aa1e7e6d..8ec53337 100644 --- a/arch/x86/kernel/syscall.c +++ b/arch/x86/kernel/syscall.c @@ -95,6 +95,7 @@ int obtain_clone_cpuid() { } goto retry; } + get_cpu_local_var(cpuid)->status = CPU_STATUS_RESERVED; ihk_mc_spinlock_unlock_noirq(&cpuid_head_lock); out: return cpuid; diff --git a/kernel/include/cls.h b/kernel/include/cls.h index 198c59a1..3a7784cf 100644 --- a/kernel/include/cls.h +++ b/kernel/include/cls.h @@ -30,6 +30,7 @@ struct malloc_header { #define CPU_STATUS_DISABLE (0) #define CPU_STATUS_IDLE (1) #define CPU_STATUS_RUNNING (2) +#define CPU_STATUS_RESERVED (3) extern ihk_spinlock_t cpu_status_lock; #define CPU_FLAG_NEED_RESCHED 0x1U diff --git a/kernel/include/process.h b/kernel/include/process.h index 718c21ca..a8dc0219 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -444,5 +444,6 @@ void cpu_clear(int cpu, cpu_set_t *cpu_set, ihk_spinlock_t *lock); struct process *findthread_and_lock(int pid, int tid, ihk_spinlock_t **savelock, unsigned long *irqstate); void process_unlock(void *savelock, unsigned long irqstate); +void release_cpuid(int cpuid); #endif diff --git a/kernel/process.c b/kernel/process.c index 8355ad1d..ad2aad8f 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -1996,7 +1996,8 @@ static void idle(void) { struct cpu_local_var *v = get_this_cpu_local_var(); - v->status = CPU_STATUS_IDLE; + if(v->status == CPU_STATUS_RUNNING) + v->status = CPU_STATUS_IDLE; cpu_enable_interrupt(); while (1) { @@ -2021,7 +2022,8 @@ static void idle(void) * 4) The idle process was resumed, and halted for waiting for * the interrupt that had already been handled. */ - if (v->status == CPU_STATUS_IDLE) { + if (v->status == CPU_STATUS_IDLE || + v->status == CPU_STATUS_RESERVED) { long s; struct process *p; @@ -2034,7 +2036,8 @@ static void idle(void) } ihk_mc_spinlock_unlock(&v->runq_lock, s); } - if (v->status == CPU_STATUS_IDLE) { + if (v->status == CPU_STATUS_IDLE || + v->status == CPU_STATUS_RESERVED) { cpu_safe_halt(); } else { @@ -2189,19 +2192,8 @@ redo: /* No process? Run idle.. */ if (!next) { - list_for_each_entry_safe(proc, tmp, &(v->runq), sched_list) { - if (proc->ftn->status & (PS_INTERRUPTIBLE | - PS_UNINTERRUPTIBLE | - PS_STOPPED | - PS_TRACED)) { - next = proc; - break; - } - } - if (!next) { - next = &cpu_local_var(idle); - v->status = CPU_STATUS_IDLE; - } + next = &cpu_local_var(idle); + v->status = v->runq_len? CPU_STATUS_RESERVED: CPU_STATUS_IDLE; } } @@ -2258,6 +2250,13 @@ redo: } } +void +release_cpuid(int cpuid) +{ + if (!get_cpu_local_var(cpuid)->runq_len) + get_cpu_local_var(cpuid)->status = CPU_STATUS_IDLE; +} + void check_need_resched(void) { struct cpu_local_var *v = get_this_cpu_local_var(); diff --git a/kernel/syscall.c b/kernel/syscall.c index 722a38f2..81470873 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -1745,6 +1745,7 @@ unsigned long do_fork(int clone_flags, unsigned long newsp, clone_flags); if (!new) { + release_cpuid(cpuid); return -ENOMEM; } @@ -1764,6 +1765,7 @@ unsigned long do_fork(int clone_flags, unsigned long newsp, kprintf("ERROR: forking host process\n"); /* TODO: clean-up new */ + release_cpuid(cpuid); return -EFAULT; } @@ -1811,6 +1813,7 @@ unsigned long do_fork(int clone_flags, unsigned long newsp, if (ihk_mc_pt_virt_to_phys(new->vm->page_table, (void *)child_tidptr, &phys)) { kprintf("ERROR: looking up physical addr for child process\n"); + release_cpuid(cpuid); return -EFAULT; }