[PATCH] ppc64: pSeries shared processor fixes

Anton Blanchard anton at samba.org
Fri Dec 10 03:07:05 EST 2004


Hi,

It turns out there are more issues with our VPA code:

1. vpa_init doesnt report errors when it fails. This was masking a bug
where the VPA spanned 2 pages and phyp failed to register it.
2. We call idle_setup before we initialise the boot cpus vpa. This means
we never select the shared processor idle loop.
3. We dont call vpa_init on UP kernels.

I think this should go in ASAP, can people give it a once over?

Signed-off-by: Anton Blanchard <anton at samba.org>

diff -puN arch/ppc64/kernel/smp.c~fix_vpa arch/ppc64/kernel/smp.c
--- foobar2/arch/ppc64/kernel/smp.c~fix_vpa	2004-12-10 02:26:35.070363325 +1100
+++ foobar2-anton/arch/ppc64/kernel/smp.c	2004-12-10 02:26:35.113360044 +1100
@@ -76,8 +76,6 @@ extern unsigned char stab_array[];
 
 extern int cpu_idle(void *unused);
 void smp_call_function_interrupt(void);
-extern long register_vpa(unsigned long flags, unsigned long proc,
-			 unsigned long vpa);
 
 int smt_enabled_at_boot = 1;
 
diff -puN arch/ppc64/kernel/pSeries_smp.c~fix_vpa arch/ppc64/kernel/pSeries_smp.c
--- foobar2/arch/ppc64/kernel/pSeries_smp.c~fix_vpa	2004-12-10 02:26:35.075362944 +1100
+++ foobar2-anton/arch/ppc64/kernel/pSeries_smp.c	2004-12-10 02:26:35.115359891 +1100
@@ -59,16 +59,6 @@
 
 extern void pseries_secondary_smp_init(unsigned long); 
 
-static void vpa_init(int cpu)
-{
-	unsigned long flags, pcpu = get_hard_smp_processor_id(cpu);
-
-	/* Register the Virtual Processor Area (VPA) */
-	flags = 1UL << (63 - 18);
-	register_vpa(flags, pcpu, __pa((unsigned long)&(paca[cpu].lppaca)));
-}
-
-
 /* Get state of physical CPU.
  * Return codes:
  *	0	- The processor is in the RTAS stopped state
diff -puN arch/ppc64/kernel/setup.c~fix_vpa arch/ppc64/kernel/setup.c
--- foobar2/arch/ppc64/kernel/setup.c~fix_vpa	2004-12-10 02:26:35.081362486 +1100
+++ foobar2-anton/arch/ppc64/kernel/setup.c	2004-12-10 02:26:35.118359662 +1100
@@ -1020,11 +1020,11 @@ void __init setup_arch(char **cmdline_p)
 	/* set up the bootmem stuff with available memory */
 	do_init_bootmem();
 
+	ppc_md.setup_arch();
+
 	/* Select the correct idle loop for the platform. */
 	idle_setup();
 
-	ppc_md.setup_arch();
-
 	paging_init();
 	ppc64_boot_msg(0x15, "Setup Done");
 }
diff -puN arch/ppc64/kernel/pSeries_setup.c~fix_vpa arch/ppc64/kernel/pSeries_setup.c
--- foobar2/arch/ppc64/kernel/pSeries_setup.c~fix_vpa	2004-12-10 02:26:35.085362180 +1100
+++ foobar2-anton/arch/ppc64/kernel/pSeries_setup.c	2004-12-10 02:26:35.120359510 +1100
@@ -234,6 +234,9 @@ static void __init pSeries_setup_arch(vo
 #endif
 
 	pSeries_nvram_init();
+
+	if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR)
+		vpa_init(boot_cpuid);
 }
 
 static int __init pSeries_init_panel(void)
diff -puN include/asm-ppc64/plpar_wrappers.h~fix_vpa include/asm-ppc64/plpar_wrappers.h
--- foobar2/include/asm-ppc64/plpar_wrappers.h~fix_vpa	2004-12-10 02:26:35.090361799 +1100
+++ foobar2-anton/include/asm-ppc64/plpar_wrappers.h	2004-12-10 02:26:35.121359433 +1100
@@ -22,12 +22,14 @@ static inline long cede_processor(void)
 	return(0); 
 }
 
-static inline long register_vpa(unsigned long flags, unsigned long proc, unsigned long vpa)
+static inline long register_vpa(unsigned long flags, unsigned long proc,
+				unsigned long vpa)
 {
-	plpar_hcall_norets(H_REGISTER_VPA, flags, proc, vpa);
-	return(0); 
+	return plpar_hcall_norets(H_REGISTER_VPA, flags, proc, vpa);
 }
 
+void vpa_init(int cpu);
+
 static inline long plpar_pte_remove(unsigned long flags,
 				    unsigned long ptex,
 				    unsigned long avpn,
diff -puN arch/ppc64/kernel/pSeries_lpar.c~fix_vpa arch/ppc64/kernel/pSeries_lpar.c
--- foobar2/arch/ppc64/kernel/pSeries_lpar.c~fix_vpa	2004-12-10 02:26:35.095361417 +1100
+++ foobar2-anton/arch/ppc64/kernel/pSeries_lpar.c	2004-12-10 02:55:47.622076537 +1100
@@ -259,6 +259,22 @@ out:
 	return found;
 }
 
+void vpa_init(int cpu)
+{
+	int hwcpu = get_hard_smp_processor_id(cpu);
+	unsigned long vpa = (unsigned long)&(paca[cpu].lppaca);
+	long ret;
+	unsigned long flags;
+
+	/* Register the Virtual Processor Area (VPA) */
+	flags = 1UL << (63 - 18);
+	ret = register_vpa(flags, hwcpu, __pa(vpa));
+
+	if (ret)
+		printk(KERN_ERR "WARNING: vpa_init: VPA registration for "
+				"cpu %d (hw %d) of area %lx returns %ld\n",
+				cpu, hwcpu, __pa(vpa), ret);
+}
 
 long pSeries_lpar_hpte_insert(unsigned long hpte_group,
 			      unsigned long va, unsigned long prpn,
_



More information about the Linuxppc64-dev mailing list