mirror of https://github.com/torvalds/linux.git
While testing cpu hoptlug (cpu down and up in loops) on kernel 4.4, it was observed that occasionally check for cpu online will fail in kernel/cpu.c, _cpu_up: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/tree/kernel/cpu.c?h=v4.4.79#n485 518 /* Arch-specific enabling code. */ 519 ret = __cpu_up(cpu, idle); 520 521 if (ret != 0) 522 goto out_notify; 523 BUG_ON(!cpu_online(cpu)); Reason is race between start_secondary and _cpu_up. cpu_callin_map is set before cpu_online_mask. In __cpu_up, cpu_callin_map is waited for, but cpu online mask is not, resulting in race in which secondary processor started and set cpu_callin_map, but not yet set the online mask,resulting in above BUG being hit. Upstream differs in the area. cpu_online check is in bringup_wait_for_ap, which is after cpu reached AP_ONLINE_IDLE,where secondary passed its start function. Nonetheless, fix makes start_secondary safe and not depending on other locks throughout the code. It protects as well against cpu_online checks put in between sometimes in the future. Fix this by moving completion after all flags are set. Signed-off-by: Matija Glavinic Pecotic <matija.glavinic-pecotic.ext@nokia.com> Cc: Alexander Sverdlin <alexander.sverdlin@nokia.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/16925/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org> |
||
|---|---|---|
| .. | ||
| .gitignore | ||
| 8250-platform.c | ||
| Makefile | ||
| asm-offsets.c | ||
| binfmt_elfn32.c | ||
| binfmt_elfo32.c | ||
| bmips_5xxx_init.S | ||
| bmips_vec.S | ||
| branch.c | ||
| cacheinfo.c | ||
| cevt-bcm1480.c | ||
| cevt-ds1287.c | ||
| cevt-gt641xx.c | ||
| cevt-r4k.c | ||
| cevt-sb1250.c | ||
| cevt-txx9.c | ||
| cmpxchg.c | ||
| cps-vec-ns16550.S | ||
| cps-vec.S | ||
| cpu-bugs64.c | ||
| cpu-probe.c | ||
| crash.c | ||
| crash_dump.c | ||
| csrc-bcm1480.c | ||
| csrc-ioasic.c | ||
| csrc-r4k.c | ||
| csrc-sb1250.c | ||
| early_printk.c | ||
| early_printk_8250.c | ||
| elf.c | ||
| entry.S | ||
| ftrace.c | ||
| genex.S | ||
| gpio_txx9.c | ||
| head.S | ||
| i8253.c | ||
| idle.c | ||
| irq-gt641xx.c | ||
| irq-msc01.c | ||
| irq-rm7000.c | ||
| irq.c | ||
| irq_txx9.c | ||
| jump_label.c | ||
| kgdb.c | ||
| kprobes.c | ||
| linux32.c | ||
| machine_kexec.c | ||
| mcount.S | ||
| mips-cm.c | ||
| mips-cpc.c | ||
| mips-mt-fpaff.c | ||
| mips-mt.c | ||
| mips-r2-to-r6-emul.c | ||
| mips_machine.c | ||
| module.c | ||
| octeon_switch.S | ||
| perf_event.c | ||
| perf_event_mipsxx.c | ||
| pm-cps.c | ||
| pm.c | ||
| probes-common.h | ||
| proc.c | ||
| process.c | ||
| prom.c | ||
| ptrace.c | ||
| ptrace32.c | ||
| r4k_fpu.S | ||
| r4k_switch.S | ||
| r2300_fpu.S | ||
| r2300_switch.S | ||
| r6000_fpu.S | ||
| relocate.c | ||
| relocate_kernel.S | ||
| reset.c | ||
| rtlx-cmp.c | ||
| rtlx-mt.c | ||
| rtlx.c | ||
| scall32-o32.S | ||
| scall64-64.S | ||
| scall64-n32.S | ||
| scall64-o32.S | ||
| segment.c | ||
| setup.c | ||
| signal-common.h | ||
| signal.c | ||
| signal32.c | ||
| signal_n32.c | ||
| signal_o32.c | ||
| smp-bmips.c | ||
| smp-cmp.c | ||
| smp-cps.c | ||
| smp-mt.c | ||
| smp-up.c | ||
| smp.c | ||
| spinlock_test.c | ||
| spram.c | ||
| stacktrace.c | ||
| sync-r4k.c | ||
| syscall.c | ||
| sysrq.c | ||
| time.c | ||
| topology.c | ||
| traps.c | ||
| unaligned.c | ||
| uprobes.c | ||
| vdso.c | ||
| vmlinux.lds.S | ||
| vpe-cmp.c | ||
| vpe-mt.c | ||
| vpe.c | ||
| watch.c | ||