Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9b6695a8 authored by Ralf Baechle's avatar Ralf Baechle
Browse files

[MIPS] SMP: Fix initialization order bug.


    
A recent change requires cpu_possible_map to be initialized before
smp_sched_init() but most MIPS platforms were initializing their
processors in the prom_prepare_cpus callback of smp_prepare_cpus.  The
simple fix of calling prom_prepare_cpus from one of the earlier SMP
initialization hooks doesn't work well either since IPIs may require
init_IRQ() to have completed, so bit the bullet and split
prom_prepare_cpus into two initialization functions, plat_smp_setup
which is called early from setup_arch and plat_prepare_cpus called where
prom_prepare_cpus used to be called.
    
Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 3e6cb2d3
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -540,6 +540,9 @@ void __init setup_arch(char **cmdline_p)
	sparse_init();
	paging_init();
	resource_init();
#ifdef CONFIG_SMP
	plat_smp_setup();
#endif
}

int __init fpu_disable(char *s)
+1 −1
Original line number Diff line number Diff line
@@ -236,7 +236,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
	init_new_context(current, &init_mm);
	current_thread_info()->cpu = 0;
	smp_tune_scheduling();
	prom_prepare_cpus(max_cpus);
	plat_prepare_cpus(max_cpus);
}

/* preload SMP state for boot cpu */
+7 −6
Original line number Diff line number Diff line
@@ -143,7 +143,7 @@ static struct irqaction irq_call = {
 * Make sure all CPU's are in a sensible state before we boot any of the
 * secondarys
 */
void prom_prepare_cpus(unsigned int max_cpus)
void plat_smp_setup(void)
{
	unsigned long val;
	int i, num;
@@ -179,12 +179,10 @@ void prom_prepare_cpus(unsigned int max_cpus)
				write_vpe_c0_vpeconf0(tmp);

				/* Record this as available CPU */
				if (i < max_cpus) {
				cpu_set(i, phys_cpu_present_map);
				__cpu_number_map[i]	= ++num;
				__cpu_logical_map[num]	= i;
			}
			}

			/* disable multi-threading with TC's */
			write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE);
@@ -241,7 +239,10 @@ void prom_prepare_cpus(unsigned int max_cpus)
		set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch);
		set_vi_handler (MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch);
	}
}

void __init plat_prepare_cpus(unsigned int max_cpus)
{
	cpu_ipi_resched_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_RESCHED_IRQ;
	cpu_ipi_call_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_CALL_IRQ;

+6 −18
Original line number Diff line number Diff line
@@ -50,37 +50,25 @@ void __init prom_grab_secondary(void)
 * We don't want to start the secondary CPU yet nor do we have a nice probing
 * feature in PMON so we just assume presence of the secondary core.
 */
static char maxcpus_string[] __initdata =
	KERN_WARNING "max_cpus set to 0; using 1 instead\n";

void __init prom_prepare_cpus(unsigned int max_cpus)
void __init plat_smp_setup(void)
{
	int enabled = 0, i;

	if (max_cpus == 0) {
		printk(maxcpus_string);
		max_cpus = 1;
	}
	int i;

	cpus_clear(phys_cpu_present_map);

	for (i = 0; i < 2; i++) {
		if (i == max_cpus)
			break;

		/*
		 * The boot CPU
		 */
		cpu_set(i, phys_cpu_present_map);
		__cpu_number_map[i]	= i;
		__cpu_logical_map[i]	= i;
		enabled++;
	}
}

void __init plat_prepare_cpus(unsigned int max_cpus)
{
	/*
	 * Be paranoid.  Enable the IPI only if we're really about to go SMP.
	 */
	if (enabled > 1)
	if (cpus_weight(cpu_possible_map))
		set_c0_status(STATUSF_IP5);
}

+6 −1
Original line number Diff line number Diff line
@@ -140,7 +140,7 @@ static __init void intr_clear_all(nasid_t nasid)
		REMOTE_HUB_CLR_INTR(nasid, i);
}

void __init prom_prepare_cpus(unsigned int max_cpus)
void __init plat_smp_setup(void)
{
	cnodeid_t	cnode;

@@ -161,6 +161,11 @@ void __init prom_prepare_cpus(unsigned int max_cpus)
	alloc_cpupda(0, 0);
}

void __init plat_prepare_cpus(unsigned int max_cpus)
{
	/* We already did everything necessary earlier */
}

/*
 * Launch a slave into smp_bootstrap().  It doesn't take an argument, and we
 * set sp to the kernel stack of the newly created idle process, gp to the proc
Loading