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; };