]> 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 bb9b2e247d1a512c529460682815a3d0ae6f9283..8afd25b5a61f4fc133af1ff064f15b296ac06f82 100644 (file)
@@ -579,7 +579,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);
@@ -612,9 +613,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;
 }
 
@@ -750,7 +753,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;
@@ -759,9 +763,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;
 }
 
@@ -980,7 +986,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;
 }