Per-cpu data init
authorBarret Rhoden <brho@cs.berkeley.edu>
Sun, 25 Oct 2009 06:51:50 +0000 (23:51 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Sun, 25 Oct 2009 06:51:50 +0000 (23:51 -0700)
Adds a function to properly initialize the percpu data for every core.
(Core 0 was neglected).  This needs to be called by each core at the end
of smp_boot.  Lets keep the arches separate at this point, in case we
have some arch specific percpu info.

Also does a little test where spawn creates a couple processes, one of
which goes all multi and stuff, and moves to other cores.

kern/arch/i386/init.c
kern/arch/i386/smp_boot.c
kern/arch/sparc/smp.c
kern/include/smp.h
kern/src/manager.c
kern/src/process.c
user/apps/roslib/spawn.c

index 2ac2a2a..c1cbf86 100644 (file)
@@ -18,6 +18,8 @@ void arch_init()
        pci_init();
        ioapic_init(); // MUST BE AFTER PCI/ISA INIT!
                
+       // TODO: move these back to regular init.  requires fixing the __NETWORK__
+       // inits to not need multiple cores running.
        // this returns when all other cores are done and ready to receive IPIs
        smp_boot();
        env_init();
index f07f279..c6e7ddb 100644 (file)
@@ -156,6 +156,9 @@ void smp_boot(void)
        init_barrier(&generic_barrier, num_cpus); // barrier used by smp_mtrr_handler
        smp_call_function_all(smp_mtrr_handler, &generic_barrier, 0);
 
+       // initialize my per-cpu info
+       smp_percpu_init();
+
        // Should probably flush everyone's TLB at this point, to get rid of
        // temp mappings that were removed.  TODO
 }
@@ -257,10 +260,17 @@ uint32_t smp_main(void)
        // set a default logical id for now
        lapic_set_logid(lapic_get_id());
 
-       // TODO: do this somewhere else.  in general, we need to do some per_cpu
-       // info init.  or a per_cpu active_msg init
-       STAILQ_INIT(&per_cpu_info[core_id()].active_msgs);
+       // initialize my per-cpu info
+       smp_percpu_init();
 
        return my_stack_top; // will be loaded in smp_entry.S
 }
 
+/* Perform any initialization needed by per_cpu_info.  Right now, this just
+ * inits the amsg list (which sparc will probably also want).  Make sure every
+ * core calls this at some point in the smp_boot process. */
+void smp_percpu_init(void)
+{
+       uint32_t coreid = core_id();
+       STAILQ_INIT(&per_cpu_info[coreid].active_msgs);
+}
index 95c6183..bd13f22 100644 (file)
@@ -143,3 +143,13 @@ int smp_call_wait(handler_wrapper_t* wrapper)
        spin_unlock(&wrapper->lock);
        return 0;
 }
+
+/* Perform any initialization needed by per_cpu_info.  Right now, this just
+ * inits the amsg list (which sparc will probably also want).  Make sure every
+ * core calls this at some point in the smp_boot process. */
+void smp_percpu_init(void)
+{
+       static_assert(0);
+       uint32_t coreid = core_id();
+       STAILQ_INIT(&per_cpu_info[coreid].active_msgs);
+}
index 6e6fe71..2df1054 100644 (file)
@@ -21,7 +21,7 @@
 #ifdef __SHARC__
 typedef sharC_env_t;
 #endif
-// will want this padded out to cacheline alignment
+
 struct per_cpu_info {
        spinlock_t lock;
        bool preempt_pending;
@@ -36,7 +36,7 @@ struct per_cpu_info {
 
        spinlock_t amsg_lock;
        struct active_msg_list active_msgs;
-};
+}__attribute__((aligned(HW_CACHE_ALIGN)));
 
 typedef struct per_cpu_info NTPTV(t) NTPTV(a0t) NTPTV(a1t) NTPTV(a2t) per_cpu_info_t;
 
@@ -46,6 +46,7 @@ extern volatile uint8_t RO num_cpus;
 /* SMP bootup functions */
 void smp_boot(void);
 void smp_idle(void);
+void smp_percpu_init(void); // this must be called by each core individually
 
 /* SMP utility functions */
 int smp_call_function_self(poly_isr_t handler, TV(t) data,
index 6cab0fb..d99fc1c 100644 (file)
@@ -52,7 +52,7 @@ void manager(void)
        switch (progress++) {
                case 0:
                        //p = kfs_proc_create(kfs_lookup_path("roslib_mproctests"));
-                       p = kfs_proc_create(kfs_lookup_path("roslib_mhello"));
+                       p = kfs_proc_create(kfs_lookup_path("roslib_spawn"));
                        // being proper and all:
                        spin_lock_irqsave(&p->proc_lock);
                        proc_set_state(p, PROC_RUNNABLE_S);
index 6fc2633..4df51d8 100644 (file)
@@ -779,8 +779,8 @@ void print_proc_info(pid_t pid)
                printk("Bad PID.\n");
                return;
        }
-       spin_lock_irqsave(&p->proc_lock);
        spinlock_debug(&p->proc_lock);
+       spin_lock_irqsave(&p->proc_lock);
        printk("struct proc: %p\n", p);
        printk("PID: %d\n", p->env_id);
        printk("PPID: %d\n", p->env_parent_id);
index 3905de2..83c4caf 100644 (file)
@@ -5,6 +5,7 @@
 
 int main(int argc, char** argv)
 {
+       #if 0
        /* try some bad combos */
        int pid = proc_create("garbagexxx");
        cprintf("Garbage pid result: %d\n", pid);
@@ -14,10 +15,11 @@ int main(int argc, char** argv)
 
        err = proc_run(-1);
        cprintf("proc_run(-1) error: %e\n", err);
-
+       #endif
 
        #define NUM_KIDS 5
        int child_pid[NUM_KIDS];
+       #if 0
        cprintf("U: attempting to create hello(s)\n");
        for (int i = 0; i < NUM_KIDS; i++)
                child_pid[i] = proc_create("roslib_hello");
@@ -26,6 +28,12 @@ int main(int argc, char** argv)
                cprintf("U: attempting to run hello (pid: %d)\n", child_pid[i]);
                proc_run(child_pid[i]);
        }
-
+       #endif
+       cprintf("U: attempting to create and run hello\n");
+       child_pid[0] = proc_create("roslib_hello");
+       proc_run(child_pid[0]);
+       cprintf("U: attempting to create and run mhello\n");
+       child_pid[1] = proc_create("roslib_mhello");
+       proc_run(child_pid[1]);
        return 0;
 }