On Wed, Jul 15, 2015 at 05:07:39AM +0000, Miod Vallat wrote:
> > The patch below solves stalled IPI processing on octeon. When IPIs are
> > finally enabled during boot, some kernel threads have already been
> > started. There seems to be no mechanism that would update interrupt
> > masks for a running thread, so the early threads run IPIs disabled.
> > This will lead to a deadlock quite soon after launching other cores.
> > The patch makes the registering of the IPI handler happen early enough
> > for the correct idle_mask to propagate to all threads.
> 
> This makes sense. However, your `ipi_enabled' new variable basically
> mimics an `if (ipi_handler != NULL)' test, so there is no need for an
> extra variable.

Here is a revised patch.


Index: arch/octeon/octeon/machdep.c
===================================================================
RCS file: src/sys/arch/octeon/octeon/machdep.c,v
retrieving revision 1.64
diff -u -p -r1.64 machdep.c
--- arch/octeon/octeon/machdep.c        25 Jun 2015 10:56:00 -0000      1.64
+++ arch/octeon/octeon/machdep.c        15 Jul 2015 13:21:02 -0000
@@ -128,6 +128,10 @@ int                octeon_cpuspeed(int *);
 static void    process_bootargs(void);
 static uint64_t        get_ncpusfound(void);
 
+#ifdef MULTIPROCESSOR
+uint32_t       ipi_intr(uint32_t, struct trap_frame *);
+#endif
+
 extern void    parse_uboot_root(void);
 
 cons_decl(cn30xxuart);
@@ -487,6 +491,10 @@ mips_init(__register_t a0, __register_t 
                Debugger();
 #endif
 
+#ifdef MULTIPROCESSOR
+       set_intr(INTPRI_IPI, CR_INT_1, ipi_intr);
+#endif
+
        /*
         * Return the new kernel stack pointer.
         */
@@ -771,8 +779,6 @@ uint32_t cpu_spinup_mask = 0;
 uint64_t cpu_spinup_a0, cpu_spinup_sp;
 static int (*ipi_handler)(void *);
 
-uint32_t ipi_intr(uint32_t, struct trap_frame *);
-
 extern bus_space_t iobus_tag;
 extern bus_space_handle_t iobus_h;
 
@@ -852,6 +858,9 @@ ipi_intr(uint32_t hwpend, struct trap_fr
         */
        bus_space_write_8(&iobus_tag, iobus_h, CIU_IP3_EN0(cpuid), 0);
 
+       if (ipi_handler == NULL)
+               return hwpend;
+
        ipi_handler((void *)cpuid);
 
        /*
@@ -872,7 +881,6 @@ hw_ipi_intr_establish(int (*func)(void *
                0xffffffff);
        bus_space_write_8(&iobus_tag, iobus_h, CIU_IP3_EN0(cpuid),
                (1ULL << CIU_INT_MBOX0)|(1ULL << CIU_INT_MBOX1));
-       set_intr(INTPRI_IPI, CR_INT_1, ipi_intr);
 
        return 0;
 };

Reply via email to