diff --git a/kernel/host.c b/kernel/host.c index 5c7864f7..da75d26c 100644 --- a/kernel/host.c +++ b/kernel/host.c @@ -10,6 +10,14 @@ #include #include +#define DEBUG_PRINT_HOST + +#ifdef DEBUG_PRINT_HOST +#define dkprintf kprintf +#else +#define dkprintf(...) +#endif + /* * Communication with host */ @@ -29,7 +37,7 @@ static void process_msg_prepare_process(unsigned long rphys) p = aal_mc_map_virtual(phys, npages, PTATTR_WRITABLE); n = p->num_sections; - kprintf("# of sections: %d\n", n); + dkprintf("# of sections: %d\n", n); pn = aal_mc_allocate(sizeof(struct program_load_desc) + sizeof(struct program_image_section) * n, 0); @@ -92,7 +100,7 @@ static void process_msg_prepare_process(unsigned long rphys) p->rprocess = (unsigned long)proc; init_process_stack(proc); - kprintf("new process : %p [%d] / table : %p\n", proc, proc->pid, + dkprintf("new process : %p [%d] / table : %p\n", proc, proc->pid, proc->vm->page_table); aal_mc_free(pn); @@ -143,14 +151,14 @@ static void process_msg_init_acked(unsigned long pphys) lparam->post_fin = 1; - kprintf("Syscall parameters: (%d)\n", aal_mc_get_processor_id()); - kprintf(" Response: %lx, %p\n", + dkprintf("Syscall parameters: (%d)\n", aal_mc_get_processor_id()); + dkprintf(" Response: %lx, %p\n", lparam->response_pa, lparam->response_va); - kprintf(" Request : %lx, %lx, %p\n", + dkprintf(" Request : %lx, %lx, %p\n", lparam->request_pa, lparam->request_rpa, lparam->request_va); - kprintf(" Doorbell: %lx, %lx, %p\n", + dkprintf(" Doorbell: %lx, %lx, %p\n", lparam->doorbell_pa, lparam->doorbell_rpa, lparam->doorbell_va); - kprintf(" Post: %lx, %lx, %p\n", + dkprintf(" Post: %lx, %lx, %p\n", lparam->post_pa, lparam->post_rpa, lparam->post_va); } @@ -168,7 +176,7 @@ static int syscall_packet_handler(struct aal_ikc_channel_desc *c, switch (packet->msg) { case SCD_MSG_INIT_CHANNEL_ACKED: - kprintf("init channel acked!\n"); + dkprintf("SCD_MSG_INIT_CHANNEL_ACKED\n"); process_msg_init_acked(packet->arg); return 0; @@ -183,9 +191,12 @@ static int syscall_packet_handler(struct aal_ikc_channel_desc *c, return 0; case SCD_MSG_SCHEDULE_PROCESS: - kprintf("next one : %lx\n", packet->arg); + dkprintf("SCD_MSG_SCHEDULE_PROCESS: %lx\n", packet->arg); - cpu_local_var(next) = (struct process *)packet->arg; + runq_add_proc((struct process *)packet->arg, + aal_mc_get_processor_id()); + + //cpu_local_var(next) = (struct process *)packet->arg; return 0; } return 0; @@ -202,12 +213,12 @@ void init_host_syscall_channel(void) param.magic = 0x1129; param.handler = syscall_packet_handler; - kprintf("(syscall) Trying to connect host ..."); + dkprintf("(syscall) Trying to connect host ..."); while (aal_ikc_connect(NULL, ¶m) != 0) { - kprintf("."); + dkprintf("."); aal_mc_delay_us(1000 * 1000); } - kprintf("connected.\n"); + dkprintf("connected.\n"); get_this_cpu_local_var()->syscall_channel = param.channel; diff --git a/kernel/include/cls.h b/kernel/include/cls.h index 6ad87cd8..17c7f86b 100644 --- a/kernel/include/cls.h +++ b/kernel/include/cls.h @@ -25,8 +25,10 @@ struct cpu_local_var { struct process idle; struct process_vm idle_vm; + aal_spinlock_t runq_lock; struct process *current; - struct process *next; + struct list_head runq; + size_t runq_len; struct aal_ikc_channel_desc *syscall_channel; diff --git a/kernel/include/process.h b/kernel/include/process.h index e18296cc..cd8d854d 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -12,7 +12,11 @@ #define VR_IO_NOCACHE 0x100 #define VR_REMOTE 0x200 -#define PS_ZOMBIE 0x1 +#define PS_RUNNING 0x1 +#define PS_INTERRUPTIBLE 0x2 +#define PS_UNINTERRUPTIBLE 0x3 +#define PS_ZOMBIE 0x4 +#define PS_EXITED 0x5 struct vm_range { struct list_head list; @@ -41,12 +45,15 @@ struct process_vm { struct process { int pid; int status; + int cpu_id; struct process_vm *vm; aal_mc_kernel_context_t ctx; aal_mc_user_context_t *uctx; + struct list_head sched_list; // Runqueue + struct thread { int *clear_child_tid; } thread; @@ -69,5 +76,7 @@ unsigned long extend_process_region(struct process *proc, unsigned long address); void schedule(void); +void runq_add_proc(struct process *proc, int cpu_id); +void runq_del_proc(struct process *proc, int cpu_id); #endif diff --git a/kernel/process.c b/kernel/process.c index 6cba7f0e..add93639 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -21,6 +21,7 @@ void init_process_vm(struct process_vm *vm) aal_atomic_set(&vm->refcount, 1); INIT_LIST_HEAD(&vm->vm_range_list); vm->page_table = aal_mc_pt_create(); + vm->region.tlsblock_base = 0; } struct process *create_process(unsigned long user_pc) @@ -248,28 +249,56 @@ void sched_init(void) idle_process->vm = &cpu_local_var(idle_vm); aal_mc_init_context(&idle_process->ctx, NULL, idle); + idle_process->pid = aal_mc_get_processor_id(); - cpu_local_var(next) = idle_process; - cpu_local_var(status) = CPU_STATUS_RUNNING; + INIT_LIST_HEAD(&cpu_local_var(runq)); + cpu_local_var(runq_len) = 0; + aal_mc_spinlock_init(&cpu_local_var(runq_lock)); } void schedule(void) { struct cpu_local_var *v = get_this_cpu_local_var(); - struct process *next, *prev; + struct process *next, *prev, *proc, *tmp = NULL; int switch_ctx = 0; + unsigned long irqstate; - cpu_disable_interrupt(); - if (v->next && v->next != v->current) { - prev = v->current; - next = v->next; + irqstate = aal_mc_spinlock_lock(&(v->runq_lock)); - switch_ctx = 1; + next = NULL; + prev = v->current; - v->current = next; - v->next = NULL; + /* All runnable processes are on the runqueue */ + if (prev && prev != &cpu_local_var(idle)) { + list_del(&prev->sched_list); + --v->runq_len; + + /* Round-robin if not exited yet */ + if (prev->status != PS_EXITED) { + list_add_tail(&prev->sched_list, &(v->runq)); + ++v->runq_len; + } } - cpu_enable_interrupt(); + + /* Pick a new running process */ + list_for_each_entry_safe(proc, tmp, &(v->runq), sched_list) { + if (proc->status == PS_RUNNING) { + next = proc; + break; + } + } + + /* No process? Run idle.. */ + if (!next) { + next = &cpu_local_var(idle); + } + + if (prev != next) { + switch_ctx = 1; + v->current = next; + } + + aal_mc_spinlock_unlock(&(v->runq_lock), irqstate); if (switch_ctx) { dkprintf("[%d] schedule: %d => %d \n", @@ -277,7 +306,6 @@ void schedule(void) prev ? prev->pid : 0, next ? next->pid : 0); aal_mc_load_page_table(next->vm->page_table); - do_arch_prctl(ARCH_SET_FS, next->vm->region.tlsblock_base); if (prev) { @@ -288,4 +316,42 @@ void schedule(void) } } +/* Runq lock must be held here */ +void __runq_add_proc(struct process *proc, int cpu_id) +{ + struct cpu_local_var *v = get_cpu_local_var(cpu_id); + list_add_tail(&proc->sched_list, &v->runq); + ++v->runq_len; + proc->cpu_id = cpu_id; + proc->status = PS_RUNNING; + + dkprintf("runq_add_proc(): pid %d added to CPU[%d]'s runq\n", + proc->pid, cpu_id); +} + +void runq_add_proc(struct process *proc, int cpu_id) +{ + struct cpu_local_var *v = get_cpu_local_var(cpu_id); + unsigned long irqstate; + + irqstate = aal_mc_spinlock_lock(&(v->runq_lock)); + __runq_add_proc(proc, cpu_id); + aal_mc_spinlock_unlock(&(v->runq_lock), irqstate); + + /* + if (cpu != this_cpu) + xcall_reschedule(cpu); + */ +} + +void runq_del_proc(struct process *proc, int cpu_id) +{ + struct cpu_local_var *v = get_cpu_local_var(cpu_id); + unsigned long irqstate; + + irqstate = aal_mc_spinlock_lock(&(v->runq_lock)); + list_del(&proc->sched_list); + ++v->runq_len; + aal_mc_spinlock_unlock(&(v->runq_lock), irqstate); +} diff --git a/kernel/syscall.c b/kernel/syscall.c index aa71f599..a8e6936b 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -213,9 +213,12 @@ SYSCALL_DECLARE(exit_group) SYSCALL_HEADER; do_syscall(&request, ctx); + runq_del_proc(cpu_local_var(current), aal_mc_get_processor_id()); free_process_memory(cpu_local_var(current)); - cpu_local_var(next) = &cpu_local_var(idle); + + //cpu_local_var(next) = &cpu_local_var(idle); + cpu_local_var(current) = NULL; schedule(); return 0; @@ -422,7 +425,7 @@ SYSCALL_DECLARE(clone) unsigned long pptid; int *vptid; if (aal_mc_pt_virt_to_phys(cpu_local_var(current)->vm->page_table, - aal_mc_syscall_arg2(ctx), &pptid)) + (int*)aal_mc_syscall_arg2(ctx), &pptid)) return -EFAULT; vptid = (int *)phys_to_virt(pptid); @@ -430,13 +433,15 @@ SYSCALL_DECLARE(clone) } new->thread.clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) - ? aal_mc_syscall_arg3(ctx) + ? (int*)aal_mc_syscall_arg3(ctx) : NULL; aal_mc_syscall_ret(new->uctx) = 0; - get_cpu_local_var(cpuid)->next = new; - get_cpu_local_var(cpuid)->status = CPU_STATUS_RUNNING; + + runq_add_proc(new, cpuid); + //get_cpu_local_var(cpuid)->next = new; + //get_cpu_local_var(cpuid)->status = CPU_STATUS_RUNNING; //aal_mc_spinlock_unlock(&cpu_status_lock, flags); aal_mc_interrupt_cpu(aal_mc_get_cpu_info()->hw_ids[cpuid], 0xd1); @@ -446,6 +451,18 @@ SYSCALL_DECLARE(clone) return new->pid; } +SYSCALL_DECLARE(set_tid_address) +{ + cpu_local_var(current)->thread.clear_child_tid = + (int*)aal_mc_syscall_arg2(ctx); + + return cpu_local_var(current)->pid; +} + +SYSCALL_DECLARE(set_robust_list) +{ + return -ENOSYS; +} SYSCALL_DECLARE(writev) { @@ -510,7 +527,10 @@ static long (*syscall_table[])(int, aal_mc_user_context_t *) = { [110] = sys_getxid, [111] = sys_getxid, [158] = sys_arch_prctl, + [218] = sys_set_tid_address, [231] = sys_exit_group, + [273] = sys_set_robust_list, + [288] = NULL, }; #if 0