Fixes smp_call_function (again)
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 12 Jan 2015 17:13:45 +0000 (12:13 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Mon, 12 Jan 2015 17:13:45 +0000 (12:13 -0500)
2e856c58 was wrong; past-barret was right.  It's a checklist, so you tick off
items as they are done.  The confusing part when debugging was that the IRQ
handlers were firing, but were not downing the checklist.

The root of the problem was that the SMP_CALL IRQ numbers didn't line up with
the "clever" initialization routine used for the handler wrappers.  A while
back I reorganized the x86 IRQ vectors and moved SMP_CALL0 to 224 from 240.
The initialization didn't change, so the smp_call vectors were still 240.  240
happened to be the timer IRQ, which means an smp_call_function would run on the
timer tick too.  The main thing was that the check for downing the checklist
didn't happen, since it expected 224-228, so the checklist would never clear.
That appeared like the waiting code was wrong, which it was not.

kern/arch/x86/smp_boot.c
kern/arch/x86/trap.h
kern/src/atomic.c

index 981dc00..2900e41 100644 (file)
@@ -38,7 +38,7 @@ barrier_t generic_barrier;
 
 #define INIT_HANDLER_WRAPPER(v)                                     \
 {                                                                   \
-       handler_wrappers[(v)].vector = 0xf##v;                          \
+       handler_wrappers[(v)].vector = 0xe##v;                          \
        handler_wrappers[(v)].cpu_list = &f##v##_cpu_list;              \
        handler_wrappers[(v)].cpu_list->mask.size = num_cpus;           \
 }
index 066d488..0ee5767 100644 (file)
@@ -52,7 +52,8 @@
 
 /* 224-239 are OS IPI vectors (0xe0-0xef) */
 /* smp_call_function IPIs, keep in sync with NUM_HANDLER_WRAPPERS.
- * SMP_CALL0 needs to be 16-aligned (we mask in x86/trap.c) */
+ * SMP_CALL0 needs to be 16-aligned (we mask in x86/trap.c).  If you move these,
+ * also change INIT_HANDLER_WRAPPER */
 #define I_SMP_CALL0                            224
 #define I_SMP_CALL1                            (I_SMP_CALL0 + 1)
 #define I_SMP_CALL2                            (I_SMP_CALL0 + 2)
index 2552f3b..cc73a71 100644 (file)
@@ -274,7 +274,7 @@ int waiton_checklist(checklist_t* list)
 {
        extern atomic_t outstanding_calls;
        // can consider breakout out early, like above, and erroring out
-       while (!checklist_is_full(list))
+       while (!checklist_is_clear(list))
                cpu_relax();
        spin_unlock_irqsave(&list->lock);
        // global counter of wrappers either waited on or being contended for.