]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
feat: SMP load balancing for fork/clone + IPI resched
authorTulio A M Mendes <[email protected]>
Mon, 16 Feb 2026 21:08:55 +0000 (18:08 -0300)
committerTulio A M Mendes <[email protected]>
Mon, 16 Feb 2026 21:08:55 +0000 (18:08 -0300)
Enable load balancing in process_fork_create and process_clone_create:
both now dispatch to the least-loaded CPU via sched_pcpu_least_loaded().

All three process creation functions (create_kernel, fork, clone) now
send IPI_RESCHED to the target CPU after releasing sched_lock, waking
idle APs immediately when work is enqueued to their runqueue.

83/83 smoke tests pass in 9s, cppcheck clean.

src/kernel/scheduler.c

index b5197f9aaa70d393ba9693073ff0e08bc0434dde..1ba3d79a4e9d99563479dc44f0b20b8325c07364 100644 (file)
@@ -570,7 +570,8 @@ struct process* process_fork_create(uintptr_t child_as, const void* child_regs)
     proc->flags = 0;
     proc->tls_base = 0;
     proc->clear_child_tid = NULL;
-    proc->cpu_id = 0;
+    uint32_t fork_target = sched_pcpu_least_loaded();
+    proc->cpu_id = fork_target;
 
     if (current_process) {
         memcpy(proc->fpu_state, current_process->fpu_state, FPU_STATE_SIZE);
@@ -603,9 +604,11 @@ struct process* process_fork_create(uintptr_t child_as, const void* child_regs)
     ready_queue_head->prev = proc;
     ready_queue_tail = proc;
 
-    rq_enqueue(pcpu_rq[proc->cpu_id].active, proc);
+    rq_enqueue(pcpu_rq[fork_target].active, proc);
+    sched_pcpu_inc_load(fork_target);
 
     spin_unlock_irqrestore(&sched_lock, flags);
+    sched_ipi_resched(fork_target);
     return proc;
 }
 
@@ -741,7 +744,8 @@ struct process* process_clone_create(uint32_t clone_flags,
     proc->sp = arch_kstack_init((uint8_t*)kstack + KSTACK_SIZE,
                                   thread_wrapper, clone_child_trampoline);
 
-    proc->cpu_id = 0;
+    uint32_t clone_target = sched_pcpu_least_loaded();
+    proc->cpu_id = clone_target;
 
     /* Insert into process list */
     proc->next = ready_queue_head;
@@ -750,9 +754,11 @@ struct process* process_clone_create(uint32_t clone_flags,
     ready_queue_head->prev = proc;
     ready_queue_tail = proc;
 
-    rq_enqueue(pcpu_rq[proc->cpu_id].active, proc);
+    rq_enqueue(pcpu_rq[clone_target].active, proc);
+    sched_pcpu_inc_load(clone_target);
 
     spin_unlock_irqrestore(&sched_lock, flags);
+    sched_ipi_resched(clone_target);
     return proc;
 }
 
@@ -971,7 +977,7 @@ struct process* process_create_kernel(void (*entry_point)(void)) {
     sched_pcpu_inc_load(target);
 
     spin_unlock_irqrestore(&sched_lock, flags);
-    /* IPI disabled for testing */
+    sched_ipi_resched(target);
     return proc;
 }