Skip to contentSkip to conversation

Change cpu_data[] and cpu_devices[] to per_cpu variables

PATCH In review Helge Deller 2 participants 8 messages May 2, 2008 – May 16, 2008 PA-RISC architecture

lore
Share & tools
lore

Helge Deller

author maintainer
#0 lore raw

PATCH 1/1 Change cpu_data[] and cpu_devices[] to per_cpu variables

Change cpu_data[] and cpu_devices[] from array sized by NR_CPUS to per_cpu variables.

 arch/parisc/Kconfig            |    8 +++-
 arch/parisc/kernel/irq.c       |   11 +++---
 arch/parisc/kernel/processor.c |   68 +++++++++++++++++++++--------------------
 arch/parisc/kernel/setup.c     |    2 -
 arch/parisc/kernel/smp.c       |   32 +++++++++----------
 arch/parisc/kernel/time.c      |    4 +-
 arch/parisc/kernel/topology.c  |    4 +-
 include/asm-parisc/processor.h |    4 +-
 8 files changed, 69 insertions(+), 64 deletions(-)
arch/parisc/Kconfig +6 -2
index bc7a19d..6dcd2a4 100644
@@ -253,10 +253,14 @@ config HPUX
 	depends on !64BIT
 
 config NR_CPUS
-	int "Maximum number of CPUs (2-32)"
-	range 2 32
+	int "Maximum number of CPUs (2-255)"
+	range 2 255
 	depends on SMP
 	default "32"
+	help
+	  This allows you to specify the maximum number of CPUs which this
+	  kernel will support.  The maximum supported value is 255 and the
+	  minimum value which makes sense is 2.
 
 endmenu
 
arch/parisc/kernel/irq.c +6 -5
index 23ef950..3ee6b33 100644
@@ -298,7 +298,7 @@ unsigned long txn_affinity_addr(unsigned int irq, int cpu)
 	irq_desc[irq].affinity = cpumask_of_cpu(cpu);
 #endif
 
-	return cpu_data[cpu].txn_addr;
+	return per_cpu(cpu_data, cpu).txn_addr;
 }
 
 
@@ -309,8 +309,9 @@ unsigned long txn_alloc_addr(unsigned int virt_irq)
 	next_cpu++; /* assign to "next" CPU we want this bugger on */
 
 	/* validate entry */
-	while ((next_cpu < NR_CPUS) && (!cpu_data[next_cpu].txn_addr || 
-		!cpu_online(next_cpu)))
+	while ((next_cpu < NR_CPUS) &&
+		(!per_cpu(cpu_data, next_cpu).txn_addr ||
+		 !cpu_online(next_cpu)))
 		next_cpu++;
 
 	if (next_cpu >= NR_CPUS) 
@@ -359,7 +360,7 @@ void do_cpu_irq_mask(struct pt_regs *regs)
 		printk(KERN_DEBUG "redirecting irq %d from CPU %d to %d\n",
 		       irq, smp_processor_id(), cpu);
 		gsc_writel(irq + CPU_IRQ_BASE,
-			   cpu_data[cpu].hpa);
+			   per_cpu(cpu_data, cpu).hpa);
 		goto set_out;
 	}
 #endif
@@ -421,5 +422,5 @@ void __init init_IRQ(void)
 
 void ack_bad_irq(unsigned int irq)
 {
-	printk("unexpected IRQ %d\n", irq);
+	printk(KERN_WARNING "unexpected IRQ %d\n", irq);
 }
arch/parisc/kernel/processor.c +35 -33

140 lines not on this page · raw message

arch/parisc/kernel/setup.c +1 -1
index 39e7c5a..f2656ce 100644
@@ -319,7 +319,7 @@ static int __init parisc_init(void)
 	
 	processor_init();
 	printk(KERN_INFO "CPU(s): %d x %s at %d.%06d MHz\n",
-			boot_cpu_data.cpu_count,
+			num_present_cpus(),
 			boot_cpu_data.cpu_name,
 			boot_cpu_data.cpu_hz / 1000000,
 			boot_cpu_data.cpu_hz % 1000000	);
arch/parisc/kernel/smp.c +15 -17
index 85fc775..1fdea4d 100644
@@ -56,16 +56,17 @@ static int smp_debug_lvl = 0;
 		if (lvl >= smp_debug_lvl)	\
 			printk(printargs);
 #else
-#define smp_debug(lvl, ...)
+#define smp_debug(lvl, ...)	do { } while(0)
 #endif /* DEBUG_SMP */
 
 DEFINE_SPINLOCK(smp_lock);
 
 volatile struct task_struct *smp_init_current_idle_task;
 
-static volatile int cpu_now_booting __read_mostly = 0;	/* track which CPU is booting */
+/* track which CPU is booting */
+static volatile int cpu_now_booting __cpuinitdata;
 
-static int parisc_max_cpus __read_mostly = 1;
+static int parisc_max_cpus __cpuinitdata = 1;
 
 /* online cpus are ones that we've managed to bring up completely
  * possible cpus are all valid cpu 
@@ -146,7 +147,7 @@ irqreturn_t
 ipi_interrupt(int irq, void *dev_id) 
 {
 	int this_cpu = smp_processor_id();
-	struct cpuinfo_parisc *p = &cpu_data[this_cpu];
+	struct cpuinfo_parisc *p = &per_cpu(cpu_data, this_cpu);
 	unsigned long ops;
 	unsigned long flags;
 
@@ -246,13 +247,13 @@ ipi_interrupt(int irq, void *dev_id)
 static inline void
 ipi_send(int cpu, enum ipi_message_type op)
 {
-	struct cpuinfo_parisc *p = &cpu_data[cpu];
+	struct cpuinfo_parisc *p = &per_cpu(cpu_data, cpu);
 	spinlock_t *lock = &per_cpu(ipi_lock, cpu);
 	unsigned long flags;
 
 	spin_lock_irqsave(lock, flags);
 	p->pending_ipi |= 1 << op;
-	gsc_writel(IPI_IRQ - CPU_IRQ_BASE, cpu_data[cpu].hpa);
+	gsc_writel(IPI_IRQ - CPU_IRQ_BASE, p->hpa);
 	spin_unlock_irqrestore(lock, flags);
 }
 
@@ -260,10 +261,7 @@ ipi_send(int cpu, enum ipi_message_type op)
 static inline void
 send_IPI_single(int dest_cpu, enum ipi_message_type op)
 {
-	if (dest_cpu == NO_PROC_ID) {
-		BUG();
-		return;
-	}
+	BUG_ON(dest_cpu == NO_PROC_ID);
 
 	ipi_send(dest_cpu, op);
 }
@@ -416,8 +414,7 @@ smp_cpu_init(int cpunum)
 	/* Initialise the idle task for this CPU */
 	atomic_inc(&init_mm.mm_count);
 	current->active_mm = &init_mm;
-	if(current->mm)
-		BUG();
+	BUG_ON(current->mm);
 	enter_lazy_tlb(&init_mm, current);
 
 	init_IRQ();   /* make sure no IRQs are enabled or pending */
@@ -452,6 +449,7 @@ void __init smp_callin(void)
  */
 int __cpuinit smp_boot_one_cpu(int cpuid)
 {
+	const struct cpuinfo_parisc *p = &per_cpu(cpu_data, cpuid);
 	struct task_struct *idle;
 	long timeout;
 
@@ -483,7 +481,7 @@ int __cpuinit smp_boot_one_cpu(int cpuid)
 	smp_init_current_idle_task = idle ;
 	mb();
 
-	printk("Releasing cpu %d now, hpa=%lx\n", cpuid, cpu_data[cpuid].hpa);
+	printk(KERN_INFO "Releasing cpu %d now, hpa=%lx\n", cpuid, p->hpa);
 
 	/*
 	** This gets PDC to release the CPU from a very tight loop.
@@ -494,7 +492,7 @@ int __cpuinit smp_boot_one_cpu(int cpuid)
 	** EIR{0}). MEM_RENDEZ is valid only when it is nonzero and the 
 	** contents of memory are valid."
 	*/
-	gsc_writel(TIMER_IRQ - CPU_IRQ_BASE, cpu_data[cpuid].hpa);
+	gsc_writel(TIMER_IRQ - CPU_IRQ_BASE, p->hpa);
 	mb();
 
 	/* 
@@ -526,12 +524,12 @@ alive:
 	return 0;
 }
 
-void __devinit smp_prepare_boot_cpu(void)
+void __init smp_prepare_boot_cpu(void)
 {
-	int bootstrap_processor=cpu_data[0].cpuid;	/* CPU ID of BSP */
+	int bootstrap_processor = per_cpu(cpu_data, 0).cpuid;
 
 	/* Setup BSP mappings */
-	printk("SMP: bootstrap CPU ID is %d\n",bootstrap_processor);
+	printk(KERN_INFO "SMP: bootstrap CPU ID is %d\n", bootstrap_processor);
 
 	cpu_set(bootstrap_processor, cpu_online_map);
 	cpu_set(bootstrap_processor, cpu_present_map);
arch/parisc/kernel/time.c +2 -2
index 24be86b..9db61b4 100644
@@ -59,7 +59,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id)
 	unsigned long cycles_elapsed, ticks_elapsed;
 	unsigned long cycles_remainder;
 	unsigned int cpu = smp_processor_id();
-	struct cpuinfo_parisc *cpuinfo = &cpu_data[cpu];
+	struct cpuinfo_parisc *cpuinfo = &per_cpu(cpu_data, cpu);
 
 	/* gcc can optimize for "read-only" case with a local clocktick */
 	unsigned long cpt = clocktick;
@@ -212,7 +212,7 @@ void __init start_cpu_itimer(void)
 
 	mtctl(next_tick, 16);		/* kick off Interval Timer (CR16) */
 
-	cpu_data[cpu].it_value = next_tick;
+	per_cpu(cpu_data, cpu).it_value = next_tick;
 }
 
 void __init time_init(void)
arch/parisc/kernel/topology.c +2 -2
index d71cb01..f515938 100644
@@ -22,14 +22,14 @@
 #include <linux/cpu.h>
 #include <linux/cache.h>
 
-static struct cpu cpu_devices[NR_CPUS] __read_mostly;
+static DEFINE_PER_CPU(struct cpu, cpu_devices);
 
 static int __init topology_init(void)
 {
 	int num;
 
 	for_each_present_cpu(num) {
-		register_cpu(&cpu_devices[num], num);
+		register_cpu(&per_cpu(cpu_devices, num), num);
 	}
 	return 0;
 }
include/asm-parisc/processor.h +2 -2
index 3c9d348..9d64df8 100644
@@ -17,6 +17,7 @@
 #include <asm/ptrace.h>
 #include <asm/types.h>
 #include <asm/system.h>
+#include <asm/percpu.h>
 #endif /* __ASSEMBLY__ */
 
 #define KERNEL_STACK_SIZE 	(4*PAGE_SIZE)
@@ -109,8 +110,7 @@ struct cpuinfo_parisc {
 };
 
 extern struct system_cpuinfo_parisc boot_cpu_data;
-extern struct cpuinfo_parisc cpu_data[NR_CPUS];
-#define current_cpu_data cpu_data[smp_processor_id()]
+DECLARE_PER_CPU(struct cpuinfo_parisc, cpu_data);
 
 #define CPU_HVERSION ((boot_cpu_data.hversion >> 4) & 0x0FFF)
 
#1 lore raw

arch/parisc/Kconfig config HPUX · line 263

Quoted 12 lines · Helge Deller

config NR_CPUS

arch/parisc/Kconfig +6 -2
-	int "Maximum number of CPUs (2-32)"
-	range 2 32
+	int "Maximum number of CPUs (2-255)"
+	range 2 255
 	depends on SMP
 	default "32"
+	help
+	  This allows you to specify the maximum number of CPUs which this
+	  kernel will support.  The maximum supported value is 255 and the
+	  minimum value which makes sense is 2.

Er. Why?

author maintainer
#2 lore raw
Quoted 15 lines · Kyle McMartin

arch/parisc/Kconfig config HPUX · line 263

Quoted 12 lines · Helge Deller

config NR_CPUS

arch/parisc/Kconfig +6 -2
-	int "Maximum number of CPUs (2-32)"
-	range 2 32
+	int "Maximum number of CPUs (2-255)"
+	range 2 255
 	depends on SMP
 	default "32"
+	help
+	  This allows you to specify the maximum number of CPUs which this
+	  kernel will support.  The maximum supported value is 255 and the
+	  minimum value which makes sense is 2.

Er. Why?

This is mostly copied over from x86 arch and I think it doesn't make anything worse... Doesn't Superdomes support more than 32 CPUs ? (although I think superdome isn't supported yet, or is it?)

Helge

#3 lore raw
Quoted 4 lines · Helge Deller

This is mostly copied over from x86 arch and I think it doesn't make anything worse...
Doesn't Superdomes support more than 32 CPUs ? (although I think superdome isn't supported yet, or is it?)

We don't support anything bigger than 8-way (and only because N-class is special and has two cpu busses). Much work would be needed to support more than that for Superdome.

r, Kyle

author maintainer
#4 lore raw
Quoted 7 lines · Kyle McMartin
Quoted 2 lines · Helge Deller

This is mostly copied over from x86 arch and I think it doesn't make anything worse... Doesn't Superdomes support more than 32 CPUs ? (although I think superdome isn't supported yet, or is it?)

We don't support anything bigger than 8-way (and only because N-class is special and has two cpu busses). Much work would be needed to support more than that for Superdome.

Ok, no problem if you drop the Kconfig part of the patch. The other parts of the patch are still useful nevertheless.

Helge

#5 lore raw
Quoted 7 lines · Helge Deller
Quoted 6 lines · Kyle McMartin
Quoted 4 lines · Helge Deller

This is mostly copied over from x86 arch and I think it doesn't make anything worse...
Doesn't Superdomes support more than 32 CPUs ? (although I think superdome isn't supported yet, or is it?)

Quoted 7 lines
Quoted 3 lines

We don't support anything bigger than 8-way (and only because N-class is special and has two cpu busses). Much work would be needed to support more than that for Superdome.

Ok, no problem if you drop the Kconfig part of the patch. The other parts of the patch are still useful nevertheless.

I'll get it in for .27

cheers, Kyle

author maintainer
#6 lore raw
Quoted 5 lines · Kyle McMartin
Quoted 4 lines · Helge Deller
Quoted 3 lines · Kyle McMartin
Quoted 2 lines · Helge Deller

This is mostly copied over from x86 arch and I think it doesn't make anything worse... Doesn't Superdomes support more than 32 CPUs ? (although I think superdome isn't supported yet, or is it?)

Quoted 8 lines
Quoted 6 lines
Quoted 3 lines

We don't support anything bigger than 8-way (and only because N-class is special and has two cpu busses). Much work would be needed to support more than that for Superdome.

Ok, no problem if you drop the Kconfig part of the patch. The other parts of the patch are still useful nevertheless.

I'll get it in for .27

Thanks Kyle.

This is even my preferred solution, since I forgot to mention that I only was able to compile- and boot-test it on a UP machine, so a little more testing in SMP environments would be good.... (I don't have a SMP machine).

Helge

#7 lore raw
Quoted 4 lines · Helge Deller

This is even my preferred solution, since I forgot to mention that I only was able to compile- and boot-test it on a UP machine, so a little more testing in SMP environments would be good.... (I don't have a SMP machine).

Can you check how much shipping a machine to your house would be? My address is 1944 Juno Ave., Ottawa, Canada, K1H 6T2. (Not like it matters making this public, it's in the WHOIS for my domain anyway. ;-)

regards, Kyle