RFC: Dynamic segment table allocation

David Gibson david at gibson.dropbear.id.au
Wed Jun 30 16:51:05 EST 2004


Can anyone see a problem with the patch below?  If not, I plan to push
it to Andrew in the next few days.  Boots on a 4-way Power3 (RS/6000
270) and an RS64 iSeries lpar.

PPC64 machines before Power4 need a segment table page allocated for
each CPU.  Currently these are allocated statically in a big array in
head.S for all CPUs.  However, except for the boot CPU, there are no
particular constraints on the segment table's location, and the
secondary CPUs don't come up until quite late when get_free_pages() is
operational.

This patch dynamically allocates segment table pages as the secondary
CPUs come up.  This reduces the kernel image size by 192k...

Signed-off-by: David Gibson <david at gibson.dropbear.id.au>

Index: working-2.6/arch/ppc64/kernel/head.S
===================================================================
--- working-2.6.orig/arch/ppc64/kernel/head.S	2004-06-30 16:01:34.503673448 +1000
+++ working-2.6/arch/ppc64/kernel/head.S	2004-06-30 16:04:44.314702496 +1000
@@ -2201,11 +2201,6 @@
 ioremap_dir:
 	.space	4096

-/* 1 page segment table per cpu (max 48, cpu0 allocated at STAB0_PHYS_ADDR) */
-	.globl	stab_array
-stab_array:
-	.space	4096 * 48
-
 /*
  * This space gets a copy of optional info passed to us by the bootstrap
  * Used to pass parameters into the kernel like root=/dev/sda1, etc.
Index: working-2.6/arch/ppc64/kernel/smp.c
===================================================================
--- working-2.6.orig/arch/ppc64/kernel/smp.c	2004-06-30 16:01:34.506672992 +1000
+++ working-2.6/arch/ppc64/kernel/smp.c	2004-06-30 16:12:44.944722104 +1000
@@ -877,16 +877,17 @@
 	paca[cpu].default_decr = tb_ticks_per_jiffy / decr_overclock;

 	if (!(cur_cpu_spec->cpu_features & CPU_FTR_SLB)) {
-		void *tmp;
+		unsigned long newstab;

-		/* maximum of 48 CPUs on machines with a segment table */
-		if (cpu >= 48)
-			BUG();
-
-		tmp = &stab_array[PAGE_SIZE * cpu];
-		memset(tmp, 0, PAGE_SIZE);
-		paca[cpu].stab_addr = (unsigned long)tmp;
-		paca[cpu].stab_real = virt_to_abs(tmp);
+		newstab = __get_free_page(GFP_KERNEL);
+		if (! newstab) {
+			printk(KERN_ERR "__cpu_up(): Unable to allocate segment table for CPU %d\n", cpu);
+			return -ENOMEM;
+		}
+
+		memset((void *)newstab, 0, PAGE_SIZE);
+		paca[cpu].stab_addr = newstab;
+		paca[cpu].stab_real = virt_to_abs(newstab);
 	}

 	/* The information for processor bringup must


--
David Gibson			| For every complex problem there is a
david AT gibson.dropbear.id.au	| solution which is simple, neat and
				| wrong.
http://www.ozlabs.org/people/dgibson

** Sent via the linuxppc64-dev mail list. See http://lists.linuxppc.org/





More information about the Linuxppc64-dev mailing list