linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 01/37] powerpc: fix memory corruption from unallocated slaves
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
@ 2011-05-11  5:28 ` Milton Miller
  2011-05-11  5:28 ` [PATCH 02/37] powerpc: don't search for paca in freed memory Milton Miller
                   ` (36 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:28 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt

Commit 1fc711f7ffb01089efc58042cfdbac8573d1b59a (powerpc/kexec: Fix race
in kexec shutdown) moved the write to signal the cpu had exited the kernel
from before the transition to real mode in kexec_smp_wait to kexec_wait.

Unfornately it missed that kexec_wait is used both by cpus leaving the
kernel and by secondary slave cpus that were not allocated a paca for
what ever reason -- they could be beyond nr_cpus or not described in
the current device tree for whatever reason (for example, kexec-load
was not refreshed after a cpu hotplug operation).  Cpus coming through
that path they will write to paca[NR_CPUS] which is beyond the space
allocated for the paca data and overwrite memory not allocated to pacas
but very likely still real mode accessable).

Move the write back to kexec_smp_wait, which is used only by cpus that
found their paca, but after the transition to real mode.

Signed-off-by: Milton Miller <miltonm@bga.com>
Cc: <stable@kernel.org> # (1fc711f was backported to 2.6.32)
---
 arch/powerpc/kernel/misc_64.S |   13 ++++++++-----
 1 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
index 206a321..e89df59 100644
--- a/arch/powerpc/kernel/misc_64.S
+++ b/arch/powerpc/kernel/misc_64.S
@@ -462,7 +462,8 @@ _GLOBAL(disable_kernel_fp)
  * wait for the flag to change, indicating this kernel is going away but
  * the slave code for the next one is at addresses 0 to 100.
  *
- * This is used by all slaves.
+ * This is used by all slaves, even those that did not find a matching
+ * paca in the secondary startup code.
  *
  * Physical (hardware) cpu id should be in r3.
  */
@@ -471,10 +472,6 @@ _GLOBAL(kexec_wait)
 1:	mflr	r5
 	addi	r5,r5,kexec_flag-1b
 
-	li	r4,KEXEC_STATE_REAL_MODE
-	stb	r4,PACAKEXECSTATE(r13)
-	SYNC
-
 99:	HMT_LOW
 #ifdef CONFIG_KEXEC		/* use no memory without kexec */
 	lwz	r4,0(r5)
@@ -499,11 +496,17 @@ kexec_flag:
  *
  * get phys id from paca
  * switch to real mode
+ * mark the paca as no longer used
  * join other cpus in kexec_wait(phys_id)
  */
 _GLOBAL(kexec_smp_wait)
 	lhz	r3,PACAHWCPUID(r13)
 	bl	real_mode
+
+	li	r4,KEXEC_STATE_REAL_MODE
+	stb	r4,PACAKEXECSTATE(r13)
+	SYNC
+
 	b	.kexec_wait
 
 /*
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 02/37] powerpc: don't search for paca in freed memory
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
  2011-05-11  5:28 ` [PATCH 01/37] powerpc: fix memory corruption from unallocated slaves Milton Miller
@ 2011-05-11  5:28 ` Milton Miller
  2011-05-11  5:28 ` [PATCH 03/37] powerpc/kdump64: Don't reference freed memory as pacas Milton Miller
                   ` (35 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:28 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt

Starting with 1426d5a3bd07589534286375998c0c8c6fdc5260 (powerpc:
Dynamically allocate pacas) we free the memory for pacas beyond
cpu_possible, but we failed to update the loop the secondary cpus use
to find their paca.  If the system has running cpu threads for which
the kernel did not allocate a paca for they will search the memory that
was freed.  For instance this could happen when the device tree for
a kdump kernel was not updated after a cpu hotplug, or the kernel is
running with more cpus than the kernel was configured.

Since c1854e00727f50f7ac99e98d26ece04c087ef785 (powerpc: Set nr_cpu_ids
early and use it to free PACAs) we set nr_cpu_ids before telling the
cpus to advance, so use that to limit the search.

We can't reference nr_cpu_ids without CONFIG_SMP because it is defined
as 1 instead of a memory location, but any extra threads should be sent
to kexec_wait in that case anyways, so make that explicit and remove
the search loop for UP.

Note to stable: The fix also requires
c1854e00727f50f7ac99e98d26ece04c087ef785 (powerpc: Set
nr_cpu_ids early and use it to free PACAs) to function.  Also
9d07bc841c9779b4d7902e417f4e509996ce805d (Properly handshake CPUs going
out of boot spin loop) affects the second chunk, specifically the branch
target was 3b before and is 4b after that patch, and there was a blank
line before the #ifdef CONFIG_SMP that was removed

Cc: <stable@kernel.org> # .34.x: c1854e0072 powerpc: Set nr_cpu_ids early
Cc: <stable@kernel.org> # .34.x
Signed-off-by: Milton Miller <miltonm@bga.com>
---
 arch/powerpc/kernel/head_64.S |   13 ++++++++-----
 1 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 73d6e9a..ba50409 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -218,13 +218,19 @@ generic_secondary_common_init:
 	 */
 	LOAD_REG_ADDR(r13, paca)	/* Load paca pointer		 */
 	ld	r13,0(r13)		/* Get base vaddr of paca array	 */
+#ifndef CONFIG_SMP
+	addi	r13,r13,PACA_SIZE	/* know r13 if used accidentally */
+	b	.kexec_wait		/* wait for next kernel if !SMP	 */
+#else
+	LOAD_REG_ADDR(r7, nr_cpu_ids)	/* Load nr_cpu_ids address       */
+	lwz	r7,0(r7)		/* also the max paca allocated 	 */
 	li	r5,0			/* logical cpu id                */
 1:	lhz	r6,PACAHWCPUID(r13)	/* Load HW procid from paca      */
 	cmpw	r6,r24			/* Compare to our id             */
 	beq	2f
 	addi	r13,r13,PACA_SIZE	/* Loop to next PACA on miss     */
 	addi	r5,r5,1
-	cmpwi	r5,NR_CPUS
+	cmpw	r5,r7			/* Check if more pacas exist     */
 	blt	1b
 
 	mr	r3,r24			/* not found, copy phys to r3	 */
@@ -259,9 +265,6 @@ generic_secondary_common_init:
 4:	HMT_LOW
 	lbz	r23,PACAPROCSTART(r13)	/* Test if this processor should */
 					/* start.			 */
-#ifndef CONFIG_SMP
-	b	4b			/* Never go on non-SMP		 */
-#else
 	cmpwi	0,r23,0
 	beq	4b			/* Loop until told to go	 */
 
@@ -273,7 +276,7 @@ generic_secondary_common_init:
 	subi	r1,r1,STACK_FRAME_OVERHEAD
 
 	b	__secondary_start
-#endif
+#endif /* SMP */
 
 /*
  * Turn the MMU off.
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 03/37] powerpc/kdump64: Don't reference freed memory as pacas
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
  2011-05-11  5:28 ` [PATCH 01/37] powerpc: fix memory corruption from unallocated slaves Milton Miller
  2011-05-11  5:28 ` [PATCH 02/37] powerpc: don't search for paca in freed memory Milton Miller
@ 2011-05-11  5:28 ` Milton Miller
  2011-05-11  5:28 ` [PATCH 04/37] powerpc/iseries: cleanup and fix secondary startup Milton Miller
                   ` (34 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:28 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt

Starting with 1426d5a3bd07589534286375998c0c8c6fdc5260 (powerpc:
Dynamically allocate pacas) the space for pacas beyond cpu_possible
is freed, but we failed to update the loop in crash.c.

Since c1854e00727f50f7ac99e98d26ece04c087ef785 (powerpc: Set nr_cpu_ids
early and use it to free PACAs) the number of pacas allocated is
always nr_cpu_ids.

Signed-off-by: Milton Miller <miltonm@bga.com>
Cc: <stable@kernel.org> # .34.x
---
This is the simplest fix, and quite sutiable for stable.

We can merge the crash waits with the normal kexec waits later,
and fix the hole described in the other version.
---
 arch/powerpc/kernel/crash.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c
index 21f2c78..4e6ee94 100644
--- a/arch/powerpc/kernel/crash.c
+++ b/arch/powerpc/kernel/crash.c
@@ -236,7 +236,7 @@ static void crash_kexec_wait_realmode(int cpu)
 	int i;
 
 	msecs = 10000;
-	for (i=0; i < NR_CPUS && msecs > 0; i++) {
+	for (i=0; i < nr_cpu_ids && msecs > 0; i++) {
 		if (i == cpu)
 			continue;
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 04/37] powerpc/iseries: cleanup and fix secondary startup
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (2 preceding siblings ...)
  2011-05-11  5:28 ` [PATCH 03/37] powerpc/kdump64: Don't reference freed memory as pacas Milton Miller
@ 2011-05-11  5:28 ` Milton Miller
  2011-05-11  5:28 ` [PATCH 05/37] powerpc: Respect nr_cpu_ids when calling set_cpu_possible and set_cpu_present Milton Miller
                   ` (33 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:28 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt; +Cc: Stephen Rothwell

9cb82f2f4692293a27c578c3038518ce4477de72 (Make iSeries spin on
__secondary_hold_spinloop, like pSeries) added a load of current_set
but this load was repeated later and we don't even have the paca yet.
It also checked __secondary_hold_spinloop with a 32 bit compare instead
of a 64 bit compare.

b6f6b98a4e91fcf31db7de54c3aa86252fc6fb5f (Don't spin on sync instruction
at boot time) missed the copy of the startup code in iseries.

1426d5a3bd07589534286375998c0c8c6fdc5260 (Dynamically allocate pacas)
doesn't allow for pacas to be less than lppacas and recalculated the paca
location from the cpu id in r0 every time through the secondary loop.

Various revisions over time made the comments on conditional branches
confusing with respect to being a hold loop or forward progress

Mostly in-order description of the changes:

Replicate the few lines of code saved by the ugly scoped ifdef CONFIG_SMP
in the secondary loop between yielding on UP and marking time with the
hypervisor on SMP.  Always compile the iseries_secondary_yield loop and
use it if the cpu id is above nr_cpu_ids.  Change all forward progress
paths to be forward branches to the next numerical label.  Assign a
label to all loops.  Move all sync instructions from the loops to the
forward progress path.  Wait to load current_set until paca is set to go.
Move the iseries_secondary_smp_loop label to cover the whole spin loop.
Add HMT_MEDIUM when we make forward progress.

Signed-off-by: Milton Miller <miltonm@bga.com>
---
commpile tested only
---
 arch/powerpc/platforms/iseries/exception.S |   59 ++++++++++++++++-----------
 1 files changed, 35 insertions(+), 24 deletions(-)

diff --git a/arch/powerpc/platforms/iseries/exception.S b/arch/powerpc/platforms/iseries/exception.S
index a67984c..29c02f3 100644
--- a/arch/powerpc/platforms/iseries/exception.S
+++ b/arch/powerpc/platforms/iseries/exception.S
@@ -61,29 +61,31 @@ system_reset_iSeries:
 /* Spin on __secondary_hold_spinloop until it is updated by the boot cpu. */
 /* In the UP case we'll yield() later, and we will not access the paca anyway */
 #ifdef CONFIG_SMP
-1:
+iSeries_secondary_wait_paca:
 	HMT_LOW
 	LOAD_REG_ADDR(r23, __secondary_hold_spinloop)
 	ld	r23,0(r23)
-	sync
-	LOAD_REG_ADDR(r3,current_set)
-	sldi	r28,r24,3		/* get current_set[cpu#] */
-	ldx	r3,r3,r28
-	addi	r1,r3,THREAD_SIZE
-	subi	r1,r1,STACK_FRAME_OVERHEAD
 
-	cmpwi	0,r23,0			/* Keep poking the Hypervisor until */
-	bne	2f			/* we're released */
-	/* Let the Hypervisor know we are alive */
+	cmpdi	0,r23,0
+	bne	2f			/* go on when the master is ready */
+
+	/* Keep poking the Hypervisor until we're released */
 	/* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */
 	lis	r3,0x8002
 	rldicr	r3,r3,32,15		/* r0 = (r3 << 32) & 0xffff000000000000 */
 	li	r0,-1			/* r0=-1 indicates a Hypervisor call */
 	sc				/* Invoke the hypervisor via a system call */
-	b	1b
-#endif
+	b	iSeries_secondary_wait_paca
 
 2:
+	HMT_MEDIUM
+	sync
+
+	LOAD_REG_ADDR(r3, nr_cpu_ids)	/* get number of pacas allocated */
+	lwz	r3,0(r3)		/* nr_cpus= or NR_CPUS can limit */
+	cmpld	0,r24,r3		/* is our cpu number allocated? */
+	bge	iSeries_secondary_yield	/* no, yield forever */
+
 	/* Load our paca now that it's been allocated */
 	LOAD_REG_ADDR(r13, paca)
 	ld	r13,0(r13)
@@ -94,10 +96,24 @@ system_reset_iSeries:
 	ori	r23,r23,MSR_RI
 	mtmsrd	r23			/* RI on */
 
-	HMT_LOW
-#ifdef CONFIG_SMP
+iSeries_secondary_smp_loop:
 	lbz	r23,PACAPROCSTART(r13)	/* Test if this processor
 					 * should start */
+	cmpwi	0,r23,0
+	bne	3f			/* go on when we are told */
+
+	HMT_LOW
+	/* Let the Hypervisor know we are alive */
+	/* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */
+	lis	r3,0x8002
+	rldicr	r3,r3,32,15		/* r0 = (r3 << 32) & 0xffff000000000000 */
+	li	r0,-1			/* r0=-1 indicates a Hypervisor call */
+	sc				/* Invoke the hypervisor via a system call */
+	mfspr	r13,SPRN_SPRG_PACA	/* Put r13 back ???? */
+	b	iSeries_secondary_smp_loop /* wait for signal to start */
+
+3:
+	HMT_MEDIUM
 	sync
 	LOAD_REG_ADDR(r3,current_set)
 	sldi	r28,r24,3		/* get current_set[cpu#] */
@@ -105,27 +121,22 @@ system_reset_iSeries:
 	addi	r1,r3,THREAD_SIZE
 	subi	r1,r1,STACK_FRAME_OVERHEAD
 
-	cmpwi	0,r23,0
-	beq	iSeries_secondary_smp_loop	/* Loop until told to go */
 	b	__secondary_start		/* Loop until told to go */
-iSeries_secondary_smp_loop:
-	/* Let the Hypervisor know we are alive */
-	/* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */
-	lis	r3,0x8002
-	rldicr	r3,r3,32,15		/* r0 = (r3 << 32) & 0xffff000000000000 */
-#else /* CONFIG_SMP */
+#endif /* CONFIG_SMP */
+
+iSeries_secondary_yield:
 	/* Yield the processor.  This is required for non-SMP kernels
 		which are running on multi-threaded machines. */
+	HMT_LOW
 	lis	r3,0x8000
 	rldicr	r3,r3,32,15		/* r3 = (r3 << 32) & 0xffff000000000000 */
 	addi	r3,r3,18		/* r3 = 0x8000000000000012 which is "yield" */
 	li	r4,0			/* "yield timed" */
 	li	r5,-1			/* "yield forever" */
-#endif /* CONFIG_SMP */
 	li	r0,-1			/* r0=-1 indicates a Hypervisor call */
 	sc				/* Invoke the hypervisor via a system call */
 	mfspr	r13,SPRN_SPRG_PACA	/* Put r13 back ???? */
-	b	2b			/* If SMP not configured, secondaries
+	b	iSeries_secondary_yield	/* If SMP not configured, secondaries
 					 * loop forever */
 
 /***  ISeries-LPAR interrupt handlers ***/
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 05/37] powerpc: Respect nr_cpu_ids when calling set_cpu_possible and set_cpu_present
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (3 preceding siblings ...)
  2011-05-11  5:28 ` [PATCH 04/37] powerpc/iseries: cleanup and fix secondary startup Milton Miller
@ 2011-05-11  5:28 ` Milton Miller
  2011-05-11  5:28 ` [PATCH 06/37] powerpc: use nr_cpu_ids in initial paca allocation Milton Miller
                   ` (32 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:28 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt

We should not set cpus above nr_cpu_ids to possible.  While we
will trigger a warning with CONFIG_CPUMASK_DEBUG, even then the mask
initializers will set the bits beyond what the iterators check and cause
nr_cpu_ids to increase.

Respecting nr_cpu_ids during setup will allow us to use it in our initial
paca allocation.  It can be reduced from NR_CPUS by the existing early param
nr_cpus=, which was added in 2b633e3fac5efada088b57d31e65401f22bcc18f (smp:
Use nr_cpus= to set nr_cpu_ids early).  We already call parse_early_parms
between finding the command line and allocating the pacas.

Signed-off-by: Milton Miller <miltonm@bga.com>

---

Probably-not-worth-Cc: stable (2.6.34 and up)
---
 arch/powerpc/kernel/setup-common.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 1475df6..fce759b 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -404,7 +404,7 @@ static void __init cpu_init_thread_core_maps(int tpc)
  *                  cpu_present_mask
  *
  * Having the possible map set up early allows us to restrict allocations
- * of things like irqstacks to num_possible_cpus() rather than NR_CPUS.
+ * of things like irqstacks to nr_cpu_ids rather than NR_CPUS.
  *
  * We do not initialize the online map here; cpus set their own bits in
  * cpu_online_mask as they come up.
@@ -424,7 +424,7 @@ void __init smp_setup_cpu_maps(void)
 
 	DBG("smp_setup_cpu_maps()\n");
 
-	while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) {
+	while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < nr_cpu_ids) {
 		const int *intserv;
 		int j, len;
 
@@ -443,7 +443,7 @@ void __init smp_setup_cpu_maps(void)
 				intserv = &cpu;	/* assume logical == phys */
 		}
 
-		for (j = 0; j < nthreads && cpu < NR_CPUS; j++) {
+		for (j = 0; j < nthreads && cpu < nr_cpu_ids; j++) {
 			DBG("    thread %d -> cpu %d (hard id %d)\n",
 			    j, cpu, intserv[j]);
 			set_cpu_present(cpu, true);
@@ -483,12 +483,12 @@ void __init smp_setup_cpu_maps(void)
 		if (cpu_has_feature(CPU_FTR_SMT))
 			maxcpus *= nthreads;
 
-		if (maxcpus > NR_CPUS) {
+		if (maxcpus > nr_cpu_ids) {
 			printk(KERN_WARNING
 			       "Partition configured for %d cpus, "
 			       "operating system maximum is %d.\n",
-			       maxcpus, NR_CPUS);
-			maxcpus = NR_CPUS;
+			       maxcpus, nr_cpu_ids);
+			maxcpus = nr_cpu_ids;
 		} else
 			printk(KERN_INFO "Partition configured for %d cpus.\n",
 			       maxcpus);
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 06/37] powerpc: use nr_cpu_ids in initial paca allocation
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (4 preceding siblings ...)
  2011-05-11  5:28 ` [PATCH 05/37] powerpc: Respect nr_cpu_ids when calling set_cpu_possible and set_cpu_present Milton Miller
@ 2011-05-11  5:28 ` Milton Miller
  2011-05-11  5:28 ` [PATCH 07/37] powerpc: call no-longer static setup_nr_cpu_ids instead of replicating it Milton Miller
                   ` (31 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:28 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt

Now that we never set a cpu above nr_cpu_ids possible we can
limit our initial paca allocation to nr_cpu_ids.  We can then
clamp the number of cpus in platforms/iseries/setup.c.

Signed-off-by: Milton Miller <miltonm@bga.com>
---
---
 arch/powerpc/kernel/paca.c             |   17 ++++++-----------
 arch/powerpc/platforms/iseries/setup.c |    5 +++++
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index 102244e..efeb881 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -7,7 +7,7 @@
  *      2 of the License, or (at your option) any later version.
  */
 
-#include <linux/threads.h>
+#include <linux/smp.h>
 #include <linux/module.h>
 #include <linux/memblock.h>
 
@@ -178,7 +178,7 @@ static int __initdata paca_size;
 
 void __init allocate_pacas(void)
 {
-	int nr_cpus, cpu, limit;
+	int cpu, limit;
 
 	/*
 	 * We can't take SLB misses on the paca, and we want to access them
@@ -190,23 +190,18 @@ void __init allocate_pacas(void)
 	if (firmware_has_feature(FW_FEATURE_ISERIES))
 		limit = min(limit, HvPagesToMap * HVPAGESIZE);
 
-	nr_cpus = NR_CPUS;
-	/* On iSeries we know we can never have more than 64 cpus */
-	if (firmware_has_feature(FW_FEATURE_ISERIES))
-		nr_cpus = min(64, nr_cpus);
-
-	paca_size = PAGE_ALIGN(sizeof(struct paca_struct) * nr_cpus);
+	paca_size = PAGE_ALIGN(sizeof(struct paca_struct) * nr_cpu_ids);
 
 	paca = __va(memblock_alloc_base(paca_size, PAGE_SIZE, limit));
 	memset(paca, 0, paca_size);
 
 	printk(KERN_DEBUG "Allocated %u bytes for %d pacas at %p\n",
-		paca_size, nr_cpus, paca);
+		paca_size, nr_cpu_ids, paca);
 
-	allocate_lppacas(nr_cpus, limit);
+	allocate_lppacas(nr_cpu_ids, limit);
 
 	/* Can't use for_each_*_cpu, as they aren't functional yet */
-	for (cpu = 0; cpu < nr_cpus; cpu++)
+	for (cpu = 0; cpu < nr_cpu_ids; cpu++)
 		initialise_paca(&paca[cpu], cpu);
 }
 
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index 81cb8d2..c25a081 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -685,6 +685,11 @@ void * __init iSeries_early_setup(void)
 	powerpc_firmware_features |= FW_FEATURE_ISERIES;
 	powerpc_firmware_features |= FW_FEATURE_LPAR;
 
+#ifdef CONFIG_SMP
+	/* On iSeries we know we can never have more than 64 cpus */
+	nr_cpu_ids = max(nr_cpu_ids, 64);
+#endif
+
 	iSeries_fixup_klimit();
 
 	/*
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 07/37] powerpc: call no-longer static setup_nr_cpu_ids instead of replicating it
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (5 preceding siblings ...)
  2011-05-11  5:28 ` [PATCH 06/37] powerpc: use nr_cpu_ids in initial paca allocation Milton Miller
@ 2011-05-11  5:28 ` Milton Miller
  2011-05-11  5:28 ` [PATCH 08/37] powerpc: mpic: limit NR_CPUS loop to 32 bit Milton Miller
                   ` (30 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:28 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt

c1854e00727f50f7ac99e98d26ece04c087ef785 (powerpc: Set nr_cpu_ids early
and use it to free PACAs) copied the formerly static setup_nr_cpu_ids
from init/main.c but 34db18a054c600b6f81787165669dc572fe4de25 (smp:
move smp setup functions to kernel/smp.c) moved it to kernel/smp.c
with a declaration in include/linux/smp.h, so we can call it instead of
replicating it.

Signed-off-by: Milton Miller <miltonm@bga.com>
---
I found this cleanup while c1854e was being merged, but saved it from the
end to ease backporting.
---
 arch/powerpc/kernel/setup-common.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index fce759b..ef33a08 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -510,7 +510,7 @@ void __init smp_setup_cpu_maps(void)
 	cpu_init_thread_core_maps(nthreads);
 
 	/* Now that possible cpus are set, set nr_cpu_ids for later use */
-	nr_cpu_ids = find_last_bit(cpumask_bits(cpu_possible_mask),NR_CPUS) + 1;
+	setup_nr_cpu_ids();
 
 	free_unused_pacas();
 }
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 08/37] powerpc: mpic: limit NR_CPUS loop to 32 bit
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (6 preceding siblings ...)
  2011-05-11  5:28 ` [PATCH 07/37] powerpc: call no-longer static setup_nr_cpu_ids instead of replicating it Milton Miller
@ 2011-05-11  5:28 ` Milton Miller
  2011-05-11  5:29 ` [PATCH 09/37] powerpc: mpic: break cpumask abstraction earlier Milton Miller
                   ` (29 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:28 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt

mpic_physmask was looping NR_CPUS times over a mask that was passed as
a u32. Since mpic is architecturaly limited to 32 physical cpus, clamp
the logical cpus to 32 when compiling (we could also clamp at runtime
to nr_cpu_ids).

Signed-off-by: Milton Miller <miltonm@bga.com>
---
 arch/powerpc/sysdev/mpic.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 824a94f..a93da80 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -631,7 +631,7 @@ static inline u32 mpic_physmask(u32 cpumask)
 	int i;
 	u32 mask = 0;
 
-	for (i = 0; i < NR_CPUS; ++i, cpumask >>= 1)
+	for (i = 0; i < min(32, NR_CPUS); ++i, cpumask >>= 1)
 		mask |= (cpumask & 1) << get_hard_smp_processor_id(i);
 	return mask;
 }
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 09/37] powerpc: mpic: break cpumask abstraction earlier
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (7 preceding siblings ...)
  2011-05-11  5:28 ` [PATCH 08/37] powerpc: mpic: limit NR_CPUS loop to 32 bit Milton Miller
@ 2011-05-11  5:29 ` Milton Miller
  2011-05-11  5:29 ` [PATCH 10/37] powerpc: remove call sites of MSG_ALL_BUT_SELF Milton Miller
                   ` (28 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:29 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt

mpic_set_affinity is allocating and freeing a cpumask var even though
it was breaking the cpumask abstraction when passing the mask to
mpic_physmask.  It also didn't have any check for allocatin failure.

Break the cpumask abstraction earlier and use simple bitwise and of the
bits from the mask with the bits of cpu_online_mask.

Signed-off-by: Milton Miller <miltonm@bga.com>
---
 arch/powerpc/sysdev/mpic.c |   10 +++-------
 1 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index a93da80..116695b 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -821,16 +821,12 @@ int mpic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
 
 		mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION), 1 << cpuid);
 	} else {
-		cpumask_var_t tmp;
+		u32 mask = cpumask_bits(cpumask)[0];
 
-		alloc_cpumask_var(&tmp, GFP_KERNEL);
-
-		cpumask_and(tmp, cpumask, cpu_online_mask);
+		mask &= cpumask_bits(cpu_online_mask)[0];
 
 		mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION),
-			       mpic_physmask(cpumask_bits(tmp)[0]));
-
-		free_cpumask_var(tmp);
+			       mpic_physmask(mask));
 	}
 
 	return 0;
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 10/37] powerpc: remove call sites of MSG_ALL_BUT_SELF
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (8 preceding siblings ...)
  2011-05-11  5:29 ` [PATCH 09/37] powerpc: mpic: break cpumask abstraction earlier Milton Miller
@ 2011-05-11  5:29 ` Milton Miller
  2011-05-11  5:29 ` [PATCH 11/37] powerpc: remove checks for MSG_ALL and MSG_ALL_BUT_SELF Milton Miller
                   ` (27 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:29 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt

The only user of MSG_ALL_BUT_SELF in the whole kernel tree is powerpc,
and it only uses it to start the debugger. Both debuggers always call
smp_send_debugger_break with MSG_ALL_BUT_SELF, and only mpic can do
anything more optimal than a loop over all online cpus, but all message
passing implementations have to code for this special delivery target.

Convert smp_send_debugger_break to take void and loop calling the smp_ops
message_pass function for each of the other cpus in the online cpumask.

Use raw_smp_processor_id() because we are either entering the debugger
or trying to start kdump and the additional warning it not useful were
it to trigger.

Signed-off-by: Milton Miller <miltonm@bga.com>
---
 arch/powerpc/include/asm/smp.h |    2 +-
 arch/powerpc/kernel/kgdb.c     |    2 +-
 arch/powerpc/kernel/smp.c      |   19 +++++++++++++------
 arch/powerpc/xmon/xmon.c       |    2 +-
 4 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index 5087349..91472c5 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -35,7 +35,7 @@ extern void cpu_die(void);
 
 #ifdef CONFIG_SMP
 
-extern void smp_send_debugger_break(int cpu);
+extern void smp_send_debugger_break(void);
 extern void smp_message_recv(int);
 extern void start_secondary_resume(void);
 
diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c
index 42850ee..bd9d35f 100644
--- a/arch/powerpc/kernel/kgdb.c
+++ b/arch/powerpc/kernel/kgdb.c
@@ -109,7 +109,7 @@ static int kgdb_call_nmi_hook(struct pt_regs *regs)
 #ifdef CONFIG_SMP
 void kgdb_roundup_cpus(unsigned long flags)
 {
-	smp_send_debugger_break(MSG_ALL_BUT_SELF);
+	smp_send_debugger_break();
 }
 #endif
 
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 87517ab..b744114 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -218,11 +218,18 @@ void arch_send_call_function_ipi_mask(const struct cpumask *mask)
 		smp_ops->message_pass(cpu, PPC_MSG_CALL_FUNCTION);
 }
 
-#ifdef CONFIG_DEBUGGER
-void smp_send_debugger_break(int cpu)
+#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
+void smp_send_debugger_break(void)
 {
-	if (likely(smp_ops))
-		smp_ops->message_pass(cpu, PPC_MSG_DEBUGGER_BREAK);
+	int cpu;
+	int me = raw_smp_processor_id();
+
+	if (unlikely(!smp_ops))
+		return;
+
+	for_each_online_cpu(cpu)
+		if (cpu != me)
+			smp_ops->message_pass(cpu, PPC_MSG_DEBUGGER_BREAK);
 }
 #endif
 
@@ -230,9 +237,9 @@ void smp_send_debugger_break(int cpu)
 void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *))
 {
 	crash_ipi_function_ptr = crash_ipi_callback;
-	if (crash_ipi_callback && smp_ops) {
+	if (crash_ipi_callback) {
 		mb();
-		smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_DEBUGGER_BREAK);
+		smp_send_debugger_break();
 	}
 }
 #endif
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 91309c5..42541bb 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -437,7 +437,7 @@ static int xmon_core(struct pt_regs *regs, int fromipi)
 		xmon_owner = cpu;
 		mb();
 		if (ncpus > 1) {
-			smp_send_debugger_break(MSG_ALL_BUT_SELF);
+			smp_send_debugger_break();
 			/* wait for other cpus to come in */
 			for (timeout = 100000000; timeout != 0; --timeout) {
 				if (cpumask_weight(&cpus_in_xmon) >= ncpus)
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 11/37] powerpc: remove checks for MSG_ALL and MSG_ALL_BUT_SELF
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (9 preceding siblings ...)
  2011-05-11  5:29 ` [PATCH 10/37] powerpc: remove call sites of MSG_ALL_BUT_SELF Milton Miller
@ 2011-05-11  5:29 ` Milton Miller
  2011-05-11  5:29 ` [PATCH 12/37] linux/smp.h: remove unused MSG_ flags Milton Miller
                   ` (26 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:29 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt

Now that smp_ops->smp_message_pass is always called with an (online) cpu
number for the target remove the checks for MSG_ALL and MSG_ALL_BUT_SELF.

Signed-off-by: Milton Miller <miltonm@bga.com>
---
rediffed for ppc-next xics split
---
 arch/powerpc/include/asm/dbell.h       |    2 +-
 arch/powerpc/include/asm/machdep.h     |    2 +-
 arch/powerpc/include/asm/xics.h        |    2 +-
 arch/powerpc/kernel/dbell.c            |   29 +++++------------------------
 arch/powerpc/platforms/cell/beat_smp.c |   18 +-----------------
 arch/powerpc/platforms/cell/smp.c      |   18 +-----------------
 arch/powerpc/platforms/iseries/smp.c   |   18 +-----------------
 arch/powerpc/platforms/powermac/smp.c  |   17 +++--------------
 arch/powerpc/platforms/ps3/smp.c       |   22 +++-------------------
 arch/powerpc/sysdev/mpic.c             |   20 ++------------------
 arch/powerpc/sysdev/xics/icp-hv.c      |   18 +-----------------
 arch/powerpc/sysdev/xics/icp-native.c  |   18 +-----------------
 12 files changed, 21 insertions(+), 163 deletions(-)

diff --git a/arch/powerpc/include/asm/dbell.h b/arch/powerpc/include/asm/dbell.h
index 0893ab9..3269eb4 100644
--- a/arch/powerpc/include/asm/dbell.h
+++ b/arch/powerpc/include/asm/dbell.h
@@ -27,7 +27,7 @@ enum ppc_dbell {
 	PPC_G_DBELL_MC = 4,	/* guest mcheck doorbell */
 };
 
-extern void doorbell_message_pass(int target, int msg);
+extern void doorbell_message_pass(int cpu, int msg);
 extern void doorbell_exception(struct pt_regs *regs);
 extern void doorbell_check_self(void);
 extern void doorbell_setup_this_cpu(void);
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index c6345ac..b0802a5 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -31,7 +31,7 @@ struct kimage;
 
 #ifdef CONFIG_SMP
 struct smp_ops_t {
-	void  (*message_pass)(int target, int msg);
+	void  (*message_pass)(int cpu, int msg);
 	int   (*probe)(void);
 	int   (*kick_cpu)(int nr);
 	void  (*setup_cpu)(int nr);
diff --git a/arch/powerpc/include/asm/xics.h b/arch/powerpc/include/asm/xics.h
index 6c06306..1750c8d 100644
--- a/arch/powerpc/include/asm/xics.h
+++ b/arch/powerpc/include/asm/xics.h
@@ -40,7 +40,7 @@ struct icp_ops {
 	void (*teardown_cpu)(void);
 	void (*flush_ipi)(void);
 #ifdef CONFIG_SMP
-	void (*message_pass)(int target, int msg);
+	void (*message_pass)(int cpu, int msg);
 	irq_handler_t ipi_action;
 #endif
 };
diff --git a/arch/powerpc/kernel/dbell.c b/arch/powerpc/kernel/dbell.c
index 3307a52..e49b24c 100644
--- a/arch/powerpc/kernel/dbell.c
+++ b/arch/powerpc/kernel/dbell.c
@@ -34,32 +34,13 @@ void doorbell_setup_this_cpu(void)
 	info->tag = mfspr(SPRN_PIR) & 0x3fff;
 }
 
-void doorbell_message_pass(int target, int msg)
+void doorbell_message_pass(int cpu, int msg)
 {
 	struct doorbell_cpu_info *info;
-	int i;
-
-	if (target < NR_CPUS) {
-		info = &per_cpu(doorbell_cpu_info, target);
-		set_bit(msg, &info->messages);
-		ppc_msgsnd(PPC_DBELL, 0, info->tag);
-	}
-	else if (target == MSG_ALL_BUT_SELF) {
-		for_each_online_cpu(i) {
-			if (i == smp_processor_id())
-				continue;
-			info = &per_cpu(doorbell_cpu_info, i);
-			set_bit(msg, &info->messages);
-			ppc_msgsnd(PPC_DBELL, 0, info->tag);
-		}
-	}
-	else { /* target == MSG_ALL */
-		for_each_online_cpu(i) {
-			info = &per_cpu(doorbell_cpu_info, i);
-			set_bit(msg, &info->messages);
-		}
-		ppc_msgsnd(PPC_DBELL, PPC_DBELL_MSG_BRDCAST, 0);
-	}
+
+	info = &per_cpu(doorbell_cpu_info, cpu);
+	set_bit(msg, &info->messages);
+	ppc_msgsnd(PPC_DBELL, 0, info->tag);
 }
 
 void doorbell_exception(struct pt_regs *regs)
diff --git a/arch/powerpc/platforms/cell/beat_smp.c b/arch/powerpc/platforms/cell/beat_smp.c
index 3e86acb..23bbe6e 100644
--- a/arch/powerpc/platforms/cell/beat_smp.c
+++ b/arch/powerpc/platforms/cell/beat_smp.c
@@ -67,22 +67,6 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu)
 	return 0;
 }
 
-static void smp_beatic_message_pass(int target, int msg)
-{
-	unsigned int i;
-
-	if (target < NR_CPUS) {
-		beatic_cause_IPI(target, msg);
-	} else {
-		for_each_online_cpu(i) {
-			if (target == MSG_ALL_BUT_SELF
-			    && i == smp_processor_id())
-				continue;
-			beatic_cause_IPI(i, msg);
-		}
-	}
-}
-
 static int __init smp_beatic_probe(void)
 {
 	return cpumask_weight(cpu_possible_mask);
@@ -105,7 +89,7 @@ static int smp_celleb_cpu_bootable(unsigned int nr)
 	return 1;
 }
 static struct smp_ops_t bpa_beatic_smp_ops = {
-	.message_pass	= smp_beatic_message_pass,
+	.message_pass	= beatic_cause_IPI,
 	.probe		= smp_beatic_probe,
 	.kick_cpu	= smp_celleb_kick_cpu,
 	.setup_cpu	= smp_beatic_setup_cpu,
diff --git a/arch/powerpc/platforms/cell/smp.c b/arch/powerpc/platforms/cell/smp.c
index a2161b9..d176e61 100644
--- a/arch/powerpc/platforms/cell/smp.c
+++ b/arch/powerpc/platforms/cell/smp.c
@@ -103,22 +103,6 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu)
 	return 1;
 }
 
-static void smp_iic_message_pass(int target, int msg)
-{
-	unsigned int i;
-
-	if (target < NR_CPUS) {
-		iic_cause_IPI(target, msg);
-	} else {
-		for_each_online_cpu(i) {
-			if (target == MSG_ALL_BUT_SELF
-			    && i == smp_processor_id())
-				continue;
-			iic_cause_IPI(i, msg);
-		}
-	}
-}
-
 static int __init smp_iic_probe(void)
 {
 	iic_request_IPIs();
@@ -168,7 +152,7 @@ static int smp_cell_cpu_bootable(unsigned int nr)
 	return 1;
 }
 static struct smp_ops_t bpa_iic_smp_ops = {
-	.message_pass	= smp_iic_message_pass,
+	.message_pass	= iic_cause_IPI,
 	.probe		= smp_iic_probe,
 	.kick_cpu	= smp_cell_kick_cpu,
 	.setup_cpu	= smp_cell_setup_cpu,
diff --git a/arch/powerpc/platforms/iseries/smp.c b/arch/powerpc/platforms/iseries/smp.c
index 02a677a..dcdbc5d 100644
--- a/arch/powerpc/platforms/iseries/smp.c
+++ b/arch/powerpc/platforms/iseries/smp.c
@@ -59,28 +59,12 @@ void iSeries_smp_message_recv(void)
 			smp_message_recv(msg);
 }
 
-static inline void smp_iSeries_do_message(int cpu, int msg)
+static void smp_iSeries_message_pass(int cpu, int msg)
 {
 	set_bit(msg, &iSeries_smp_message[cpu]);
 	HvCall_sendIPI(&(paca[cpu]));
 }
 
-static void smp_iSeries_message_pass(int target, int msg)
-{
-	int i;
-
-	if (target < NR_CPUS)
-		smp_iSeries_do_message(target, msg);
-	else {
-		for_each_online_cpu(i) {
-			if ((target == MSG_ALL_BUT_SELF) &&
-					(i == smp_processor_id()))
-				continue;
-			smp_iSeries_do_message(i, msg);
-		}
-	}
-}
-
 static int smp_iSeries_probe(void)
 {
 	return cpumask_weight(cpu_possible_mask);
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 621d4b7..c49e719 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -186,21 +186,10 @@ irqreturn_t psurge_primary_intr(int irq, void *d)
 	return IRQ_HANDLED;
 }
 
-static void smp_psurge_message_pass(int target, int msg)
+static void smp_psurge_message_pass(int cpu, int msg)
 {
-	int i;
-
-	if (num_online_cpus() < 2)
-		return;
-
-	for_each_online_cpu(i) {
-		if (target == MSG_ALL
-		    || (target == MSG_ALL_BUT_SELF && i != smp_processor_id())
-		    || target == i) {
-			set_bit(msg, &psurge_smp_message[i]);
-			psurge_set_ipi(i);
-		}
-	}
+	set_bit(msg, &psurge_smp_message[cpu]);
+	psurge_set_ipi(cpu);
 }
 
 /*
diff --git a/arch/powerpc/platforms/ps3/smp.c b/arch/powerpc/platforms/ps3/smp.c
index 51ffde4..4c44794 100644
--- a/arch/powerpc/platforms/ps3/smp.c
+++ b/arch/powerpc/platforms/ps3/smp.c
@@ -39,7 +39,7 @@
 #define MSG_COUNT 4
 static DEFINE_PER_CPU(unsigned int [MSG_COUNT], ps3_ipi_virqs);
 
-static void do_message_pass(int target, int msg)
+static void ps3_smp_message_pass(int cpu, int msg)
 {
 	int result;
 	unsigned int virq;
@@ -49,28 +49,12 @@ static void do_message_pass(int target, int msg)
 		return;
 	}
 
-	virq = per_cpu(ps3_ipi_virqs, target)[msg];
+	virq = per_cpu(ps3_ipi_virqs, cpu)[msg];
 	result = ps3_send_event_locally(virq);
 
 	if (result)
 		DBG("%s:%d: ps3_send_event_locally(%d, %d) failed"
-			" (%d)\n", __func__, __LINE__, target, msg, result);
-}
-
-static void ps3_smp_message_pass(int target, int msg)
-{
-	int cpu;
-
-	if (target < NR_CPUS)
-		do_message_pass(target, msg);
-	else if (target == MSG_ALL_BUT_SELF) {
-		for_each_online_cpu(cpu)
-			if (cpu != smp_processor_id())
-				do_message_pass(cpu, msg);
-	} else {
-		for_each_online_cpu(cpu)
-			do_message_pass(cpu, msg);
-	}
+			" (%d)\n", __func__, __LINE__, cpu, msg, result);
 }
 
 static int ps3_smp_probe(void)
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 116695b..68ea50c 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -1628,31 +1628,15 @@ static void mpic_send_ipi(unsigned int ipi_no, const struct cpumask *cpu_mask)
 		       mpic_physmask(cpumask_bits(cpu_mask)[0]));
 }
 
-void smp_mpic_message_pass(int target, int msg)
+void smp_mpic_message_pass(int cpu, int msg)
 {
-	cpumask_var_t tmp;
-
 	/* make sure we're sending something that translates to an IPI */
 	if ((unsigned int)msg > 3) {
 		printk("SMP %d: smp_message_pass: unknown msg %d\n",
 		       smp_processor_id(), msg);
 		return;
 	}
-	switch (target) {
-	case MSG_ALL:
-		mpic_send_ipi(msg, cpu_online_mask);
-		break;
-	case MSG_ALL_BUT_SELF:
-		alloc_cpumask_var(&tmp, GFP_NOWAIT);
-		cpumask_andnot(tmp, cpu_online_mask,
-			       cpumask_of(smp_processor_id()));
-		mpic_send_ipi(msg, tmp);
-		free_cpumask_var(tmp);
-		break;
-	default:
-		mpic_send_ipi(msg, cpumask_of(target));
-		break;
-	}
+	mpic_send_ipi(msg, cpumask_of(cpu));
 }
 
 int __init smp_mpic_probe(void)
diff --git a/arch/powerpc/sysdev/xics/icp-hv.c b/arch/powerpc/sysdev/xics/icp-hv.c
index 76e8724..234764c 100644
--- a/arch/powerpc/sysdev/xics/icp-hv.c
+++ b/arch/powerpc/sysdev/xics/icp-hv.c
@@ -118,7 +118,7 @@ static void icp_hv_set_cpu_priority(unsigned char cppr)
 
 #ifdef CONFIG_SMP
 
-static inline void icp_hv_do_message(int cpu, int msg)
+static void icp_hv_message_pass(int cpu, int msg)
 {
 	unsigned long *tgt = &per_cpu(xics_ipi_message, cpu);
 
@@ -127,22 +127,6 @@ static inline void icp_hv_do_message(int cpu, int msg)
 	icp_hv_set_qirr(cpu, IPI_PRIORITY);
 }
 
-static void icp_hv_message_pass(int target, int msg)
-{
-	unsigned int i;
-
-	if (target < NR_CPUS) {
-		icp_hv_do_message(target, msg);
-	} else {
-		for_each_online_cpu(i) {
-			if (target == MSG_ALL_BUT_SELF
-			    && i == smp_processor_id())
-				continue;
-			icp_hv_do_message(i, msg);
-		}
-	}
-}
-
 static irqreturn_t icp_hv_ipi_action(int irq, void *dev_id)
 {
 	int cpu = smp_processor_id();
diff --git a/arch/powerpc/sysdev/xics/icp-native.c b/arch/powerpc/sysdev/xics/icp-native.c
index 3508321..246500e 100644
--- a/arch/powerpc/sysdev/xics/icp-native.c
+++ b/arch/powerpc/sysdev/xics/icp-native.c
@@ -134,7 +134,7 @@ static unsigned int icp_native_get_irq(void)
 
 #ifdef CONFIG_SMP
 
-static inline void icp_native_do_message(int cpu, int msg)
+static void icp_native_message_pass(int cpu, int msg)
 {
 	unsigned long *tgt = &per_cpu(xics_ipi_message, cpu);
 
@@ -143,22 +143,6 @@ static inline void icp_native_do_message(int cpu, int msg)
 	icp_native_set_qirr(cpu, IPI_PRIORITY);
 }
 
-static void icp_native_message_pass(int target, int msg)
-{
-	unsigned int i;
-
-	if (target < NR_CPUS) {
-		icp_native_do_message(target, msg);
-	} else {
-		for_each_online_cpu(i) {
-			if (target == MSG_ALL_BUT_SELF
-			    && i == smp_processor_id())
-				continue;
-			icp_native_do_message(i, msg);
-		}
-	}
-}
-
 static irqreturn_t icp_native_ipi_action(int irq, void *dev_id)
 {
 	int cpu = smp_processor_id();
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 12/37] linux/smp.h: remove unused MSG_ flags
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (10 preceding siblings ...)
  2011-05-11  5:29 ` [PATCH 11/37] powerpc: remove checks for MSG_ALL and MSG_ALL_BUT_SELF Milton Miller
@ 2011-05-11  5:29 ` Milton Miller
  2011-05-11  5:29 ` [PATCH 13/37] powerpc/mpic: simplify ipi cpu mask handling Milton Miller
                   ` (25 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:29 UTC (permalink / raw)
  To: linuxppc-dev, linux-kernel, Benjamin Herrenschmidt

Now that powerpc has removed its use of MSG_ALL_BUT_SELF and MSG_ALL
all these MSG_ flags are unused.

Signed-off-by: Milton Miller <miltonm@bga.com>
---
To be merged by powerpc with the series posted to linuxppc-dev

After the previous 2 patches, grep shows the following false hits (from
partial symbol matches):

find . -name .git -prune -o -name .pc -prune -o -name patches -prune -o -type f|
 xargs grep -E 'MSG_(ALL|RESCHEDULE|CALL_FUNCTION|INVALIDATE_TLB|STOP_CPU)'

	XFRM_MSG_ALLOCSPI (include/linux/xfrm.h, net/xfrm/xfrm_user.c)
	CHANNELMSG_ALLOFFERS_DELIVERED (drivers/staging/hv/)
	PPC_MSG_CALL_FUNCTION, PPC_MSG_RESCHEDULE (arch/powerpc/)
	SMP_MSG_RESCHEDULE (arch/sh/)
---
 include/linux/smp.h |   10 ----------
 1 files changed, 0 insertions(+), 10 deletions(-)

diff --git a/include/linux/smp.h b/include/linux/smp.h
index 74243c8..7ad824d 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -98,16 +98,6 @@ void ipi_call_unlock_irq(void);
  */
 int on_each_cpu(smp_call_func_t func, void *info, int wait);
 
-#define MSG_ALL_BUT_SELF	0x8000	/* Assume <32768 CPU's */
-#define MSG_ALL			0x8001
-
-#define MSG_INVALIDATE_TLB	0x0001	/* Remote processor TLB invalidate */
-#define MSG_STOP_CPU		0x0002	/* Sent to shut down slave CPU's
-					 * when rebooting
-					 */
-#define MSG_RESCHEDULE		0x0003	/* Reschedule request from master CPU*/
-#define MSG_CALL_FUNCTION       0x0004  /* Call function on all other CPUs */
-
 /*
  * Mark the boot cpu "online" so that it can call console drivers in
  * printk() and can access its per-cpu storage.
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 13/37] powerpc/mpic: simplify ipi cpu mask handling
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (11 preceding siblings ...)
  2011-05-11  5:29 ` [PATCH 12/37] linux/smp.h: remove unused MSG_ flags Milton Miller
@ 2011-05-11  5:29 ` Milton Miller
  2011-05-11  5:29 ` [PATCH 14/37] powerpc: remove powermac/pic.h Milton Miller
                   ` (24 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:29 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt

Now that MSG_ALL and MSG_ALL_BUT_SELF have been eliminated,
smp_mpic_mesage_pass no longer needs to lookup the cpumask just to
have mpic_send_ipi extract part of it and recode it in a NR_CPUS loop
by mpic_physmask.

Signed-off-by: Milton Miller <miltonm@bga.com>
---
I chose stepwise refinement but this could be merged into the ALL_BUT_SELF
removal patch.
---
 arch/powerpc/sysdev/mpic.c |   24 +++++++++++-------------
 1 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 68ea50c..53121f6 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -1613,30 +1613,28 @@ void mpic_request_ipis(void)
 	}
 }
 
-static void mpic_send_ipi(unsigned int ipi_no, const struct cpumask *cpu_mask)
+void smp_mpic_message_pass(int cpu, int msg)
 {
 	struct mpic *mpic = mpic_primary;
+	u32 physmask;
 
 	BUG_ON(mpic == NULL);
 
-#ifdef DEBUG_IPI
-	DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, ipi_no);
-#endif
-
-	mpic_cpu_write(MPIC_INFO(CPU_IPI_DISPATCH_0) +
-		       ipi_no * MPIC_INFO(CPU_IPI_DISPATCH_STRIDE),
-		       mpic_physmask(cpumask_bits(cpu_mask)[0]));
-}
-
-void smp_mpic_message_pass(int cpu, int msg)
-{
 	/* make sure we're sending something that translates to an IPI */
 	if ((unsigned int)msg > 3) {
 		printk("SMP %d: smp_message_pass: unknown msg %d\n",
 		       smp_processor_id(), msg);
 		return;
 	}
-	mpic_send_ipi(msg, cpumask_of(cpu));
+
+#ifdef DEBUG_IPI
+	DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, msg);
+#endif
+
+	physmask = 1 << get_hard_smp_processor_id(cpu);
+
+	mpic_cpu_write(MPIC_INFO(CPU_IPI_DISPATCH_0) +
+		       msg * MPIC_INFO(CPU_IPI_DISPATCH_STRIDE), physmask);
 }
 
 int __init smp_mpic_probe(void)
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 14/37] powerpc: remove powermac/pic.h
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (12 preceding siblings ...)
  2011-05-11  5:29 ` [PATCH 13/37] powerpc/mpic: simplify ipi cpu mask handling Milton Miller
@ 2011-05-11  5:29 ` Milton Miller
  2011-05-11  5:29 ` [PATCH 15/37] powerpc: remove alloc_maybe_bootmem for zalloc version Milton Miller
                   ` (23 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:29 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt

Its unused, and of the three declarations, one is duplicated in pmac.h,
the second is static and the third is renamed and static.

Signed-off-by: Milton Miller <miltonm@bga.com>
---
---
 arch/powerpc/platforms/powermac/pic.h |   11 -----------
 1 files changed, 0 insertions(+), 11 deletions(-)
 delete mode 100644 arch/powerpc/platforms/powermac/pic.h

diff --git a/arch/powerpc/platforms/powermac/pic.h b/arch/powerpc/platforms/powermac/pic.h
deleted file mode 100644
index d622a83..0000000
--- a/arch/powerpc/platforms/powermac/pic.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef __PPC_PLATFORMS_PMAC_PIC_H
-#define __PPC_PLATFORMS_PMAC_PIC_H
-
-#include <linux/irq.h>
-
-extern struct irq_chip pmac_pic;
-
-extern void pmac_pic_init(void);
-extern int pmac_get_irq(void);
-
-#endif /* __PPC_PLATFORMS_PMAC_PIC_H */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 15/37] powerpc: remove alloc_maybe_bootmem for zalloc version
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (13 preceding siblings ...)
  2011-05-11  5:29 ` [PATCH 14/37] powerpc: remove powermac/pic.h Milton Miller
@ 2011-05-11  5:29 ` Milton Miller
  2011-05-11  5:29 ` [PATCH 16/37] powerpc: remove stubbed beat smp support Milton Miller
                   ` (22 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:29 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt

Replace all remaining callers of alloc_maybe_bootmem with
zalloc_maybe_bootmem.   The callsite in pci_dn is followed with a
memset to clear the memory, and not zeroing at the other callsites
in the celleb fake pci code could lead to following uninitialized
memory as pointers or even freeing said pointers on error paths.

Signed-off-by: Milton Miller <miltonm@bga.com>
---
 arch/powerpc/include/asm/system.h        |    2 --
 arch/powerpc/kernel/pci_dn.c             |    3 +--
 arch/powerpc/lib/alloc.c                 |    8 --------
 arch/powerpc/platforms/cell/celleb_pci.c |    6 +++---
 4 files changed, 4 insertions(+), 15 deletions(-)

diff --git a/arch/powerpc/include/asm/system.h b/arch/powerpc/include/asm/system.h
index 5e474dd..2dc595d 100644
--- a/arch/powerpc/include/asm/system.h
+++ b/arch/powerpc/include/asm/system.h
@@ -219,8 +219,6 @@ extern int mem_init_done;	/* set on boot once kmalloc can be called */
 extern int init_bootmem_done;	/* set once bootmem is available */
 extern phys_addr_t memory_limit;
 extern unsigned long klimit;
-
-extern void *alloc_maybe_bootmem(size_t size, gfp_t mask);
 extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask);
 
 extern int powersave_nap;	/* set if nap mode can be used in idle loop */
diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c
index d225d99..6baabc1 100644
--- a/arch/powerpc/kernel/pci_dn.c
+++ b/arch/powerpc/kernel/pci_dn.c
@@ -43,10 +43,9 @@ void * __devinit update_dn_pci_info(struct device_node *dn, void *data)
 	const u32 *regs;
 	struct pci_dn *pdn;
 
-	pdn = alloc_maybe_bootmem(sizeof(*pdn), GFP_KERNEL);
+	pdn = zalloc_maybe_bootmem(sizeof(*pdn), GFP_KERNEL);
 	if (pdn == NULL)
 		return NULL;
-	memset(pdn, 0, sizeof(*pdn));
 	dn->data = pdn;
 	pdn->node = dn;
 	pdn->phb = phb;
diff --git a/arch/powerpc/lib/alloc.c b/arch/powerpc/lib/alloc.c
index f53e09c..13b676c 100644
--- a/arch/powerpc/lib/alloc.c
+++ b/arch/powerpc/lib/alloc.c
@@ -6,14 +6,6 @@
 
 #include <asm/system.h>
 
-void * __init_refok alloc_maybe_bootmem(size_t size, gfp_t mask)
-{
-	if (mem_init_done)
-		return kmalloc(size, mask);
-	else
-		return alloc_bootmem(size);
-}
-
 void * __init_refok zalloc_maybe_bootmem(size_t size, gfp_t mask)
 {
 	void *p;
diff --git a/arch/powerpc/platforms/cell/celleb_pci.c b/arch/powerpc/platforms/cell/celleb_pci.c
index 2904b0a..5822141 100644
--- a/arch/powerpc/platforms/cell/celleb_pci.c
+++ b/arch/powerpc/platforms/cell/celleb_pci.c
@@ -319,7 +319,7 @@ static int __init celleb_setup_fake_pci_device(struct device_node *node,
 
 	size = 256;
 	config = &private->fake_config[devno][fn];
-	*config = alloc_maybe_bootmem(size, GFP_KERNEL);
+	*config = zalloc_maybe_bootmem(size, GFP_KERNEL);
 	if (*config == NULL) {
 		printk(KERN_ERR "PCI: "
 		       "not enough memory for fake configuration space\n");
@@ -330,7 +330,7 @@ static int __init celleb_setup_fake_pci_device(struct device_node *node,
 
 	size = sizeof(struct celleb_pci_resource);
 	res = &private->res[devno][fn];
-	*res = alloc_maybe_bootmem(size, GFP_KERNEL);
+	*res = zalloc_maybe_bootmem(size, GFP_KERNEL);
 	if (*res == NULL) {
 		printk(KERN_ERR
 		       "PCI: not enough memory for resource data space\n");
@@ -431,7 +431,7 @@ static int __init phb_set_bus_ranges(struct device_node *dev,
 static void __init celleb_alloc_private_mem(struct pci_controller *hose)
 {
 	hose->private_data =
-		alloc_maybe_bootmem(sizeof(struct celleb_pci_private),
+		zalloc_maybe_bootmem(sizeof(struct celleb_pci_private),
 			GFP_KERNEL);
 }
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 16/37] powerpc: remove stubbed beat smp support
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (14 preceding siblings ...)
  2011-05-11  5:29 ` [PATCH 15/37] powerpc: remove alloc_maybe_bootmem for zalloc version Milton Miller
@ 2011-05-11  5:29 ` Milton Miller
  2011-05-11  5:29 ` [PATCH 17/37] powerpc cell: use smp_request_message_ipi Milton Miller
                   ` (21 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:29 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt

I have no idea if the beat hypervisor supports multiple cpus in
a partition, but the code has not been touched since these stubs
were added in February of 2007 except to move them in April of 2008.
These are stubs: start_cpu always returns fail (which is dropped),
the message passing and reciving are empty functions, and the top
of file comment says "Incomplete".

Signed-off-by: Milton Miller <miltonm@bga.com>
---
 arch/powerpc/platforms/cell/Makefile         |    1 -
 arch/powerpc/platforms/cell/beat_interrupt.c |   16 ----
 arch/powerpc/platforms/cell/beat_interrupt.h |    3 -
 arch/powerpc/platforms/cell/beat_smp.c       |  107 --------------------------
 arch/powerpc/platforms/cell/celleb_setup.c   |    4 -
 5 files changed, 0 insertions(+), 131 deletions(-)
 delete mode 100644 arch/powerpc/platforms/cell/beat_smp.c

diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile
index 8839ef6..a4a8935 100644
--- a/arch/powerpc/platforms/cell/Makefile
+++ b/arch/powerpc/platforms/cell/Makefile
@@ -43,7 +43,6 @@ obj-y					+= celleb_setup.o \
 					   beat_hvCall.o beat_interrupt.o \
 					   beat_iommu.o
 
-obj-$(CONFIG_SMP)			+= beat_smp.o
 obj-$(CONFIG_PPC_UDBG_BEAT)		+= beat_udbg.o
 obj-$(CONFIG_SERIAL_TXX9)		+= celleb_scc_sio.o
 obj-$(CONFIG_SPU_BASE)			+= beat_spu_priv1.o
diff --git a/arch/powerpc/platforms/cell/beat_interrupt.c b/arch/powerpc/platforms/cell/beat_interrupt.c
index 4cb9e14..d46f7e4 100644
--- a/arch/powerpc/platforms/cell/beat_interrupt.c
+++ b/arch/powerpc/platforms/cell/beat_interrupt.c
@@ -257,22 +257,6 @@ void __init beatic_init_IRQ(void)
 	irq_set_default_host(beatic_host);
 }
 
-#ifdef CONFIG_SMP
-
-/* Nullified to compile with SMP mode */
-void beatic_setup_cpu(int cpu)
-{
-}
-
-void beatic_cause_IPI(int cpu, int mesg)
-{
-}
-
-void beatic_request_IPIs(void)
-{
-}
-#endif /* CONFIG_SMP */
-
 void beatic_deinit_IRQ(void)
 {
 	int	i;
diff --git a/arch/powerpc/platforms/cell/beat_interrupt.h b/arch/powerpc/platforms/cell/beat_interrupt.h
index b470fd0..a7e52f9 100644
--- a/arch/powerpc/platforms/cell/beat_interrupt.h
+++ b/arch/powerpc/platforms/cell/beat_interrupt.h
@@ -24,9 +24,6 @@
 
 extern void beatic_init_IRQ(void);
 extern unsigned int beatic_get_irq(void);
-extern void beatic_cause_IPI(int cpu, int mesg);
-extern void beatic_request_IPIs(void);
-extern void beatic_setup_cpu(int);
 extern void beatic_deinit_IRQ(void);
 
 #endif
diff --git a/arch/powerpc/platforms/cell/beat_smp.c b/arch/powerpc/platforms/cell/beat_smp.c
deleted file mode 100644
index 23bbe6e..0000000
--- a/arch/powerpc/platforms/cell/beat_smp.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * SMP support for Celleb platform. (Incomplete)
- *
- * (C) Copyright 2006 TOSHIBA CORPORATION
- *
- * This code is based on arch/powerpc/platforms/cell/smp.c:
- * Dave Engebretsen, Peter Bergner, and
- * Mike Corrigan {engebret|bergner|mikec}@us.ibm.com
- * Plus various changes from other IBM teams...
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#undef DEBUG
-
-#include <linux/kernel.h>
-#include <linux/smp.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/threads.h>
-#include <linux/cpu.h>
-
-#include <asm/irq.h>
-#include <asm/smp.h>
-#include <asm/machdep.h>
-#include <asm/udbg.h>
-
-#include "beat_interrupt.h"
-
-#ifdef DEBUG
-#define DBG(fmt...) udbg_printf(fmt)
-#else
-#define DBG(fmt...)
-#endif
-
-/*
- * The primary thread of each non-boot processor is recorded here before
- * smp init.
- */
-/* static cpumask_t of_spin_map; */
-
-/**
- * smp_startup_cpu() - start the given cpu
- *
- * At boot time, there is nothing to do for primary threads which were
- * started from Open Firmware.  For anything else, call RTAS with the
- * appropriate start location.
- *
- * Returns:
- *	0	- failure
- *	1	- success
- */
-static inline int __devinit smp_startup_cpu(unsigned int lcpu)
-{
-	return 0;
-}
-
-static int __init smp_beatic_probe(void)
-{
-	return cpumask_weight(cpu_possible_mask);
-}
-
-static void __devinit smp_beatic_setup_cpu(int cpu)
-{
-	beatic_setup_cpu(cpu);
-}
-
-static int __devinit smp_celleb_kick_cpu(int nr)
-{
-	BUG_ON(nr < 0 || nr >= NR_CPUS);
-
-	return smp_startup_cpu(nr);
-}
-
-static int smp_celleb_cpu_bootable(unsigned int nr)
-{
-	return 1;
-}
-static struct smp_ops_t bpa_beatic_smp_ops = {
-	.message_pass	= beatic_cause_IPI,
-	.probe		= smp_beatic_probe,
-	.kick_cpu	= smp_celleb_kick_cpu,
-	.setup_cpu	= smp_beatic_setup_cpu,
-	.cpu_bootable	= smp_celleb_cpu_bootable,
-};
-
-/* This is called very early */
-void __init smp_init_celleb(void)
-{
-	DBG(" -> smp_init_celleb()\n");
-
-	smp_ops = &bpa_beatic_smp_ops;
-
-	DBG(" <- smp_init_celleb()\n");
-}
diff --git a/arch/powerpc/platforms/cell/celleb_setup.c b/arch/powerpc/platforms/cell/celleb_setup.c
index e538455..d58d9ba 100644
--- a/arch/powerpc/platforms/cell/celleb_setup.c
+++ b/arch/powerpc/platforms/cell/celleb_setup.c
@@ -128,10 +128,6 @@ static void __init celleb_setup_arch_beat(void)
 	spu_management_ops	= &spu_management_of_ops;
 #endif
 
-#ifdef CONFIG_SMP
-	smp_init_celleb();
-#endif
-
 	celleb_setup_arch_common();
 }
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 17/37]  powerpc cell: use smp_request_message_ipi
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (15 preceding siblings ...)
  2011-05-11  5:29 ` [PATCH 16/37] powerpc: remove stubbed beat smp support Milton Miller
@ 2011-05-11  5:29 ` Milton Miller
  2011-05-11  5:29 ` [PATCH 18/37] powerpc: move smp_ops_t from machdep.h to smp.h Milton Miller
                   ` (20 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:29 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt

This is a request to merge patchwork id 3780 with the same subject.
I believe it was marked "changes requested" because it depended on a
patch that had requested changes, but those were resolved and this
one got overlooked.  The next patch will remove smp_msg_recv.

thanks,
milton

Here is the original change log:

Subject: [PATCH 15/16]  powerpc cell: use smp_request_message_ipi

cell native has 4 interrupts for ipis, so use the new smp_request_message_ipi
to save pathlength and the data-dependent branch.

This has the side effects of enabling the debugger ipi for kdump and
setting IRQF_PERCPU for the ipi interrupts.  It doesn't undo the virq
mapping if it turns out the ipi is not used.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* [PATCH 18/37] powerpc: move smp_ops_t from machdep.h to smp.h
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (16 preceding siblings ...)
  2011-05-11  5:29 ` [PATCH 17/37] powerpc cell: use smp_request_message_ipi Milton Miller
@ 2011-05-11  5:29 ` Milton Miller
  2011-05-11  5:29 ` [PATCH 19/37] powerpc: consolidate ipi message mux and demux Milton Miller
                   ` (19 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:29 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt

I can't see any reason these functions are needed by machdep.h
and they are all hidden by CONFIG_SMP with no UP alternative.

Also move the declarations for the fallback timebase ops, which
are used to fill in the smp ops.

Signed-off-by: Milton Miller <miltonm@bga.com>
---
 arch/powerpc/include/asm/machdep.h |   21 ---------------------
 arch/powerpc/include/asm/smp.h     |   15 +++++++++++++++
 2 files changed, 15 insertions(+), 21 deletions(-)

diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index b0802a5..47cacdd 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -29,21 +29,6 @@ struct file;
 struct pci_controller;
 struct kimage;
 
-#ifdef CONFIG_SMP
-struct smp_ops_t {
-	void  (*message_pass)(int cpu, int msg);
-	int   (*probe)(void);
-	int   (*kick_cpu)(int nr);
-	void  (*setup_cpu)(int nr);
-	void  (*bringup_done)(void);
-	void  (*take_timebase)(void);
-	void  (*give_timebase)(void);
-	int   (*cpu_disable)(void);
-	void  (*cpu_die)(unsigned int nr);
-	int   (*cpu_bootable)(unsigned int nr);
-};
-#endif
-
 struct machdep_calls {
 	char		*name;
 #ifdef CONFIG_PPC64
@@ -312,12 +297,6 @@ extern sys_ctrler_t sys_ctrler;
 
 #endif /* CONFIG_PPC_PMAC */
 
-#ifdef CONFIG_SMP
-/* Poor default implementations */
-extern void __devinit smp_generic_give_timebase(void);
-extern void __devinit smp_generic_take_timebase(void);
-#endif /* CONFIG_SMP */
-
 
 /* Functions to produce codes on the leds.
  * The SRC code should be unique for the message category and should
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index 91472c5..6f7c95c 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -35,9 +35,24 @@ extern void cpu_die(void);
 
 #ifdef CONFIG_SMP
 
+struct smp_ops_t {
+	void  (*message_pass)(int cpu, int msg);
+	int   (*probe)(void);
+	int   (*kick_cpu)(int nr);
+	void  (*setup_cpu)(int nr);
+	void  (*bringup_done)(void);
+	void  (*take_timebase)(void);
+	void  (*give_timebase)(void);
+	int   (*cpu_disable)(void);
+	void  (*cpu_die)(unsigned int nr);
+	int   (*cpu_bootable)(unsigned int nr);
+};
+
 extern void smp_send_debugger_break(void);
 extern void smp_message_recv(int);
 extern void start_secondary_resume(void);
+extern void __devinit smp_generic_give_timebase(void);
+extern void __devinit smp_generic_take_timebase(void);
 
 DECLARE_PER_CPU(unsigned int, cpu_pvr);
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 19/37] powerpc: consolidate ipi message mux and demux
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (17 preceding siblings ...)
  2011-05-11  5:29 ` [PATCH 18/37] powerpc: move smp_ops_t from machdep.h to smp.h Milton Miller
@ 2011-05-11  5:29 ` Milton Miller
  2011-05-19  6:57   ` Benjamin Herrenschmidt
  2011-05-11  5:29 ` [PATCH 20/37] powerpc: add kconfig for muxed smp ipi support Milton Miller
                   ` (18 subsequent siblings)
  37 siblings, 1 reply; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:29 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt

Consolidate the mux and demux of ipi messages into smp.c and call
a new smp_ops callback to actually trigger the ipi.

The powerpc architecture code is optimised for having 4 distinct
ipi triggers, which are mapped to 4 distinct messages (ipi many, ipi
single, scheduler ipi, and enter debugger).  However, several interrupt
controllers only provide a single software triggered interrupt that
can be delivered to each cpu.  To resolve this limitation, each smp_ops
implementation created a per-cpu variable that is manipulated with atomic
bitops.  Since these lines will be contended they are optimialy marked as
shared_aligned and take a full cache line for each cpu.  Distro kernels
may have 2 or 3 of these in their config, each taking per-cpu space
even though at most one will be in use.

This consolidation removes smp_message_recv and replaces the single call
actions cases with direct calls from the common message recognition loop.
The complicated debugger ipi case with its muxed crash handling code is
moved to debug_ipi_action which is now called from the demux code (instead
of the multi-message action calling smp_message_recv).

I put a call to reschedule_action to increase the likelyhood of correctly
merging the anticipated scheduler_ipi() hook coming from the scheduler
tree; that single required call can be inlined later.

The actual message decode is a copy of the old pseries xics code with its
memory barriers and cache line spacing, augmented with a per-cpu unsigned
long based on the book-e doorbell code.  The optional data is set via a
callback from the implementation and is passed to the new cause-ipi hook
along with the logical cpu number.  While currently only the doorbell
implemntation uses this data it should be almost zero cost to retrieve and
pass it -- it adds a single register load for the argument from the same
cache line to which we just completed a store and the register is dead
on return from the call.  I extended the data element from unsigned int
to unsigned long in case some other code wanted to associate a pointer.

The doorbell check_self is replaced by a call to smp_muxed_ipi_resend,
conditioned on the CPU_DBELL feature.  The ifdef guard could be relaxed
to CONFIG_SMP but I left it with BOOKE for now.

Also, the doorbell interrupt vector for book-e was not calling irq_enter
and irq_exit, which throws off cpu accounting and causes code to not
realize it is running in interrupt context.  Add the missing calls.

Signed-off-by: Milton Miller <miltonm@bga.com>
---

This requires patch 3780 be applied first for cell to compile.
---
 arch/powerpc/include/asm/dbell.h       |    3 +-
 arch/powerpc/include/asm/smp.h         |   14 +++--
 arch/powerpc/include/asm/xics.h        |    2 +-
 arch/powerpc/kernel/dbell.c            |   46 +++-------------
 arch/powerpc/kernel/irq.c              |    4 +-
 arch/powerpc/kernel/smp.c              |   92 +++++++++++++++++++++----------
 arch/powerpc/platforms/85xx/smp.c      |    6 ++-
 arch/powerpc/platforms/iseries/irq.c   |    3 +-
 arch/powerpc/platforms/iseries/smp.c   |   23 +-------
 arch/powerpc/platforms/iseries/smp.h   |    6 --
 arch/powerpc/platforms/powermac/smp.c  |   27 ++-------
 arch/powerpc/platforms/pseries/smp.c   |    3 +-
 arch/powerpc/sysdev/xics/icp-hv.c      |   10 +---
 arch/powerpc/sysdev/xics/icp-native.c  |   10 +---
 arch/powerpc/sysdev/xics/xics-common.c |   30 +----------
 15 files changed, 107 insertions(+), 172 deletions(-)
 delete mode 100644 arch/powerpc/platforms/iseries/smp.h

diff --git a/arch/powerpc/include/asm/dbell.h b/arch/powerpc/include/asm/dbell.h
index 3269eb4..9c70d0c 100644
--- a/arch/powerpc/include/asm/dbell.h
+++ b/arch/powerpc/include/asm/dbell.h
@@ -27,9 +27,8 @@ enum ppc_dbell {
 	PPC_G_DBELL_MC = 4,	/* guest mcheck doorbell */
 };
 
-extern void doorbell_message_pass(int cpu, int msg);
+extern void doorbell_cause_ipi(int cpu, unsigned long data);
 extern void doorbell_exception(struct pt_regs *regs);
-extern void doorbell_check_self(void);
 extern void doorbell_setup_this_cpu(void);
 
 static inline void ppc_msgsnd(enum ppc_dbell type, u32 flags, u32 tag)
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index 6f7c95c..9ae64bf 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -20,6 +20,7 @@
 #include <linux/threads.h>
 #include <linux/cpumask.h>
 #include <linux/kernel.h>
+#include <linux/irqreturn.h>
 
 #ifndef __ASSEMBLY__
 
@@ -37,6 +38,7 @@ extern void cpu_die(void);
 
 struct smp_ops_t {
 	void  (*message_pass)(int cpu, int msg);
+	void  (*cause_ipi)(int cpu, unsigned long data);
 	int   (*probe)(void);
 	int   (*kick_cpu)(int nr);
 	void  (*setup_cpu)(int nr);
@@ -49,7 +51,6 @@ struct smp_ops_t {
 };
 
 extern void smp_send_debugger_break(void);
-extern void smp_message_recv(int);
 extern void start_secondary_resume(void);
 extern void __devinit smp_generic_give_timebase(void);
 extern void __devinit smp_generic_take_timebase(void);
@@ -109,13 +110,16 @@ extern int cpu_to_core_id(int cpu);
 #define PPC_MSG_CALL_FUNC_SINGLE	2
 #define PPC_MSG_DEBUGGER_BREAK  3
 
-/*
- * irq controllers that have dedicated ipis per message and don't
- * need additional code in the action handler may use this
- */
+/* for irq controllers that have dedicated ipis per message (4) */
 extern int smp_request_message_ipi(int virq, int message);
 extern const char *smp_ipi_name[];
 
+/* for irq controllers with only a single ipi */
+extern void smp_muxed_ipi_set_data(int cpu, unsigned long data);
+extern void smp_muxed_ipi_message_pass(int cpu, int msg);
+extern void smp_muxed_ipi_resend(void);
+extern irqreturn_t smp_ipi_demux(void);
+
 void smp_init_iSeries(void);
 void smp_init_pSeries(void);
 void smp_init_cell(void);
diff --git a/arch/powerpc/include/asm/xics.h b/arch/powerpc/include/asm/xics.h
index 1750c8d..b183a40 100644
--- a/arch/powerpc/include/asm/xics.h
+++ b/arch/powerpc/include/asm/xics.h
@@ -40,7 +40,7 @@ struct icp_ops {
 	void (*teardown_cpu)(void);
 	void (*flush_ipi)(void);
 #ifdef CONFIG_SMP
-	void (*message_pass)(int cpu, int msg);
+	void (*cause_ipi)(int cpu, unsigned long data);
 	irq_handler_t ipi_action;
 #endif
 };
diff --git a/arch/powerpc/kernel/dbell.c b/arch/powerpc/kernel/dbell.c
index e49b24c..2cc451a 100644
--- a/arch/powerpc/kernel/dbell.c
+++ b/arch/powerpc/kernel/dbell.c
@@ -13,65 +13,35 @@
 #include <linux/kernel.h>
 #include <linux/smp.h>
 #include <linux/threads.h>
-#include <linux/percpu.h>
+#include <linux/hardirq.h>
 
 #include <asm/dbell.h>
 #include <asm/irq_regs.h>
 
 #ifdef CONFIG_SMP
-struct doorbell_cpu_info {
-	unsigned long	messages;	/* current messages bits */
-	unsigned int	tag;		/* tag value */
-};
-
-static DEFINE_PER_CPU(struct doorbell_cpu_info, doorbell_cpu_info);
-
 void doorbell_setup_this_cpu(void)
 {
-	struct doorbell_cpu_info *info = &__get_cpu_var(doorbell_cpu_info);
+	unsigned long tag = mfspr(SPRN_PIR) & 0x3fff;
 
-	info->messages = 0;
-	info->tag = mfspr(SPRN_PIR) & 0x3fff;
+	smp_muxed_ipi_set_data(smp_processor_id(), tag);
 }
 
-void doorbell_message_pass(int cpu, int msg)
+void doorbell_cause_ipi(int cpu, unsigned long data)
 {
-	struct doorbell_cpu_info *info;
-
-	info = &per_cpu(doorbell_cpu_info, cpu);
-	set_bit(msg, &info->messages);
-	ppc_msgsnd(PPC_DBELL, 0, info->tag);
+	ppc_msgsnd(PPC_DBELL, 0, data);
 }
 
 void doorbell_exception(struct pt_regs *regs)
 {
 	struct pt_regs *old_regs = set_irq_regs(regs);
-	struct doorbell_cpu_info *info = &__get_cpu_var(doorbell_cpu_info);
-	int msg;
 
-	/* Warning: regs can be NULL when called from irq enable */
+	irq_enter();
 
-	if (!info->messages || (num_online_cpus() < 2))
-		goto out;
+	smp_ipi_demux();
 
-	for (msg = 0; msg < 4; msg++)
-		if (test_and_clear_bit(msg, &info->messages))
-			smp_message_recv(msg);
-
-out:
+	irq_exit();
 	set_irq_regs(old_regs);
 }
-
-void doorbell_check_self(void)
-{
-	struct doorbell_cpu_info *info = &__get_cpu_var(doorbell_cpu_info);
-
-	if (!info->messages)
-		return;
-
-	ppc_msgsnd(PPC_DBELL, 0, info->tag);
-}
-
 #else /* CONFIG_SMP */
 void doorbell_exception(struct pt_regs *regs)
 {
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index a81dd74..826552c 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -66,7 +66,6 @@
 #include <asm/ptrace.h>
 #include <asm/machdep.h>
 #include <asm/udbg.h>
-#include <asm/dbell.h>
 #include <asm/smp.h>
 
 #ifdef CONFIG_PPC64
@@ -160,7 +159,8 @@ notrace void arch_local_irq_restore(unsigned long en)
 
 #if defined(CONFIG_BOOKE) && defined(CONFIG_SMP)
 	/* Check for pending doorbell interrupts and resend to ourself */
-	doorbell_check_self();
+	if (cpu_has_feature(CPU_FTR_DBELL))
+		smp_muxed_ipi_resend();
 #endif
 
 	/*
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index b744114..72717e1 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -111,35 +111,6 @@ int __devinit smp_generic_kick_cpu(int nr)
 }
 #endif
 
-void smp_message_recv(int msg)
-{
-	switch(msg) {
-	case PPC_MSG_CALL_FUNCTION:
-		generic_smp_call_function_interrupt();
-		break;
-	case PPC_MSG_RESCHEDULE:
-		/* we notice need_resched on exit */
-		break;
-	case PPC_MSG_CALL_FUNC_SINGLE:
-		generic_smp_call_function_single_interrupt();
-		break;
-	case PPC_MSG_DEBUGGER_BREAK:
-		if (crash_ipi_function_ptr) {
-			crash_ipi_function_ptr(get_irq_regs());
-			break;
-		}
-#ifdef CONFIG_DEBUGGER
-		debugger_ipi(get_irq_regs());
-		break;
-#endif /* CONFIG_DEBUGGER */
-		/* FALLTHROUGH */
-	default:
-		printk("SMP %d: smp_message_recv(): unknown msg %d\n",
-		       smp_processor_id(), msg);
-		break;
-	}
-}
-
 static irqreturn_t call_function_action(int irq, void *data)
 {
 	generic_smp_call_function_interrupt();
@@ -160,7 +131,15 @@ static irqreturn_t call_function_single_action(int irq, void *data)
 
 static irqreturn_t debug_ipi_action(int irq, void *data)
 {
-	smp_message_recv(PPC_MSG_DEBUGGER_BREAK);
+	if (crash_ipi_function_ptr) {
+		crash_ipi_function_ptr(get_irq_regs());
+		return IRQ_HANDLED;
+	}
+
+#ifdef CONFIG_DEBUGGER
+	debugger_ipi(get_irq_regs());
+#endif /* CONFIG_DEBUGGER */
+
 	return IRQ_HANDLED;
 }
 
@@ -199,6 +178,59 @@ int smp_request_message_ipi(int virq, int msg)
 	return err;
 }
 
+struct cpu_messages {
+	unsigned long messages;		/* current messages bits */
+	unsigned long data;		/* data for cause ipi */
+};
+static DEFINE_PER_CPU_SHARED_ALIGNED(struct cpu_messages, ipi_message);
+
+void smp_muxed_ipi_set_data(int cpu, unsigned long data)
+{
+	struct cpu_messages *info = &per_cpu(ipi_message, cpu);
+
+	info->data = data;
+}
+
+void smp_muxed_ipi_message_pass(int cpu, int msg)
+{
+	struct cpu_messages *info = &per_cpu(ipi_message, cpu);
+	unsigned long *tgt = &info->messages;
+
+	set_bit(msg, tgt);
+	mb();
+	smp_ops->cause_ipi(cpu, info->data);
+}
+
+void smp_muxed_ipi_resend(void)
+{
+	struct cpu_messages *info = &__get_cpu_var(ipi_message);
+	unsigned long *tgt = &info->messages;
+
+	if (*tgt)
+		smp_ops->cause_ipi(smp_processor_id(), info->data);
+}
+
+irqreturn_t smp_ipi_demux(void)
+{
+	struct cpu_messages *info = &__get_cpu_var(ipi_message);
+	unsigned long *tgt = &info->messages;
+
+	mb();	/* order any irq clear */
+	while (*tgt) {
+		if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION, tgt))
+			generic_smp_call_function_interrupt();
+		if (test_and_clear_bit(PPC_MSG_RESCHEDULE, tgt))
+			reschedule_action(0, NULL); /* upcoming sched hook */
+		if (test_and_clear_bit(PPC_MSG_CALL_FUNC_SINGLE, tgt))
+			generic_smp_call_function_single_interrupt();
+#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
+		if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK, tgt))
+			debug_ipi_action(0, NULL);
+#endif
+	}
+	return IRQ_HANDLED;
+}
+
 void smp_send_reschedule(int cpu)
 {
 	if (likely(smp_ops))
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
index fe3f6a3..d6a93a1 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -235,8 +235,10 @@ void __init mpc85xx_smp_init(void)
 		smp_85xx_ops.message_pass = smp_mpic_message_pass;
 	}
 
-	if (cpu_has_feature(CPU_FTR_DBELL))
-		smp_85xx_ops.message_pass = doorbell_message_pass;
+	if (cpu_has_feature(CPU_FTR_DBELL)) {
+		smp_85xx_ops.message_pass = smp_muxed_ipi_message_pass;
+		smp_85xx_ops.cause_ipi = doorbell_cause_ipi;
+	}
 
 	BUG_ON(!smp_85xx_ops.message_pass);
 
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index 375c21c..b210345 100644
--- a/arch/powerpc/platforms/iseries/irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -42,7 +42,6 @@
 #include "irq.h"
 #include "pci.h"
 #include "call_pci.h"
-#include "smp.h"
 
 #ifdef CONFIG_PCI
 
@@ -316,7 +315,7 @@ unsigned int iSeries_get_irq(void)
 #ifdef CONFIG_SMP
 	if (get_lppaca()->int_dword.fields.ipi_cnt) {
 		get_lppaca()->int_dword.fields.ipi_cnt = 0;
-		iSeries_smp_message_recv();
+		smp_ipi_demux();
 	}
 #endif /* CONFIG_SMP */
 	if (hvlpevent_is_pending())
diff --git a/arch/powerpc/platforms/iseries/smp.c b/arch/powerpc/platforms/iseries/smp.c
index dcdbc5d..e3265ad 100644
--- a/arch/powerpc/platforms/iseries/smp.c
+++ b/arch/powerpc/platforms/iseries/smp.c
@@ -42,26 +42,8 @@
 #include <asm/cputable.h>
 #include <asm/system.h>
 
-#include "smp.h"
-
-static unsigned long iSeries_smp_message[NR_CPUS];
-
-void iSeries_smp_message_recv(void)
-{
-	int cpu = smp_processor_id();
-	int msg;
-
-	if (num_online_cpus() < 2)
-		return;
-
-	for (msg = 0; msg < 4; msg++)
-		if (test_and_clear_bit(msg, &iSeries_smp_message[cpu]))
-			smp_message_recv(msg);
-}
-
-static void smp_iSeries_message_pass(int cpu, int msg)
+static void smp_iSeries_cause_ipi(int cpu, unsigned long data)
 {
-	set_bit(msg, &iSeries_smp_message[cpu]);
 	HvCall_sendIPI(&(paca[cpu]));
 }
 
@@ -93,7 +75,8 @@ static void __devinit smp_iSeries_setup_cpu(int nr)
 }
 
 static struct smp_ops_t iSeries_smp_ops = {
-	.message_pass = smp_iSeries_message_pass,
+	.message_pass = smp_muxed_ipi_message_pass,
+	.cause_ipi    = smp_iSeries_cause_ipi,
 	.probe        = smp_iSeries_probe,
 	.kick_cpu     = smp_iSeries_kick_cpu,
 	.setup_cpu    = smp_iSeries_setup_cpu,
diff --git a/arch/powerpc/platforms/iseries/smp.h b/arch/powerpc/platforms/iseries/smp.h
deleted file mode 100644
index d501f7d..0000000
--- a/arch/powerpc/platforms/iseries/smp.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _PLATFORMS_ISERIES_SMP_H
-#define _PLATFORMS_ISERIES_SMP_H
-
-extern void iSeries_smp_message_recv(void);
-
-#endif	/* _PLATFORMS_ISERIES_SMP_H */
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index c49e719..a340107 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -156,28 +156,13 @@ static inline void psurge_clr_ipi(int cpu)
 /*
  * On powersurge (old SMP powermac architecture) we don't have
  * separate IPIs for separate messages like openpic does.  Instead
- * we have a bitmap for each processor, where a 1 bit means that
- * the corresponding message is pending for that processor.
- * Ideally each cpu's entry would be in a different cache line.
+ * use the generic demux helpers
  *  -- paulus.
  */
-static unsigned long psurge_smp_message[NR_CPUS];
-
 void psurge_smp_message_recv(void)
 {
-	int cpu = smp_processor_id();
-	int msg;
-
-	/* clear interrupt */
-	psurge_clr_ipi(cpu);
-
-	if (num_online_cpus() < 2)
-		return;
-
-	/* make sure there is a message there */
-	for (msg = 0; msg < 4; msg++)
-		if (test_and_clear_bit(msg, &psurge_smp_message[cpu]))
-			smp_message_recv(msg);
+	psurge_clr_ipi(smp_processor_id());
+	smp_ipi_demux();
 }
 
 irqreturn_t psurge_primary_intr(int irq, void *d)
@@ -186,9 +171,8 @@ irqreturn_t psurge_primary_intr(int irq, void *d)
 	return IRQ_HANDLED;
 }
 
-static void smp_psurge_message_pass(int cpu, int msg)
+static void smp_psurge_cause_ipi(int cpu, unsigned long data)
 {
-	set_bit(msg, &psurge_smp_message[cpu]);
 	psurge_set_ipi(cpu);
 }
 
@@ -428,7 +412,8 @@ void __init smp_psurge_give_timebase(void)
 
 /* PowerSurge-style Macs */
 struct smp_ops_t psurge_smp_ops = {
-	.message_pass	= smp_psurge_message_pass,
+	.message_pass	= smp_muxed_ipi_message_pass,
+	.cause_ipi	= smp_psurge_cause_ipi,
 	.probe		= smp_psurge_probe,
 	.kick_cpu	= smp_psurge_kick_cpu,
 	.setup_cpu	= smp_psurge_setup_cpu,
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c
index 95f5781..fbffd7e 100644
--- a/arch/powerpc/platforms/pseries/smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -207,7 +207,8 @@ static struct smp_ops_t pSeries_mpic_smp_ops = {
 };
 
 static struct smp_ops_t pSeries_xics_smp_ops = {
-	.message_pass	= NULL,	/* Filled at runtime by xics_smp_probe() */
+	.message_pass	= smp_muxed_ipi_message_pass,
+	.cause_ipi	= NULL,	/* Filled at runtime by xics_smp_probe() */
 	.probe		= xics_smp_probe,
 	.kick_cpu	= smp_pSeries_kick_cpu,
 	.setup_cpu	= smp_xics_setup_cpu,
diff --git a/arch/powerpc/sysdev/xics/icp-hv.c b/arch/powerpc/sysdev/xics/icp-hv.c
index 234764c..9518d36 100644
--- a/arch/powerpc/sysdev/xics/icp-hv.c
+++ b/arch/powerpc/sysdev/xics/icp-hv.c
@@ -118,12 +118,8 @@ static void icp_hv_set_cpu_priority(unsigned char cppr)
 
 #ifdef CONFIG_SMP
 
-static void icp_hv_message_pass(int cpu, int msg)
+static void icp_hv_cause_ipi(int cpu, unsigned long data)
 {
-	unsigned long *tgt = &per_cpu(xics_ipi_message, cpu);
-
-	set_bit(msg, tgt);
-	mb();
 	icp_hv_set_qirr(cpu, IPI_PRIORITY);
 }
 
@@ -133,7 +129,7 @@ static irqreturn_t icp_hv_ipi_action(int irq, void *dev_id)
 
 	icp_hv_set_qirr(cpu, 0xff);
 
-	return xics_ipi_dispatch(cpu);
+	return smp_ipi_demux();
 }
 
 #endif /* CONFIG_SMP */
@@ -146,7 +142,7 @@ static const struct icp_ops icp_hv_ops = {
 	.flush_ipi	= icp_hv_flush_ipi,
 #ifdef CONFIG_SMP
 	.ipi_action	= icp_hv_ipi_action,
-	.message_pass	= icp_hv_message_pass,
+	.cause_ipi	= icp_hv_cause_ipi,
 #endif
 };
 
diff --git a/arch/powerpc/sysdev/xics/icp-native.c b/arch/powerpc/sysdev/xics/icp-native.c
index 246500e..1f15ad4 100644
--- a/arch/powerpc/sysdev/xics/icp-native.c
+++ b/arch/powerpc/sysdev/xics/icp-native.c
@@ -134,12 +134,8 @@ static unsigned int icp_native_get_irq(void)
 
 #ifdef CONFIG_SMP
 
-static void icp_native_message_pass(int cpu, int msg)
+static void icp_native_cause_ipi(int cpu, unsigned long data)
 {
-	unsigned long *tgt = &per_cpu(xics_ipi_message, cpu);
-
-	set_bit(msg, tgt);
-	mb();
 	icp_native_set_qirr(cpu, IPI_PRIORITY);
 }
 
@@ -149,7 +145,7 @@ static irqreturn_t icp_native_ipi_action(int irq, void *dev_id)
 
 	icp_native_set_qirr(cpu, 0xff);
 
-	return xics_ipi_dispatch(cpu);
+	return smp_ipi_demux();
 }
 
 #endif /* CONFIG_SMP */
@@ -267,7 +263,7 @@ static const struct icp_ops icp_native_ops = {
 	.flush_ipi	= icp_native_flush_ipi,
 #ifdef CONFIG_SMP
 	.ipi_action	= icp_native_ipi_action,
-	.message_pass	= icp_native_message_pass,
+	.cause_ipi	= icp_native_cause_ipi,
 #endif
 };
 
diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c
index a0576b7..a31a710 100644
--- a/arch/powerpc/sysdev/xics/xics-common.c
+++ b/arch/powerpc/sysdev/xics/xics-common.c
@@ -126,32 +126,6 @@ void xics_mask_unknown_vec(unsigned int vec)
 
 #ifdef CONFIG_SMP
 
-DEFINE_PER_CPU_SHARED_ALIGNED(unsigned long, xics_ipi_message);
-
-irqreturn_t xics_ipi_dispatch(int cpu)
-{
-	unsigned long *tgt = &per_cpu(xics_ipi_message, cpu);
-
-	mb();	/* order mmio clearing qirr */
-	while (*tgt) {
-		if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION, tgt)) {
-			smp_message_recv(PPC_MSG_CALL_FUNCTION);
-		}
-		if (test_and_clear_bit(PPC_MSG_RESCHEDULE, tgt)) {
-			smp_message_recv(PPC_MSG_RESCHEDULE);
-		}
-		if (test_and_clear_bit(PPC_MSG_CALL_FUNC_SINGLE, tgt)) {
-			smp_message_recv(PPC_MSG_CALL_FUNC_SINGLE);
-		}
-#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
-		if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK, tgt)) {
-			smp_message_recv(PPC_MSG_DEBUGGER_BREAK);
-		}
-#endif
-	}
-	return IRQ_HANDLED;
-}
-
 static void xics_request_ipi(void)
 {
 	unsigned int ipi;
@@ -170,8 +144,8 @@ static void xics_request_ipi(void)
 
 int __init xics_smp_probe(void)
 {
-	/* Setup message_pass callback  based on which ICP is used */
-	smp_ops->message_pass = icp_ops->message_pass;
+	/* Setup cause_ipi callback  based on which ICP is used */
+	smp_ops->cause_ipi = icp_ops->cause_ipi;
 
 	/* Register all the IPIs */
 	xics_request_ipi();
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 20/37] powerpc: add kconfig for muxed smp ipi support
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (18 preceding siblings ...)
  2011-05-11  5:29 ` [PATCH 19/37] powerpc: consolidate ipi message mux and demux Milton Miller
@ 2011-05-11  5:29 ` Milton Miller
  2011-05-11  5:29 ` [PATCH 21/37] powerpc: use bytes instead of bitops in smp ipi multiplexing Milton Miller
                   ` (17 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:29 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt

Compile the new smp ipi mux and demux code only if a platform
will make use of it.  The new config is selected as required.

The new cause_ipi smp op is only available conditionally to point out
configs where the select is required; this makes setting the op an
immediate fail instead of a deferred unresolved symbol at link.

This also creates a new config for power surge powermac upgrade support
that can be disabled in expert mode but is default on.

I also removed the depends / default y on CONFIG_XICS since it is selected
by PSERIES.

Signed-off-by: Milton Miller <miltonm@bga.com>
---
I kept this seperate mostly because of the addition of the PSURGE kconfig
and to focus the discussion on the seperate concepts but it can be merged
into the previous patch if desireed.
---
 arch/powerpc/include/asm/smp.h          |    2 ++
 arch/powerpc/kernel/smp.c               |    2 ++
 arch/powerpc/platforms/Kconfig          |   11 +++++++++--
 arch/powerpc/platforms/Kconfig.cputype  |    2 ++
 arch/powerpc/platforms/iseries/Kconfig  |    1 +
 arch/powerpc/platforms/powermac/Kconfig |   11 ++++++++++-
 arch/powerpc/platforms/powermac/pic.c   |    4 ++--
 arch/powerpc/platforms/powermac/smp.c   |    8 ++++----
 8 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index 9ae64bf..11eb404 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -38,7 +38,9 @@ extern void cpu_die(void);
 
 struct smp_ops_t {
 	void  (*message_pass)(int cpu, int msg);
+#ifdef CONFIG_PPC_SMP_MUXED_IPI
 	void  (*cause_ipi)(int cpu, unsigned long data);
+#endif
 	int   (*probe)(void);
 	int   (*kick_cpu)(int nr);
 	void  (*setup_cpu)(int nr);
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 72717e1..a28e945 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -178,6 +178,7 @@ int smp_request_message_ipi(int virq, int msg)
 	return err;
 }
 
+#ifdef CONFIG_PPC_SMP_MUXED_IPI
 struct cpu_messages {
 	unsigned long messages;		/* current messages bits */
 	unsigned long data;		/* data for cause ipi */
@@ -230,6 +231,7 @@ irqreturn_t smp_ipi_demux(void)
 	}
 	return IRQ_HANDLED;
 }
+#endif /* CONFIG_PPC_SMP_MUXED_IPI */
 
 void smp_send_reschedule(int cpu)
 {
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index 6059053..ac95735 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -57,15 +57,22 @@ config UDBG_RTAS_CONSOLE
 	depends on PPC_RTAS
 	default n
 
+config PPC_SMP_MUXED_IPI
+	bool
+	help
+	  Select this opton if your platform supports SMP and your
+	  interrupt controller provides less than 4 interrupts to each
+	  cpu.	This will enable the generic code to multiplex the 4
+	  messages on to one ipi.
+
 config PPC_UDBG_BEAT
 	bool "BEAT based debug console"
 	depends on PPC_CELLEB
 	default n
 
 config XICS
-	depends on PPC_PSERIES
 	bool
-	default y
+	select PPC_SMP_MUXED_IPI
 
 config IPIC
 	bool
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index a1e6238..2165b65 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -73,6 +73,7 @@ config PPC_BOOK3S_64
 config PPC_BOOK3E_64
 	bool "Embedded processors"
 	select PPC_FPU # Make it a choice ?
+	select PPC_SMP_MUXED_IPI
 
 endchoice
 
@@ -178,6 +179,7 @@ config FSL_BOOKE
 config PPC_FSL_BOOK3E
 	bool
 	select FSL_EMB_PERFMON
+	select PPC_SMP_MUXED_IPI
 	default y if FSL_BOOKE
 
 config PTE_64BIT
diff --git a/arch/powerpc/platforms/iseries/Kconfig b/arch/powerpc/platforms/iseries/Kconfig
index ea1d362..b57cda3 100644
--- a/arch/powerpc/platforms/iseries/Kconfig
+++ b/arch/powerpc/platforms/iseries/Kconfig
@@ -1,6 +1,7 @@
 config PPC_ISERIES
 	bool "IBM Legacy iSeries"
 	depends on PPC64 && PPC_BOOK3S
+	select PPC_SMP_MUXED_IPI
 	select PPC_INDIRECT_PIO
 	select PPC_INDIRECT_MMIO
 	select PPC_PCI_CHOICE if EXPERT
diff --git a/arch/powerpc/platforms/powermac/Kconfig b/arch/powerpc/platforms/powermac/Kconfig
index 1e1a087..1afd10f 100644
--- a/arch/powerpc/platforms/powermac/Kconfig
+++ b/arch/powerpc/platforms/powermac/Kconfig
@@ -18,4 +18,13 @@ config PPC_PMAC64
 	select PPC_970_NAP
 	default y
 
-
+config PPC_PMAC32_PSURGE
+	bool "Support for powersurge upgrade cards" if EXPERT
+	depends on SMP && PPC32 && PPC_PMAC
+	select PPC_SMP_MUXED_IPI
+	default y
+	help
+	  The powersurge cpu boards can be used in the generation
+	  of powermacs that have a socket for an upgradeable cpu card,
+	  including the 7500, 8500, 9500, 9600.  Support exists for
+	  both dual and quad socket upgrade cards.
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 2f34ad0..b706cb3 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -239,7 +239,7 @@ static unsigned int pmac_pic_get_irq(void)
 	unsigned long bits = 0;
 	unsigned long flags;
 
-#ifdef CONFIG_SMP
+#ifdef CONFIG_PPC_PMAC32_PSURGE
 	void psurge_smp_message_recv(void);
 
        	/* IPI's are a hack on the powersurge -- Cort */
@@ -247,7 +247,7 @@ static unsigned int pmac_pic_get_irq(void)
 		psurge_smp_message_recv();
 		return NO_IRQ_IGNORE;	/* ignore, already handled */
         }
-#endif /* CONFIG_SMP */
+#endif /* CONFIG_PPC_PMAC32_PSURGE */
 	raw_spin_lock_irqsave(&pmac_pic_lock, flags);
 	for (irq = max_real_irqs; (irq -= 32) >= 0; ) {
 		int i = irq >> 5;
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index a340107..67b6e14 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -70,7 +70,7 @@ static void (*pmac_tb_freeze)(int freeze);
 static u64 timebase;
 static int tb_req;
 
-#ifdef CONFIG_PPC32
+#ifdef CONFIG_PPC_PMAC32_PSURGE
 
 /*
  * Powersurge (old powermac SMP) support.
@@ -420,7 +420,7 @@ struct smp_ops_t psurge_smp_ops = {
 	.give_timebase	= smp_psurge_give_timebase,
 	.take_timebase	= smp_psurge_take_timebase,
 };
-#endif /* CONFIG_PPC32 - actually powersurge support */
+#endif /* CONFIG_PPC_PMAC32_PSURGE */
 
 /*
  * Core 99 and later support
@@ -980,7 +980,7 @@ void __init pmac_setup_smp(void)
 		of_node_put(np);
 		smp_ops = &core99_smp_ops;
 	}
-#ifdef CONFIG_PPC32
+#ifdef CONFIG_PPC_PMAC32_PSURGE
 	else {
 		/* We have to set bits in cpu_possible_mask here since the
 		 * secondary CPU(s) aren't in the device tree. Various
@@ -993,7 +993,7 @@ void __init pmac_setup_smp(void)
 			set_cpu_possible(cpu, true);
 		smp_ops = &psurge_smp_ops;
 	}
-#endif /* CONFIG_PPC32 */
+#endif /* CONFIG_PPC_PMAC32_PSURGE */
 
 #ifdef CONFIG_HOTPLUG_CPU
 	ppc_md.cpu_die = pmac_cpu_die;
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 21/37] powerpc: use bytes instead of bitops in smp ipi multiplexing
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (19 preceding siblings ...)
  2011-05-11  5:29 ` [PATCH 20/37] powerpc: add kconfig for muxed smp ipi support Milton Miller
@ 2011-05-11  5:29 ` Milton Miller
  2011-05-11  5:29 ` [PATCH 22/37] powerpc: xics: cleanup xics_host_map and ipi Milton Miller
                   ` (16 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:29 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt

Since there are only 4 messages, we can replace the atomic bit set
(which uses atomic load reserve and store conditional sequence) with
a byte stores to seperate bytes.  We still have to perform a load
reserve and store conditional sequence to avoid loosing messages on
reception but we can do that with a single call to xchg.

The do {} while and __BIG_ENDIAN specific mask testing was chosen by
looking at the generated asm code.  On gcc-4.4, the bit masking becomes
a simple bit mask and test of the register returned from xchg without
storing and loading the value to the stack like attempts with a union
of bytes and an int (or worse, loading single bit constants from the
constant pool into non-voliatle registers that had to be preseved on
the stack).  The do {} while avoids an unconditional branch to the
end of the loop to test the entry / repeat condition of a while loop
and instead optimises for the expected single iteration of the loop.

We have a full mb() at the beginning to cover ordering between send,
ipi, and receive so we can use xchg_local and forgo the further
acquire and release barriers of xchg.

Signed-off-by: Milton Miller <miltonm@bga.com>
---
v4: cast int to char ptr in msg send instead of char[] to int* for xchg/test
v3a: add resend to replace dorbell_check_self
v3: settle on casting from char message[4] __aligned(4) to int ptr
v2: try initialized messages
	(ended up with globals for each check value, increased reg pressure)
v1: initial version, check bytes though pointer to result of xchg
	(resulted in store to stack then byte load / compare / branch)
---
 arch/powerpc/kernel/smp.c |   31 ++++++++++++++++++-------------
 1 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index a28e945..8321b0a 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -180,7 +180,7 @@ int smp_request_message_ipi(int virq, int msg)
 
 #ifdef CONFIG_PPC_SMP_MUXED_IPI
 struct cpu_messages {
-	unsigned long messages;		/* current messages bits */
+	int messages;			/* current messages */
 	unsigned long data;		/* data for cause ipi */
 };
 static DEFINE_PER_CPU_SHARED_ALIGNED(struct cpu_messages, ipi_message);
@@ -195,9 +195,9 @@ void smp_muxed_ipi_set_data(int cpu, unsigned long data)
 void smp_muxed_ipi_message_pass(int cpu, int msg)
 {
 	struct cpu_messages *info = &per_cpu(ipi_message, cpu);
-	unsigned long *tgt = &info->messages;
+	char *message = (char *)&info->messages;
 
-	set_bit(msg, tgt);
+	message[msg] = 1;
 	mb();
 	smp_ops->cause_ipi(cpu, info->data);
 }
@@ -205,30 +205,35 @@ void smp_muxed_ipi_message_pass(int cpu, int msg)
 void smp_muxed_ipi_resend(void)
 {
 	struct cpu_messages *info = &__get_cpu_var(ipi_message);
-	unsigned long *tgt = &info->messages;
 
-	if (*tgt)
+	if (info->messages)
 		smp_ops->cause_ipi(smp_processor_id(), info->data);
 }
 
 irqreturn_t smp_ipi_demux(void)
 {
 	struct cpu_messages *info = &__get_cpu_var(ipi_message);
-	unsigned long *tgt = &info->messages;
+	unsigned int all;
 
 	mb();	/* order any irq clear */
-	while (*tgt) {
-		if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION, tgt))
+
+	do {
+		all = xchg_local(&info->messages, 0);
+
+#ifdef __BIG_ENDIAN
+		if (all & (1 << (24 - 8 * PPC_MSG_CALL_FUNCTION)))
 			generic_smp_call_function_interrupt();
-		if (test_and_clear_bit(PPC_MSG_RESCHEDULE, tgt))
+		if (all & (1 << (24 - 8 * PPC_MSG_RESCHEDULE)))
 			reschedule_action(0, NULL); /* upcoming sched hook */
-		if (test_and_clear_bit(PPC_MSG_CALL_FUNC_SINGLE, tgt))
+		if (all & (1 << (24 - 8 * PPC_MSG_CALL_FUNC_SINGLE)))
 			generic_smp_call_function_single_interrupt();
-#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
-		if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK, tgt))
+		if (all & (1 << (24 - 8 * PPC_MSG_DEBUGGER_BREAK)))
 			debug_ipi_action(0, NULL);
+#else
+#error Unsupported ENDIAN
 #endif
-	}
+	} while (info->messages);
+
 	return IRQ_HANDLED;
 }
 #endif /* CONFIG_PPC_SMP_MUXED_IPI */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 22/37] powerpc: xics: cleanup xics_host_map and ipi
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (20 preceding siblings ...)
  2011-05-11  5:29 ` [PATCH 21/37] powerpc: use bytes instead of bitops in smp ipi multiplexing Milton Miller
@ 2011-05-11  5:29 ` Milton Miller
  2011-05-11  5:29 ` [PATCH 23/37] powerpc: radix trees are available before init_IRQ Milton Miller
                   ` (15 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:29 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt

Since we already have a special case in map to set the ipi handler, use
the desired flow.

If we don't find an ics to handle the interrupt complain instead of
returning 0 without having set a chip or handler.

Signed-off-by: Milton Miller <miltonm@bga.com>
---
 arch/powerpc/sysdev/xics/xics-common.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c
index a31a710..43b2a79 100644
--- a/arch/powerpc/sysdev/xics/xics-common.c
+++ b/arch/powerpc/sysdev/xics/xics-common.c
@@ -135,9 +135,8 @@ static void xics_request_ipi(void)
 
 	/*
 	 * IPIs are marked IRQF_DISABLED as they must run with irqs
-	 * disabled
+	 * disabled, and PERCPU.  The handler was set in map.
 	 */
-	irq_set_handler(ipi, handle_percpu_irq);
 	BUG_ON(request_irq(ipi, icp_ops->ipi_action,
 			   IRQF_DISABLED|IRQF_PERCPU, "IPI", NULL));
 }
@@ -341,15 +340,16 @@ static int xics_host_map(struct irq_host *h, unsigned int virq,
 	/* Don't call into ICS for IPIs */
 	if (hw == XICS_IPI) {
 		irq_set_chip_and_handler(virq, &xics_ipi_chip,
-					 handle_fasteoi_irq);
+					 handle_percpu_irq);
 		return 0;
 	}
 
 	/* Let the ICS setup the chip data */
 	list_for_each_entry(ics, &ics_list, link)
 		if (ics->map(ics, virq) == 0)
-			break;
-	return 0;
+			return 0;
+
+	return -EINVAL;
 }
 
 static int xics_host_xlate(struct irq_host *h, struct device_node *ct,
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 23/37] powerpc: radix trees are available before init_IRQ
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (21 preceding siblings ...)
  2011-05-11  5:29 ` [PATCH 22/37] powerpc: xics: cleanup xics_host_map and ipi Milton Miller
@ 2011-05-11  5:29 ` Milton Miller
  2011-05-11 19:00   ` Grant Likely
  2011-05-11  5:29 ` [PATCH 24/37] powerpc: return early if irq_host lookup type is wrong Milton Miller
                   ` (14 subsequent siblings)
  37 siblings, 1 reply; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:29 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt; +Cc: Thomas Gleixner

Since the generic irq code uses a radix tree for sparse interrupts,
the initcall ordering has been changed to initialize radix trees before
irqs.   We no longer need to defer creating revmap radix trees to the
arch_initcall irq_late_init.

Also, the kmem caches are allocated so we don't need to use
zalloc_maybe_bootmem.

Signed-off-by: Milton Miller <miltonm@bga.com>
---
 arch/powerpc/kernel/irq.c |   78 ++------------------------------------------
 1 files changed, 4 insertions(+), 74 deletions(-)

diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 826552c..f42e869 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -493,7 +493,6 @@ struct irq_map_entry {
 
 static LIST_HEAD(irq_hosts);
 static DEFINE_RAW_SPINLOCK(irq_big_lock);
-static unsigned int revmap_trees_allocated;
 static DEFINE_MUTEX(revmap_trees_mutex);
 static struct irq_map_entry irq_map[NR_IRQS];
 static unsigned int irq_virq_count = NR_IRQS;
@@ -537,7 +536,7 @@ struct irq_host *irq_alloc_host(struct device_node *of_node,
 	/* Allocate structure and revmap table if using linear mapping */
 	if (revmap_type == IRQ_HOST_MAP_LINEAR)
 		size += revmap_arg * sizeof(unsigned int);
-	host = zalloc_maybe_bootmem(size, GFP_KERNEL);
+	host = kzalloc(size, GFP_KERNEL);
 	if (host == NULL)
 		return NULL;
 
@@ -605,6 +604,9 @@ struct irq_host *irq_alloc_host(struct device_node *of_node,
 		smp_wmb();
 		host->revmap_data.linear.revmap = rmap;
 		break;
+	case IRQ_HOST_MAP_TREE:
+		INIT_RADIX_TREE(&host->revmap_data.tree, GFP_KERNEL);
+		break;
 	default:
 		break;
 	}
@@ -839,13 +841,6 @@ void irq_dispose_mapping(unsigned int virq)
 			host->revmap_data.linear.revmap[hwirq] = NO_IRQ;
 		break;
 	case IRQ_HOST_MAP_TREE:
-		/*
-		 * Check if radix tree allocated yet, if not then nothing to
-		 * remove.
-		 */
-		smp_rmb();
-		if (revmap_trees_allocated < 1)
-			break;
 		mutex_lock(&revmap_trees_mutex);
 		radix_tree_delete(&host->revmap_data.tree, hwirq);
 		mutex_unlock(&revmap_trees_mutex);
@@ -906,14 +901,6 @@ unsigned int irq_radix_revmap_lookup(struct irq_host *host,
 	WARN_ON(host->revmap_type != IRQ_HOST_MAP_TREE);
 
 	/*
-	 * Check if the radix tree exists and has bee initialized.
-	 * If not, we fallback to slow mode
-	 */
-	if (revmap_trees_allocated < 2)
-		return irq_find_mapping(host, hwirq);
-
-	/* Now try to resolve */
-	/*
 	 * No rcu_read_lock(ing) needed, the ptr returned can't go under us
 	 * as it's referencing an entry in the static irq_map table.
 	 */
@@ -935,18 +922,8 @@ unsigned int irq_radix_revmap_lookup(struct irq_host *host,
 void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq,
 			     irq_hw_number_t hwirq)
 {
-
 	WARN_ON(host->revmap_type != IRQ_HOST_MAP_TREE);
 
-	/*
-	 * Check if the radix tree exists yet.
-	 * If not, then the irq will be inserted into the tree when it gets
-	 * initialized.
-	 */
-	smp_rmb();
-	if (revmap_trees_allocated < 1)
-		return;
-
 	if (virq != NO_IRQ) {
 		mutex_lock(&revmap_trees_mutex);
 		radix_tree_insert(&host->revmap_data.tree, hwirq,
@@ -1054,53 +1031,6 @@ int arch_early_irq_init(void)
 	return 0;
 }
 
-/* We need to create the radix trees late */
-static int irq_late_init(void)
-{
-	struct irq_host *h;
-	unsigned int i;
-
-	/*
-	 * No mutual exclusion with respect to accessors of the tree is needed
-	 * here as the synchronization is done via the state variable
-	 * revmap_trees_allocated.
-	 */
-	list_for_each_entry(h, &irq_hosts, link) {
-		if (h->revmap_type == IRQ_HOST_MAP_TREE)
-			INIT_RADIX_TREE(&h->revmap_data.tree, GFP_KERNEL);
-	}
-
-	/*
-	 * Make sure the radix trees inits are visible before setting
-	 * the flag
-	 */
-	smp_wmb();
-	revmap_trees_allocated = 1;
-
-	/*
-	 * Insert the reverse mapping for those interrupts already present
-	 * in irq_map[].
-	 */
-	mutex_lock(&revmap_trees_mutex);
-	for (i = 0; i < irq_virq_count; i++) {
-		if (irq_map[i].host &&
-		    (irq_map[i].host->revmap_type == IRQ_HOST_MAP_TREE))
-			radix_tree_insert(&irq_map[i].host->revmap_data.tree,
-					  irq_map[i].hwirq, &irq_map[i]);
-	}
-	mutex_unlock(&revmap_trees_mutex);
-
-	/*
-	 * Make sure the radix trees insertions are visible before setting
-	 * the flag
-	 */
-	smp_wmb();
-	revmap_trees_allocated = 2;
-
-	return 0;
-}
-arch_initcall(irq_late_init);
-
 #ifdef CONFIG_VIRQ_DEBUG
 static int virq_debug_show(struct seq_file *m, void *private)
 {
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 24/37] powerpc: return early if irq_host lookup type is wrong
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (22 preceding siblings ...)
  2011-05-11  5:29 ` [PATCH 23/37] powerpc: radix trees are available before init_IRQ Milton Miller
@ 2011-05-11  5:29 ` Milton Miller
  2011-05-11 19:03   ` Grant Likely
  2011-05-11  5:30 ` [PATCH 25/37] powerpc: remove trival irq_host_ops.unmap Milton Miller
                   ` (13 subsequent siblings)
  37 siblings, 1 reply; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:29 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt; +Cc: Thomas Gleixner

If for some reason the code incrorectly calls the wrong function to
manage the revmap, not only should we warn, we should take action.
However, in the paths we expect to be taken every delivered interrupt
change to WARN_ON_ONCE.  Use the if (WARN_ON(x)) format to get the
unlikely for free.

Signed-off-by: Milton Miller <miltonm@bga.com>
---
 arch/powerpc/kernel/irq.c |   12 +++++++-----
 1 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index f42e869..4a5aa8c 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -814,8 +814,7 @@ void irq_dispose_mapping(unsigned int virq)
 		return;
 
 	host = irq_map[virq].host;
-	WARN_ON (host == NULL);
-	if (host == NULL)
+	if (WARN_ON(host == NULL))
 		return;
 
 	/* Never unmap legacy interrupts */
@@ -898,7 +897,8 @@ unsigned int irq_radix_revmap_lookup(struct irq_host *host,
 	struct irq_map_entry *ptr;
 	unsigned int virq;
 
-	WARN_ON(host->revmap_type != IRQ_HOST_MAP_TREE);
+	if (WARN_ON_ONCE(host->revmap_type != IRQ_HOST_MAP_TREE))
+		return irq_find_mapping(host, hwirq);
 
 	/*
 	 * No rcu_read_lock(ing) needed, the ptr returned can't go under us
@@ -922,7 +922,8 @@ unsigned int irq_radix_revmap_lookup(struct irq_host *host,
 void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq,
 			     irq_hw_number_t hwirq)
 {
-	WARN_ON(host->revmap_type != IRQ_HOST_MAP_TREE);
+	if (WARN_ON(host->revmap_type != IRQ_HOST_MAP_TREE))
+		return;
 
 	if (virq != NO_IRQ) {
 		mutex_lock(&revmap_trees_mutex);
@@ -937,7 +938,8 @@ unsigned int irq_linear_revmap(struct irq_host *host,
 {
 	unsigned int *revmap;
 
-	WARN_ON(host->revmap_type != IRQ_HOST_MAP_LINEAR);
+	if (WARN_ON_ONCE(host->revmap_type != IRQ_HOST_MAP_LINEAR))
+		return irq_find_mapping(host, hwirq);
 
 	/* Check revmap bounds */
 	if (unlikely(hwirq >= host->revmap_data.linear.size))
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 25/37] powerpc: remove trival irq_host_ops.unmap
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (23 preceding siblings ...)
  2011-05-11  5:29 ` [PATCH 24/37] powerpc: return early if irq_host lookup type is wrong Milton Miller
@ 2011-05-11  5:30 ` Milton Miller
  2011-05-11  5:30 ` [PATCH 26/37] powerpc: remove i8259 irq_host_ops->unmap Milton Miller
                   ` (12 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:30 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt; +Cc: Thomas Gleixner

These all just clear chip or chipdata fields, which will be done
by the generic code when we call irq_free_descs.

Signed-off-by: Milton Miller <miltonm@bga.com>
---
 arch/powerpc/platforms/82xx/pq2ads-pci-pic.c     |    8 --------
 arch/powerpc/platforms/embedded6xx/flipper-pic.c |    7 -------
 arch/powerpc/platforms/embedded6xx/hlwd-pic.c    |    7 -------
 arch/powerpc/platforms/ps3/interrupt.c           |    6 ------
 4 files changed, 0 insertions(+), 28 deletions(-)

diff --git a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
index 5d6c34c..8ccf9ed 100644
--- a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
+++ b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
@@ -112,16 +112,8 @@ static int pci_pic_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static void pci_host_unmap(struct irq_host *h, unsigned int virq)
-{
-	/* remove chip and handler */
-	irq_set_chip_data(virq, NULL);
-	irq_set_chip(virq, NULL);
-}
-
 static struct irq_host_ops pci_pic_host_ops = {
 	.map = pci_pic_host_map,
-	.unmap = pci_host_unmap,
 };
 
 int __init pq2ads_pci_init_irq(void)
diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
index 77cbe4c..f61a2dd 100644
--- a/arch/powerpc/platforms/embedded6xx/flipper-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
@@ -107,12 +107,6 @@ static int flipper_pic_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static void flipper_pic_unmap(struct irq_host *h, unsigned int irq)
-{
-	irq_set_chip_data(irq, NULL);
-	irq_set_chip(irq, NULL);
-}
-
 static int flipper_pic_match(struct irq_host *h, struct device_node *np)
 {
 	return 1;
@@ -121,7 +115,6 @@ static int flipper_pic_match(struct irq_host *h, struct device_node *np)
 
 static struct irq_host_ops flipper_irq_host_ops = {
 	.map = flipper_pic_map,
-	.unmap = flipper_pic_unmap,
 	.match = flipper_pic_match,
 };
 
diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
index 44b398b..e491917 100644
--- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
@@ -100,15 +100,8 @@ static int hlwd_pic_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static void hlwd_pic_unmap(struct irq_host *h, unsigned int irq)
-{
-	irq_set_chip_data(irq, NULL);
-	irq_set_chip(irq, NULL);
-}
-
 static struct irq_host_ops hlwd_irq_host_ops = {
 	.map = hlwd_pic_map,
-	.unmap = hlwd_pic_unmap,
 };
 
 static unsigned int __hlwd_pic_get_irq(struct irq_host *h)
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index 523bd0d..600ed2c 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -659,11 +659,6 @@ static void __maybe_unused _dump_mask(struct ps3_private *pd,
 static void dump_bmp(struct ps3_private* pd) {};
 #endif /* defined(DEBUG) */
 
-static void ps3_host_unmap(struct irq_host *h, unsigned int virq)
-{
-	irq_set_chip_data(virq, NULL);
-}
-
 static int ps3_host_map(struct irq_host *h, unsigned int virq,
 	irq_hw_number_t hwirq)
 {
@@ -683,7 +678,6 @@ static int ps3_host_match(struct irq_host *h, struct device_node *np)
 
 static struct irq_host_ops ps3_host_ops = {
 	.map = ps3_host_map,
-	.unmap = ps3_host_unmap,
 	.match = ps3_host_match,
 };
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 26/37] powerpc: remove i8259 irq_host_ops->unmap
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (24 preceding siblings ...)
  2011-05-11  5:30 ` [PATCH 25/37] powerpc: remove trival irq_host_ops.unmap Milton Miller
@ 2011-05-11  5:30 ` Milton Miller
  2011-05-11  5:30 ` [PATCH 27/37] powerpc fsl_msi: don't abuse platform_data for driver_data Milton Miller
                   ` (11 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:30 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt; +Cc: Thomas Gleixner

It was never called because the host is always IRQ_HOST_MAP_LEGACY.

And what it purported to do was mask the interrupt (which will already
have happend if we shutdown the interrupt), then synchronise_irq and
clear the chip pointer, both of which will have been be done by the
caller were we to call unmap on a legacy irq.

Signed-off-by: Milton Miller <miltonm@bga.com>
---
---
 arch/powerpc/sysdev/i8259.c |   13 -------------
 1 files changed, 0 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c
index 142770c..d18bb27 100644
--- a/arch/powerpc/sysdev/i8259.c
+++ b/arch/powerpc/sysdev/i8259.c
@@ -185,18 +185,6 @@ static int i8259_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static void i8259_host_unmap(struct irq_host *h, unsigned int virq)
-{
-	/* Make sure irq is masked in hardware */
-	i8259_mask_irq(irq_get_irq_data(virq));
-
-	/* remove chip and handler */
-	irq_set_chip_and_handler(virq, NULL, NULL);
-
-	/* Make sure it's completed */
-	synchronize_irq(virq);
-}
-
 static int i8259_host_xlate(struct irq_host *h, struct device_node *ct,
 			    const u32 *intspec, unsigned int intsize,
 			    irq_hw_number_t *out_hwirq, unsigned int *out_flags)
@@ -220,7 +208,6 @@ static int i8259_host_xlate(struct irq_host *h, struct device_node *ct,
 static struct irq_host_ops i8259_host_ops = {
 	.match = i8259_host_match,
 	.map = i8259_host_map,
-	.unmap = i8259_host_unmap,
 	.xlate = i8259_host_xlate,
 };
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 27/37] powerpc fsl_msi: don't abuse platform_data for driver_data
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (25 preceding siblings ...)
  2011-05-11  5:30 ` [PATCH 26/37] powerpc: remove i8259 irq_host_ops->unmap Milton Miller
@ 2011-05-11  5:30 ` Milton Miller
  2011-05-11 19:05   ` Grant Likely
  2011-05-11  5:30 ` [PATCH 28/37] powerpc: fsl_msi: use chip_data not handler_data Milton Miller
                   ` (10 subsequent siblings)
  37 siblings, 1 reply; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:30 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt; +Cc: Thomas Gleixner

The msi platform device driver was abusing dev.platform_data for its
platform_driver_data.  Use the correct pointer for storage.

Platform_data is supposed to be for platforms to communicate to drivers
parameters that are not otherwise discoverable.  Its lifetime matches
the platform_device not the platform device driver.  It is generally
not needed for drivers that only support systems with device trees.

Signed-off-by: Milton Miller <miltonm@bga.com>
---
---
 arch/powerpc/sysdev/fsl_msi.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index d5679dc..077776c 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -253,7 +253,7 @@ unlock:
 
 static int fsl_of_msi_remove(struct platform_device *ofdev)
 {
-	struct fsl_msi *msi = ofdev->dev.platform_data;
+	struct fsl_msi *msi = platform_get_drvdata(ofdev);
 	int virq, i;
 	struct fsl_msi_cascade_data *cascade_data;
 
@@ -327,7 +327,7 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev)
 		dev_err(&dev->dev, "No memory for MSI structure\n");
 		return -ENOMEM;
 	}
-	dev->dev.platform_data = msi;
+	platform_set_drvdata(dev, msi);
 
 	msi->irqhost = irq_alloc_host(dev->dev.of_node, IRQ_HOST_MAP_LINEAR,
 				      NR_MSI_IRQS, &fsl_msi_host_ops, 0);
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 28/37] powerpc: fsl_msi: use chip_data not handler_data
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (26 preceding siblings ...)
  2011-05-11  5:30 ` [PATCH 27/37] powerpc fsl_msi: don't abuse platform_data for driver_data Milton Miller
@ 2011-05-11  5:30 ` Milton Miller
  2011-05-11  5:30 ` [PATCH 29/37] powerpc: mpc5121_ads_cpld: remove use of NO_IRQ_IGNORE Milton Miller
                   ` (9 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:30 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt; +Cc: Thomas Gleixner

handler_data should be reserved for flow handlers on the dependent
irq, not consumed by the parent irq code that is part of the irq_chip
code.  The msi_data pointer was already set in msidesc->irqhost->hostdata
and being copied to irq_data->chipdata in the msidesc->irqhost->map()
method called via create_irq_mapping, so we can obtain the pointer
from there and free the instance it in teardown_msi_irqs.

Also remove the unnecessary cast of irq_get_handler_data in the
cascade handler, which is the demux flow handler of the parent
msi interrupt.  (This is the expected usage for handler_data).

Signed-off-by: Milton Miller <miltonm@bga.com>
---
---
 arch/powerpc/sysdev/fsl_msi.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index 077776c..067cc88 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -110,7 +110,7 @@ static void fsl_teardown_msi_irqs(struct pci_dev *pdev)
 	list_for_each_entry(entry, &pdev->msi_list, list) {
 		if (entry->irq == NO_IRQ)
 			continue;
-		msi_data = irq_get_handler_data(entry->irq);
+		msi_data = irq_get_chip_data(entry->irq);
 		irq_set_msi_desc(entry->irq, NULL);
 		msi_bitmap_free_hwirqs(&msi_data->bitmap,
 				       virq_to_hw(entry->irq), 1);
@@ -168,7 +168,7 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
 			rc = -ENOSPC;
 			goto out_free;
 		}
-		irq_set_handler_data(virq, msi_data);
+		/* chip_data is msi_data via host->hostdata in host->map() */
 		irq_set_msi_desc(virq, entry);
 
 		fsl_compose_msi_msg(pdev, hwirq, &msg, msi_data);
@@ -193,7 +193,7 @@ static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc)
 	u32 have_shift = 0;
 	struct fsl_msi_cascade_data *cascade_data;
 
-	cascade_data = (struct fsl_msi_cascade_data *)irq_get_handler_data(irq);
+	cascade_data = irq_get_handler_data(irq);
 	msi_data = cascade_data->msi_data;
 
 	raw_spin_lock(&desc->lock);
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 29/37] powerpc: mpc5121_ads_cpld: remove use of NO_IRQ_IGNORE
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (27 preceding siblings ...)
  2011-05-11  5:30 ` [PATCH 28/37] powerpc: fsl_msi: use chip_data not handler_data Milton Miller
@ 2011-05-11  5:30 ` Milton Miller
  2011-05-11 19:07   ` Grant Likely
  2011-05-11  5:30 ` [PATCH 30/37] powerpc: mpc62xx_pic: fix get_irq handling of NO_IRQ Milton Miller
                   ` (8 subsequent siblings)
  37 siblings, 1 reply; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:30 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt; +Cc: Thomas Gleixner

As NO_IRQ_IGNORE is only used between the static function cpld_pic_get_irq
and its caller cpld_pic_cascade, and cpld_pic_cascade only uses it to
suppress calling handle_generic_irq, we can change these uses to NO_IRQ
and remove the extra tests and pathlength in cpld_pic_cascade.

Signed-off-by: Milton Miller <miltonm@bga.com>
---
---
 arch/powerpc/platforms/512x/mpc5121_ads_cpld.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
index a8bc0d4..9f09319 100644
--- a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
+++ b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
@@ -97,7 +97,7 @@ cpld_pic_get_irq(int offset, u8 ignore, u8 __iomem *statusp,
 	status |= (ignore | mask);
 
 	if (status == 0xff)
-		return NO_IRQ_IGNORE;
+		return NO_IRQ;
 
 	cpld_irq = ffz(status) + offset;
 
@@ -109,14 +109,14 @@ cpld_pic_cascade(unsigned int irq, struct irq_desc *desc)
 {
 	irq = cpld_pic_get_irq(0, PCI_IGNORE, &cpld_regs->pci_status,
 		&cpld_regs->pci_mask);
-	if (irq != NO_IRQ && irq != NO_IRQ_IGNORE) {
+	if (irq != NO_IRQ) {
 		generic_handle_irq(irq);
 		return;
 	}
 
 	irq = cpld_pic_get_irq(8, MISC_IGNORE, &cpld_regs->misc_status,
 		&cpld_regs->misc_mask);
-	if (irq != NO_IRQ && irq != NO_IRQ_IGNORE) {
+	if (irq != NO_IRQ) {
 		generic_handle_irq(irq);
 		return;
 	}
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 30/37] powerpc: mpc62xx_pic: fix get_irq handling of NO_IRQ
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (28 preceding siblings ...)
  2011-05-11  5:30 ` [PATCH 29/37] powerpc: mpc5121_ads_cpld: remove use of NO_IRQ_IGNORE Milton Miller
@ 2011-05-11  5:30 ` Milton Miller
  2011-05-11 19:08   ` Grant Likely
  2011-05-11  5:30 ` [PATCH 31/37] powerpc: psurge: create a irq_host for secondary cpus Milton Miller
                   ` (7 subsequent siblings)
  37 siblings, 1 reply; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:30 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt; +Cc: Thomas Gleixner

If none of irq category bits were set mpc52xx_get_irq() would pass
NO_IRQ_IGNORE (-1) to irq_linear_revmap, which does an unsigned compare
and declares the interrupt above the linear map range.  It then punts
to irq_find_mapping, which performs a linear search of all irqs,
which will likely miss and only then return NO_IRQ.

If no status bit is set, then we should return NO_IRQ directly.
The interrupt should not be suppressed from spurious counting, in fact
that is the definition of supurious.

Signed-off-by: Milton Miller <miltonm@bga.com>
---
---
 arch/powerpc/platforms/52xx/mpc52xx_pic.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
index bb61181..1a9a495 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
@@ -486,7 +486,7 @@ void __init mpc52xx_init_irq(void)
 unsigned int mpc52xx_get_irq(void)
 {
 	u32 status;
-	int irq = NO_IRQ_IGNORE;
+	int irq;
 
 	status = in_be32(&intr->enc_status);
 	if (status & 0x00000400) {	/* critical */
@@ -509,6 +509,8 @@ unsigned int mpc52xx_get_irq(void)
 		} else {
 			irq |= (MPC52xx_IRQ_L1_PERP << MPC52xx_IRQ_L1_OFFSET);
 		}
+	} else {
+		return NO_IRQ;
 	}
 
 	return irq_linear_revmap(mpc52xx_irqhost, irq);
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 31/37] powerpc: psurge: create a irq_host for secondary cpus
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (29 preceding siblings ...)
  2011-05-11  5:30 ` [PATCH 30/37] powerpc: mpc62xx_pic: fix get_irq handling of NO_IRQ Milton Miller
@ 2011-05-11  5:30 ` Milton Miller
  2011-05-11  5:30 ` [PATCH 32/37] powerpc: remove irq_host_ops->remap hook Milton Miller
                   ` (6 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:30 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt; +Cc: Thomas Gleixner

Create a dummy irq_host using the generic dummy irq chip for the secondary
cpus to use.  Create a direct irq mapping for the ipi and register the
ipi action handler against it.  If for some unlikely reason part of this
fails then don't detect the secondary cpus.

This removes another instance of NO_IRQ_IGNORE, records the ipi stats
for the secondary cpus, and runs the ipi on the interrupt stack.

Signed-off-by: Milton Miller <miltonm@bga.com>
---
---
 arch/powerpc/platforms/powermac/pic.c  |    9 ++----
 arch/powerpc/platforms/powermac/pmac.h |    1 +
 arch/powerpc/platforms/powermac/smp.c  |   49 +++++++++++++++++++++++++++----
 3 files changed, 46 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index b706cb3..360260d 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -240,12 +240,9 @@ static unsigned int pmac_pic_get_irq(void)
 	unsigned long flags;
 
 #ifdef CONFIG_PPC_PMAC32_PSURGE
-	void psurge_smp_message_recv(void);
-
-       	/* IPI's are a hack on the powersurge -- Cort */
-       	if ( smp_processor_id() != 0 ) {
-		psurge_smp_message_recv();
-		return NO_IRQ_IGNORE;	/* ignore, already handled */
+	/* IPI's are a hack on the powersurge -- Cort */
+	if (smp_processor_id() != 0) {
+		return  psurge_secondary_virq;
         }
 #endif /* CONFIG_PPC_PMAC32_PSURGE */
 	raw_spin_lock_irqsave(&pmac_pic_lock, flags);
diff --git a/arch/powerpc/platforms/powermac/pmac.h b/arch/powerpc/platforms/powermac/pmac.h
index 20468f4..8327cce 100644
--- a/arch/powerpc/platforms/powermac/pmac.h
+++ b/arch/powerpc/platforms/powermac/pmac.h
@@ -33,6 +33,7 @@ extern void pmac_setup_pci_dma(void);
 extern void pmac_check_ht_link(void);
 
 extern void pmac_setup_smp(void);
+extern int psurge_secondary_virq;
 extern void low_cpu_die(void) __attribute__((noreturn));
 
 extern int pmac_nvram_init(void);
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 67b6e14..db092d7 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -124,6 +124,10 @@ static volatile u32 __iomem *psurge_start;
 /* what sort of powersurge board we have */
 static int psurge_type = PSURGE_NONE;
 
+/* irq for secondary cpus to report */
+static struct irq_host *psurge_host;
+int psurge_secondary_virq;
+
 /*
  * Set and clear IPIs for powersurge.
  */
@@ -159,15 +163,11 @@ static inline void psurge_clr_ipi(int cpu)
  * use the generic demux helpers
  *  -- paulus.
  */
-void psurge_smp_message_recv(void)
+static irqreturn_t psurge_ipi_intr(int irq, void *d)
 {
 	psurge_clr_ipi(smp_processor_id());
 	smp_ipi_demux();
-}
 
-irqreturn_t psurge_primary_intr(int irq, void *d)
-{
-	psurge_smp_message_recv();
 	return IRQ_HANDLED;
 }
 
@@ -176,6 +176,38 @@ static void smp_psurge_cause_ipi(int cpu, unsigned long data)
 	psurge_set_ipi(cpu);
 }
 
+static int psurge_host_map(struct irq_host *h, unsigned int virq,
+			 irq_hw_number_t hw)
+{
+	irq_set_chip_and_handler(virq, &dummy_irq_chip, handle_percpu_irq);
+
+	return 0;
+}
+
+struct irq_host_ops psurge_host_ops = {
+	.map	= psurge_host_map,
+};
+
+static int psurge_secondary_ipi_init(void)
+{
+	int rc = -ENOMEM;
+
+	psurge_host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0,
+		&psurge_host_ops, 0);
+
+	if (psurge_host)
+		psurge_secondary_virq = irq_create_direct_mapping(psurge_host);
+
+	if (psurge_secondary_virq)
+		rc = request_irq(psurge_secondary_virq, psurge_ipi_intr,
+			IRQF_DISABLED|IRQF_PERCPU, "IPI", NULL);
+
+	if (rc)
+		pr_err("Failed to setup secondary cpu IPI\n");
+
+	return rc;
+}
+
 /*
  * Determine a quad card presence. We read the board ID register, we
  * force the data bus to change to something else, and we read it again.
@@ -284,6 +316,9 @@ static int __init smp_psurge_probe(void)
 		ncpus = 2;
 	}
 
+	if (psurge_secondary_ipi_init())
+		return 1;
+
 	psurge_start = ioremap(PSURGE_START, 4);
 	psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4);
 
@@ -372,8 +407,8 @@ static int __init smp_psurge_kick_cpu(int nr)
 }
 
 static struct irqaction psurge_irqaction = {
-	.handler = psurge_primary_intr,
-	.flags = IRQF_DISABLED,
+	.handler = psurge_ipi_intr,
+	.flags = IRQF_DISABLED|IRQF_PERCPU,
 	.name = "primary IPI",
 };
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 32/37] powerpc: remove irq_host_ops->remap hook
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (30 preceding siblings ...)
  2011-05-11  5:30 ` [PATCH 31/37] powerpc: psurge: create a irq_host for secondary cpus Milton Miller
@ 2011-05-11  5:30 ` Milton Miller
  2011-05-11  5:30 ` [PATCH 33/37] powerpc: spider-pic: get pic from chip_data instead of irq_map Milton Miller
                   ` (5 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:30 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt; +Cc: Thomas Gleixner

It was called from irq_create_mapping if that was called for a host
and hwirq that was previously mapped, "to update the flags".  But the
only implementation was in beat_interrupt and all it did was repeat a
hypervisor call without error checking that was performed with error
checking at the beginning of the map hook.  In addition, the comment on
the beat remap hook says it will only called once for a given mapping,
which would apply to map not remap.

All flags should be known by the time the match hook is called, before
we call the map hook.  Removing this mostly unused hook will simpify
the requirements of irq_domain concept.

Signed-off-by: Milton Miller <miltonm@bga.com>
---
 arch/powerpc/include/asm/irq.h               |    3 ---
 arch/powerpc/kernel/irq.c                    |    2 --
 arch/powerpc/platforms/cell/beat_interrupt.c |   11 -----------
 3 files changed, 0 insertions(+), 16 deletions(-)

diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h
index e1983d5..6f4a3ef 100644
--- a/arch/powerpc/include/asm/irq.h
+++ b/arch/powerpc/include/asm/irq.h
@@ -88,9 +88,6 @@ struct irq_host_ops {
 	/* Dispose of such a mapping */
 	void (*unmap)(struct irq_host *h, unsigned int virq);
 
-	/* Update of such a mapping  */
-	void (*remap)(struct irq_host *h, unsigned int virq, irq_hw_number_t hw);
-
 	/* Translate device-tree interrupt specifier from raw format coming
 	 * from the firmware to a irq_hw_number_t (interrupt line number) and
 	 * type (sense) that can be passed to set_irq_type(). In the absence
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 4a5aa8c..0715a09 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -732,8 +732,6 @@ unsigned int irq_create_mapping(struct irq_host *host,
 	 */
 	virq = irq_find_mapping(host, hwirq);
 	if (virq != NO_IRQ) {
-		if (host->ops->remap)
-			host->ops->remap(host, virq, hwirq);
 		pr_debug("irq: -> existing mapping on virq %d\n", virq);
 		return virq;
 	}
diff --git a/arch/powerpc/platforms/cell/beat_interrupt.c b/arch/powerpc/platforms/cell/beat_interrupt.c
index d46f7e4..55015e1 100644
--- a/arch/powerpc/platforms/cell/beat_interrupt.c
+++ b/arch/powerpc/platforms/cell/beat_interrupt.c
@@ -148,16 +148,6 @@ static int beatic_pic_host_map(struct irq_host *h, unsigned int virq,
 }
 
 /*
- * Update binding hardware IRQ number (hw) and Virtuql
- * IRQ number (virq). This is called only once for a given mapping.
- */
-static void beatic_pic_host_remap(struct irq_host *h, unsigned int virq,
-			       irq_hw_number_t hw)
-{
-	beat_construct_and_connect_irq_plug(virq, hw);
-}
-
-/*
  * Translate device-tree interrupt spec to irq_hw_number_t style (ulong),
  * to pass away to irq_create_mapping().
  *
@@ -184,7 +174,6 @@ static int beatic_pic_host_match(struct irq_host *h, struct device_node *np)
 
 static struct irq_host_ops beatic_pic_host_ops = {
 	.map = beatic_pic_host_map,
-	.remap = beatic_pic_host_remap,
 	.unmap = beatic_pic_host_unmap,
 	.xlate = beatic_pic_host_xlate,
 	.match = beatic_pic_host_match,
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 33/37] powerpc: spider-pic: get pic from chip_data instead of irq_map
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (31 preceding siblings ...)
  2011-05-11  5:30 ` [PATCH 32/37] powerpc: remove irq_host_ops->remap hook Milton Miller
@ 2011-05-11  5:30 ` Milton Miller
  2011-05-11 19:13   ` Grant Likely
  2011-05-11  5:30 ` [PATCH 34/37] powerpc: axon_msi: validate msi irq via chip_data Milton Miller
                   ` (4 subsequent siblings)
  37 siblings, 1 reply; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:30 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt; +Cc: Thomas Gleixner

Building on Grant's efforts to remove the irq_map array, this patch
moves spider-pics use of virq_to_host() to use irq_data_get_chip_data
and sets the irq chip data in the map call, like most other interrupt
controllers in powerpc.

Signed-off-by: Milton Miller <miltonm@bga.com>
---
---
 arch/powerpc/platforms/cell/spider-pic.c |   13 +++++++------
 1 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index 34d2b99..442c28c 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -68,9 +68,9 @@ struct spider_pic {
 };
 static struct spider_pic spider_pics[SPIDER_CHIP_COUNT];
 
-static struct spider_pic *spider_virq_to_pic(unsigned int virq)
+static struct spider_pic *spider_irq_data_to_pic(struct irq_data *d)
 {
-	return virq_to_host(virq)->host_data;
+	return irq_data_get_irq_chip_data(d);
 }
 
 static void __iomem *spider_get_irq_config(struct spider_pic *pic,
@@ -81,7 +81,7 @@ static void __iomem *spider_get_irq_config(struct spider_pic *pic,
 
 static void spider_unmask_irq(struct irq_data *d)
 {
-	struct spider_pic *pic = spider_virq_to_pic(d->irq);
+	struct spider_pic *pic = spider_irq_data_to_pic(d);
 	void __iomem *cfg = spider_get_irq_config(pic, irqd_to_hwirq(d));
 
 	out_be32(cfg, in_be32(cfg) | 0x30000000u);
@@ -89,7 +89,7 @@ static void spider_unmask_irq(struct irq_data *d)
 
 static void spider_mask_irq(struct irq_data *d)
 {
-	struct spider_pic *pic = spider_virq_to_pic(d->irq);
+	struct spider_pic *pic = spider_irq_data_to_pic(d);
 	void __iomem *cfg = spider_get_irq_config(pic, irqd_to_hwirq(d));
 
 	out_be32(cfg, in_be32(cfg) & ~0x30000000u);
@@ -97,7 +97,7 @@ static void spider_mask_irq(struct irq_data *d)
 
 static void spider_ack_irq(struct irq_data *d)
 {
-	struct spider_pic *pic = spider_virq_to_pic(d->irq);
+	struct spider_pic *pic = spider_irq_data_to_pic(d);
 	unsigned int src = irqd_to_hwirq(d);
 
 	/* Reset edge detection logic if necessary
@@ -116,7 +116,7 @@ static void spider_ack_irq(struct irq_data *d)
 static int spider_set_irq_type(struct irq_data *d, unsigned int type)
 {
 	unsigned int sense = type & IRQ_TYPE_SENSE_MASK;
-	struct spider_pic *pic = spider_virq_to_pic(d->irq);
+	struct spider_pic *pic = spider_irq_data_to_pic(d);
 	unsigned int hw = irqd_to_hwirq(d);
 	void __iomem *cfg = spider_get_irq_config(pic, hw);
 	u32 old_mask;
@@ -171,6 +171,7 @@ static struct irq_chip spider_pic = {
 static int spider_host_map(struct irq_host *h, unsigned int virq,
 			irq_hw_number_t hw)
 {
+	irq_set_chip_data(virq, h->host_data);
 	irq_set_chip_and_handler(virq, &spider_pic, handle_level_irq);
 
 	/* Set default irq type */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 34/37] powerpc: axon_msi: validate msi irq via chip_data
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (32 preceding siblings ...)
  2011-05-11  5:30 ` [PATCH 33/37] powerpc: spider-pic: get pic from chip_data instead of irq_map Milton Miller
@ 2011-05-11  5:30 ` Milton Miller
  2011-05-11  5:30 ` [PATCH 35/37] powerpc: add virq_is_host to reduce virq_to_host usage Milton Miller
                   ` (3 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:30 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt; +Cc: Thomas Gleixner

Instead of checking for rogue msi numbers via the irq_map host field
set the chip_data to h.host_data (which is the msic struct pointer)
at map and compare it in get_irq.

Signed-off-by: Milton Miller <miltonm@bga.com>
---
---
 arch/powerpc/platforms/cell/axon_msi.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index 1e3329e..ac06903 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -113,7 +113,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
 		pr_devel("axon_msi: woff %x roff %x msi %x\n",
 			  write_offset, msic->read_offset, msi);
 
-		if (msi < NR_IRQS && virq_to_host(msi) == msic->irq_host) {
+		if (msi < NR_IRQS && irq_get_chip_data(msi) == msic) {
 			generic_handle_irq(msi);
 			msic->fifo_virt[idx] = cpu_to_le32(0xffffffff);
 		} else {
@@ -320,6 +320,7 @@ static struct irq_chip msic_irq_chip = {
 static int msic_host_map(struct irq_host *h, unsigned int virq,
 			 irq_hw_number_t hw)
 {
+	irq_set_chip_data(virq, h->host_data);
 	irq_set_chip_and_handler(virq, &msic_irq_chip, handle_simple_irq);
 
 	return 0;
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 35/37] powerpc: add virq_is_host to reduce virq_to_host usage
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (33 preceding siblings ...)
  2011-05-11  5:30 ` [PATCH 34/37] powerpc: axon_msi: validate msi irq via chip_data Milton Miller
@ 2011-05-11  5:30 ` Milton Miller
  2011-05-11 19:16   ` Grant Likely
  2011-05-11  5:30 ` [PATCH 36/37] powerpc: remove virq_to_host Milton Miller
                   ` (2 subsequent siblings)
  37 siblings, 1 reply; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:30 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt; +Cc: Thomas Gleixner

Some irq_host implementations are using virq_to_host to check if
they are the irq_host for a virtual irq.  To allow us to make space
versus time tradeoffs, replace this usage with an assertive
virq_is_host that confirms or denies the irq is associated with the
given irq_host.

Signed-off-by: Milton Miller <miltonm@bga.com>
---
 arch/powerpc/include/asm/irq.h         |    1 +
 arch/powerpc/kernel/irq.c              |    6 ++++++
 arch/powerpc/sysdev/xics/xics-common.c |    2 +-
 3 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h
index 6f4a3ef..a65d170 100644
--- a/arch/powerpc/include/asm/irq.h
+++ b/arch/powerpc/include/asm/irq.h
@@ -128,6 +128,7 @@ struct irq_host {
 struct irq_data;
 extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d);
 extern irq_hw_number_t virq_to_hw(unsigned int virq);
+extern bool virq_is_host(unsigned int virq, struct irq_host *host);
 extern struct irq_host *virq_to_host(unsigned int virq);
 
 /**
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 0715a09..73cf290 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -510,6 +510,12 @@ irq_hw_number_t virq_to_hw(unsigned int virq)
 }
 EXPORT_SYMBOL_GPL(virq_to_hw);
 
+bool virq_is_host(unsigned int virq, struct irq_host *host)
+{
+	return irq_map[virq].host == host;
+}
+EXPORT_SYMBOL_GPL(virq_is_host);
+
 struct irq_host *virq_to_host(unsigned int virq)
 {
 	return irq_map[virq].host;
diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c
index 43b2a79..445c5a0 100644
--- a/arch/powerpc/sysdev/xics/xics-common.c
+++ b/arch/powerpc/sysdev/xics/xics-common.c
@@ -213,7 +213,7 @@ void xics_migrate_irqs_away(void)
 		/* We can't set affinity on ISA interrupts */
 		if (virq < NUM_ISA_INTERRUPTS)
 			continue;
-		if (virq_to_host(virq) != xics_host)
+		if (!virq_is_host(virq, xics_host))
 			continue;
 		irq = (unsigned int)virq_to_hw(virq);
 		/* We need to get IPIs still. */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 36/37] powerpc: remove virq_to_host
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (34 preceding siblings ...)
  2011-05-11  5:30 ` [PATCH 35/37] powerpc: add virq_is_host to reduce virq_to_host usage Milton Miller
@ 2011-05-11  5:30 ` Milton Miller
  2011-05-11 19:17   ` Grant Likely
  2011-05-11  5:30 ` [PATCH 37/37] powerpc: make IRQ_NOREQUEST last to clear, first to set Milton Miller
  2011-05-11 19:40 ` [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Grant Likely
  37 siblings, 1 reply; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:30 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt; +Cc: Thomas Gleixner

The only references to the irq_map[].host field are internal to
arch/powerpc/kernel/irq.c

Signed-off-by: Milton Miller <miltonm@bga.com>
---
---
 arch/powerpc/include/asm/irq.h |    1 -
 arch/powerpc/kernel/irq.c      |    6 ------
 2 files changed, 0 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h
index a65d170..1bff591 100644
--- a/arch/powerpc/include/asm/irq.h
+++ b/arch/powerpc/include/asm/irq.h
@@ -129,7 +129,6 @@ struct irq_data;
 extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d);
 extern irq_hw_number_t virq_to_hw(unsigned int virq);
 extern bool virq_is_host(unsigned int virq, struct irq_host *host);
-extern struct irq_host *virq_to_host(unsigned int virq);
 
 /**
  * irq_alloc_host - Allocate a new irq_host data structure
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 73cf290..4368b5e 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -516,12 +516,6 @@ bool virq_is_host(unsigned int virq, struct irq_host *host)
 }
 EXPORT_SYMBOL_GPL(virq_is_host);
 
-struct irq_host *virq_to_host(unsigned int virq)
-{
-	return irq_map[virq].host;
-}
-EXPORT_SYMBOL_GPL(virq_to_host);
-
 static int default_irq_host_match(struct irq_host *h, struct device_node *np)
 {
 	return h->of_node != NULL && h->of_node == np;
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 37/37] powerpc: make IRQ_NOREQUEST last to clear, first to set
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (35 preceding siblings ...)
  2011-05-11  5:30 ` [PATCH 36/37] powerpc: remove virq_to_host Milton Miller
@ 2011-05-11  5:30 ` Milton Miller
  2011-05-11 19:18   ` Grant Likely
  2011-05-11 19:40 ` [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Grant Likely
  37 siblings, 1 reply; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:30 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt; +Cc: Thomas Gleixner

When allocating irqs, wait to clear the IRQ_NOREQUEST flag until the
host map hook has been called.

When freeing irqs, set the IRQ_NOREQUEST flag before calling the host
unmap hook.

Signed-off-by: Milton Miller <miltonm@bga.com>
---
 arch/powerpc/kernel/irq.c |   14 +++++++-------
 1 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 4368b5e..a24d37d 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -586,14 +586,14 @@ struct irq_host *irq_alloc_host(struct device_node *of_node,
 			irq_map[i].host = host;
 			smp_wmb();
 
-			/* Clear norequest flags */
-			irq_clear_status_flags(i, IRQ_NOREQUEST);
-
 			/* Legacy flags are left to default at this point,
 			 * one can then use irq_create_mapping() to
 			 * explicitly change them
 			 */
 			ops->map(host, i, i);
+
+			/* Clear norequest flags */
+			irq_clear_status_flags(i, IRQ_NOREQUEST);
 		}
 		break;
 	case IRQ_HOST_MAP_LINEAR:
@@ -664,8 +664,6 @@ static int irq_setup_virq(struct irq_host *host, unsigned int virq,
 		goto error;
 	}
 
-	irq_clear_status_flags(virq, IRQ_NOREQUEST);
-
 	/* map it */
 	smp_wmb();
 	irq_map[virq].hwirq = hwirq;
@@ -676,6 +674,8 @@ static int irq_setup_virq(struct irq_host *host, unsigned int virq,
 		goto errdesc;
 	}
 
+	irq_clear_status_flags(virq, IRQ_NOREQUEST);
+
 	return 0;
 
 errdesc:
@@ -819,6 +819,8 @@ void irq_dispose_mapping(unsigned int virq)
 	if (host->revmap_type == IRQ_HOST_MAP_LEGACY)
 		return;
 
+	irq_set_status_flags(virq, IRQ_NOREQUEST);
+
 	/* remove chip and handler */
 	irq_set_chip_and_handler(virq, NULL, NULL);
 
@@ -848,8 +850,6 @@ void irq_dispose_mapping(unsigned int virq)
 	smp_mb();
 	irq_map[virq].hwirq = host->inval_irq;
 
-	irq_set_status_flags(virq, IRQ_NOREQUEST);
-
 	irq_free_descs(virq, 1);
 	/* Free it */
 	irq_free_virt(virq, 1);
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code
@ 2011-05-11  5:43 Milton Miller
  2011-05-11  5:28 ` [PATCH 01/37] powerpc: fix memory corruption from unallocated slaves Milton Miller
                   ` (37 more replies)
  0 siblings, 38 replies; 51+ messages in thread
From: Milton Miller @ 2011-05-11  5:43 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt; +Cc: Thomas Gleixner

This series represents a somewhat ordered, somewhat meandering series
development series of patches I've been working on for the past few weeks.

It starts with memory corruption fixes that need to go back to stable
relating to slave cpu searches and paca allocation.  After refactoring
and taking into consideration of patches merged upstream, I think this
is just the first 4, but the next 3 are related.

  powerpc: fix memory corruption from unallocated slaves
  powerpc: don't search for paca in freed memory
  powerpc/kdump64:  Don't reference freed memory as pacas
  powerpc/iseries: cleanup and fix secondary startup

  powerpc: Respect nr_cpu_ids when calling set_cpu_possible and set_cpu_present
  powerpc: use nr_cpu_ids in initial paca allocation
  powerpc: call no-longer static setup_nr_cpu_ids instead of replicating it

A search for NR_CPUS found that MSG_ALL_BUT_SELF was only used to enter
the debugger, but caused special code loops in all smp_ops,
so I pulled that code for a bit more path length in the loop to enter
the debugger or kexec.  I then simplified the mpic code and factored
out common code in ipi interrupt multiplexing.   That allowed an
easy change to remove a set of lwarx/stwcx. in the ipi send path.

  powerpc: mpic: limit NR_CPUS loop to 32 bit
  powerpc: mpic: break cpumask abstraction earlier
  powerpc: remove call sites of MSG_ALL_BUT_SELF
  powerpc: remove checks for MSG_ALL and MSG_ALL_BUT_SELF
  linux/smp.h: remove unused MSG_ flags
  powerpc/mpic: simplify ipi cpu mask handling
  powerpc: remove powermac/pic.h
  powerpc: remove alloc_maybe_bootmem for zalloc version
  powerpc: remove stubbed beat smp support
  powerpc cell: use smp_request_message_ipi  [ patchwork 3780 ]
  powerpc: move smp_ops_t from machdep.h to smp.h
  powerpc: consolidate ipi message mux and demux
  powerpc: add kconfig for muxed smp ipi support
  powerpc: use bytes instead of bitops in smp ipi multiplexing

I then got sidetracked with Grant's quest to create irq_domains from the
irq_host code.  I started going through the irq_host implementations in
arch/powerpc, removing some code that was redundant or not called, tring
to simplify the interfaces before we export them.  Also standardizing
the use of the per-irq chip data and handler data.

  powerpc: xics: cleanup xics_host_map and ipi
  powerpc: radix trees are available before init_IRQ
  powerpc: return early if irq_host lookup type is wrong
  powerpc: remove trival irq_host_ops.unmap
  powerpc: remove i8259 irq_host_ops->unmap
  powerpc fsl_msi: don't abuse platform_data for driver_data
  powerpc: fsl_msi: use chip_data not handler_data
  powerpc: mpc5121_ads_cpld: remove use of NO_IRQ_IGNORE
  powerpc: mpc62xx_pic: fix get_irq handling of NO_IRQ
  powerpc: psurge: create a irq_host for secondary cpus
  powerpc: remove irq_host_ops->remap hook
  powerpc: spider-pic: get pic from chip_data instead of irq_map
  powerpc: axon_msi: validate msi irq via chip_data
  powerpc: add virq_is_host to reduce virq_to_host usage
  powerpc: remove virq_to_host
  powerpc: make IRQ_NOREQUEST last to clear, first to set

My vision is irq_host (or irq_domain) becomes a small wrapper layer
around the irq_desc layer.  irq_host details are not needed beyond
that layer; the irq_host is a opaque pointer.

Populating reverse mappings (hwirq to virq) will become part of the
irq_host layer and happen at create_irq or irq_alloc_virt.

The return value of the reverse map functions will be the irqdesc and
ppc_md.get_irq will return the irqdesc.  There is no reason to follow
up the radix tree lookup of hwirq to irq only to use that in another
radix-tree lookup to get the irqdesc that we need.  (The only remaining
user of NO_IRQ_IGNORE is iSeries, and that special return is the only
holdup.)

I already have patches that replace the irq_map.host pointer with a
per-irq_host NR_IRQ bitmap (but they are entangled with Grant's series
to switch to irq_alloc as the primary allocator).  As long as you have
fewer than BITS_PER_LONG irq_hosts that will be a win, and the only
path that might be slower is searching for the irq_host at unmap time.

For small irq count controllers that want to map all interrupts to
linux interrupts (including the legacy irq host), we can replace that
bitmap with an irq range.

The irq_host.hostdata field will become a parameter to alloc_irq_host,
and will be set as the irq's chip_data before calling ->map.  The map
routine is free to change this later (ps3 uses per-cpu data, xics now
uses the ics sub-ops as chipdata).  This allows a irq_host to have
several irq_chips for different flows but a driver can have multiple
irq_hosts for multiple instances of a given chip, distinguished
by chip_data.

My current thinking is the device node pointer stored in the host will
become generic match data, still used by the of wrapper to irq_domains
as a device node for default matching.  Both the match data and the
chip data will be availible to the match routine.  (This allows us to
keep the default of device node = match data without standardizing
a match struct inside each irq_hosts chipdata that we have to undo
every irq).

After doing a bunch of grep's on arch/sh, I think the interesting
parts of super8 interrupt handling that Thomas referred to are in
drivers/sh/intc.  For some reason they populate the radix tree first
with a descriptor of their common interrupt controler abstraction
then walk the tree, replacing the tagged elements with the pointer
to their equivalent to irq_map.  I do not yet understand the purpose
of this two phase allocation.

All patches are being sent to linuxppc-dev, a few have additional
cc's.

All patches were compiled for 3 configs: a smp 32 bit classic, a 32
bit book-e smp, and a 64 bit server, each had most platforms enabled.
I restricted many of my grep searches to arch/powerpc.   I boot tested
using bml.

 arch/powerpc/include/asm/dbell.h                 |    3 +-
 arch/powerpc/include/asm/irq.h                   |    5 +-
 arch/powerpc/include/asm/machdep.h               |   21 ----
 arch/powerpc/include/asm/smp.h                   |   33 +++++-
 arch/powerpc/include/asm/system.h                |    2 -
 arch/powerpc/include/asm/xics.h                  |    2 +-
 arch/powerpc/kernel/crash.c                      |    2 +-
 arch/powerpc/kernel/dbell.c                      |   65 ++----------
 arch/powerpc/kernel/head_64.S                    |   13 ++-
 arch/powerpc/kernel/irq.c                        |  112 ++++----------------
 arch/powerpc/kernel/kgdb.c                       |    2 +-
 arch/powerpc/kernel/misc_64.S                    |   13 ++-
 arch/powerpc/kernel/paca.c                       |   17 +--
 arch/powerpc/kernel/pci_dn.c                     |    3 +-
 arch/powerpc/kernel/setup-common.c               |   14 ++--
 arch/powerpc/kernel/smp.c                        |  118 ++++++++++++++-------
 arch/powerpc/lib/alloc.c                         |    8 --
 arch/powerpc/platforms/512x/mpc5121_ads_cpld.c   |    6 +-
 arch/powerpc/platforms/52xx/mpc52xx_pic.c        |    4 +-
 arch/powerpc/platforms/82xx/pq2ads-pci-pic.c     |    8 --
 arch/powerpc/platforms/85xx/smp.c                |    6 +-
 arch/powerpc/platforms/Kconfig                   |   11 ++-
 arch/powerpc/platforms/Kconfig.cputype           |    2 +
 arch/powerpc/platforms/cell/Makefile             |    1 -
 arch/powerpc/platforms/cell/axon_msi.c           |    3 +-
 arch/powerpc/platforms/cell/beat_interrupt.c     |   27 -----
 arch/powerpc/platforms/cell/beat_interrupt.h     |    3 -
 arch/powerpc/platforms/cell/beat_smp.c           |  123 ----------------------
 arch/powerpc/platforms/cell/celleb_pci.c         |    6 +-
 arch/powerpc/platforms/cell/celleb_setup.c       |    4 -
 arch/powerpc/platforms/cell/interrupt.c          |   27 ++----
 arch/powerpc/platforms/cell/smp.c                |   18 +---
 arch/powerpc/platforms/cell/spider-pic.c         |   13 ++-
 arch/powerpc/platforms/embedded6xx/flipper-pic.c |    7 --
 arch/powerpc/platforms/embedded6xx/hlwd-pic.c    |    7 --
 arch/powerpc/platforms/iseries/Kconfig           |    1 +
 arch/powerpc/platforms/iseries/exception.S       |   59 ++++++----
 arch/powerpc/platforms/iseries/irq.c             |    3 +-
 arch/powerpc/platforms/iseries/setup.c           |    5 +
 arch/powerpc/platforms/iseries/smp.c             |   39 +-------
 arch/powerpc/platforms/iseries/smp.h             |    6 -
 arch/powerpc/platforms/powermac/Kconfig          |   11 ++-
 arch/powerpc/platforms/powermac/pic.c            |   13 +--
 arch/powerpc/platforms/powermac/pic.h            |   11 --
 arch/powerpc/platforms/powermac/pmac.h           |    1 +
 arch/powerpc/platforms/powermac/smp.c            |   87 +++++++++-------
 arch/powerpc/platforms/ps3/interrupt.c           |    6 -
 arch/powerpc/platforms/ps3/smp.c                 |   22 +----
 arch/powerpc/platforms/pseries/smp.c             |    3 +-
 arch/powerpc/sysdev/fsl_msi.c                    |   10 +-
 arch/powerpc/sysdev/i8259.c                      |   13 ---
 arch/powerpc/sysdev/mpic.c                       |   52 +++-------
 arch/powerpc/sysdev/xics/icp-hv.c                |   26 +----
 arch/powerpc/sysdev/xics/icp-native.c            |   26 +----
 arch/powerpc/sysdev/xics/xics-common.c           |   42 ++------
 arch/powerpc/xmon/xmon.c                         |    2 +-
 include/linux/smp.h                              |   10 --
 57 files changed, 363 insertions(+), 794 deletions(-)
 delete mode 100644 arch/powerpc/platforms/cell/beat_smp.c
 delete mode 100644 arch/powerpc/platforms/iseries/smp.h
 delete mode 100644 arch/powerpc/platforms/powermac/pic.h

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 23/37] powerpc: radix trees are available before init_IRQ
  2011-05-11  5:29 ` [PATCH 23/37] powerpc: radix trees are available before init_IRQ Milton Miller
@ 2011-05-11 19:00   ` Grant Likely
  0 siblings, 0 replies; 51+ messages in thread
From: Grant Likely @ 2011-05-11 19:00 UTC (permalink / raw)
  To: Milton Miller; +Cc: Thomas Gleixner, linuxppc-dev

On Wed, May 11, 2011 at 7:29 AM, Milton Miller <miltonm@bga.com> wrote:
> Since the generic irq code uses a radix tree for sparse interrupts,
> the initcall ordering has been changed to initialize radix trees before
> irqs. =A0 We no longer need to defer creating revmap radix trees to the
> arch_initcall irq_late_init.
>
> Also, the kmem caches are allocated so we don't need to use
> zalloc_maybe_bootmem.
>
> Signed-off-by: Milton Miller <miltonm@bga.com>

w00t.  Looks right to me.

Reviewed-by: Grant Likely <grant.likely@secretlab.ca>

> ---
> =A0arch/powerpc/kernel/irq.c | =A0 78 ++---------------------------------=
---------
> =A01 files changed, 4 insertions(+), 74 deletions(-)
>
> diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
> index 826552c..f42e869 100644
> --- a/arch/powerpc/kernel/irq.c
> +++ b/arch/powerpc/kernel/irq.c
> @@ -493,7 +493,6 @@ struct irq_map_entry {
>
> =A0static LIST_HEAD(irq_hosts);
> =A0static DEFINE_RAW_SPINLOCK(irq_big_lock);
> -static unsigned int revmap_trees_allocated;
> =A0static DEFINE_MUTEX(revmap_trees_mutex);
> =A0static struct irq_map_entry irq_map[NR_IRQS];
> =A0static unsigned int irq_virq_count =3D NR_IRQS;
> @@ -537,7 +536,7 @@ struct irq_host *irq_alloc_host(struct device_node *o=
f_node,
> =A0 =A0 =A0 =A0/* Allocate structure and revmap table if using linear map=
ping */
> =A0 =A0 =A0 =A0if (revmap_type =3D=3D IRQ_HOST_MAP_LINEAR)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0size +=3D revmap_arg * sizeof(unsigned int=
);
> - =A0 =A0 =A0 host =3D zalloc_maybe_bootmem(size, GFP_KERNEL);
> + =A0 =A0 =A0 host =3D kzalloc(size, GFP_KERNEL);
> =A0 =A0 =A0 =A0if (host =3D=3D NULL)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return NULL;
>
> @@ -605,6 +604,9 @@ struct irq_host *irq_alloc_host(struct device_node *o=
f_node,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0smp_wmb();
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0host->revmap_data.linear.revmap =3D rmap;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break;
> + =A0 =A0 =A0 case IRQ_HOST_MAP_TREE:
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 INIT_RADIX_TREE(&host->revmap_data.tree, GF=
P_KERNEL);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 break;
> =A0 =A0 =A0 =A0default:
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break;
> =A0 =A0 =A0 =A0}
> @@ -839,13 +841,6 @@ void irq_dispose_mapping(unsigned int virq)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0host->revmap_data.linear.r=
evmap[hwirq] =3D NO_IRQ;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break;
> =A0 =A0 =A0 =A0case IRQ_HOST_MAP_TREE:
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 /*
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* Check if radix tree allocated yet, if =
not then nothing to
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* remove.
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*/
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 smp_rmb();
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (revmap_trees_allocated < 1)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 break;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0mutex_lock(&revmap_trees_mutex);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0radix_tree_delete(&host->revmap_data.tree,=
 hwirq);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0mutex_unlock(&revmap_trees_mutex);
> @@ -906,14 +901,6 @@ unsigned int irq_radix_revmap_lookup(struct irq_host=
 *host,
> =A0 =A0 =A0 =A0WARN_ON(host->revmap_type !=3D IRQ_HOST_MAP_TREE);
>
> =A0 =A0 =A0 =A0/*
> - =A0 =A0 =A0 =A0* Check if the radix tree exists and has bee initialized=
.
> - =A0 =A0 =A0 =A0* If not, we fallback to slow mode
> - =A0 =A0 =A0 =A0*/
> - =A0 =A0 =A0 if (revmap_trees_allocated < 2)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 return irq_find_mapping(host, hwirq);
> -
> - =A0 =A0 =A0 /* Now try to resolve */
> - =A0 =A0 =A0 /*
> =A0 =A0 =A0 =A0 * No rcu_read_lock(ing) needed, the ptr returned can't go=
 under us
> =A0 =A0 =A0 =A0 * as it's referencing an entry in the static irq_map tabl=
e.
> =A0 =A0 =A0 =A0 */
> @@ -935,18 +922,8 @@ unsigned int irq_radix_revmap_lookup(struct irq_host=
 *host,
> =A0void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 irq_hw_number_t h=
wirq)
> =A0{
> -
> =A0 =A0 =A0 =A0WARN_ON(host->revmap_type !=3D IRQ_HOST_MAP_TREE);
>
> - =A0 =A0 =A0 /*
> - =A0 =A0 =A0 =A0* Check if the radix tree exists yet.
> - =A0 =A0 =A0 =A0* If not, then the irq will be inserted into the tree wh=
en it gets
> - =A0 =A0 =A0 =A0* initialized.
> - =A0 =A0 =A0 =A0*/
> - =A0 =A0 =A0 smp_rmb();
> - =A0 =A0 =A0 if (revmap_trees_allocated < 1)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 return;
> -
> =A0 =A0 =A0 =A0if (virq !=3D NO_IRQ) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0mutex_lock(&revmap_trees_mutex);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0radix_tree_insert(&host->revmap_data.tree,=
 hwirq,
> @@ -1054,53 +1031,6 @@ int arch_early_irq_init(void)
> =A0 =A0 =A0 =A0return 0;
> =A0}
>
> -/* We need to create the radix trees late */
> -static int irq_late_init(void)
> -{
> - =A0 =A0 =A0 struct irq_host *h;
> - =A0 =A0 =A0 unsigned int i;
> -
> - =A0 =A0 =A0 /*
> - =A0 =A0 =A0 =A0* No mutual exclusion with respect to accessors of the t=
ree is needed
> - =A0 =A0 =A0 =A0* here as the synchronization is done via the state vari=
able
> - =A0 =A0 =A0 =A0* revmap_trees_allocated.
> - =A0 =A0 =A0 =A0*/
> - =A0 =A0 =A0 list_for_each_entry(h, &irq_hosts, link) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (h->revmap_type =3D=3D IRQ_HOST_MAP_TREE=
)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 INIT_RADIX_TREE(&h->revmap_=
data.tree, GFP_KERNEL);
> - =A0 =A0 =A0 }
> -
> - =A0 =A0 =A0 /*
> - =A0 =A0 =A0 =A0* Make sure the radix trees inits are visible before set=
ting
> - =A0 =A0 =A0 =A0* the flag
> - =A0 =A0 =A0 =A0*/
> - =A0 =A0 =A0 smp_wmb();
> - =A0 =A0 =A0 revmap_trees_allocated =3D 1;
> -
> - =A0 =A0 =A0 /*
> - =A0 =A0 =A0 =A0* Insert the reverse mapping for those interrupts alread=
y present
> - =A0 =A0 =A0 =A0* in irq_map[].
> - =A0 =A0 =A0 =A0*/
> - =A0 =A0 =A0 mutex_lock(&revmap_trees_mutex);
> - =A0 =A0 =A0 for (i =3D 0; i < irq_virq_count; i++) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (irq_map[i].host &&
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (irq_map[i].host->revmap_type =3D=
=3D IRQ_HOST_MAP_TREE))
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 radix_tree_insert(&irq_map[=
i].host->revmap_data.tree,
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 =A0 irq_map[i].hwirq, &irq_map[i]);
> - =A0 =A0 =A0 }
> - =A0 =A0 =A0 mutex_unlock(&revmap_trees_mutex);
> -
> - =A0 =A0 =A0 /*
> - =A0 =A0 =A0 =A0* Make sure the radix trees insertions are visible befor=
e setting
> - =A0 =A0 =A0 =A0* the flag
> - =A0 =A0 =A0 =A0*/
> - =A0 =A0 =A0 smp_wmb();
> - =A0 =A0 =A0 revmap_trees_allocated =3D 2;
> -
> - =A0 =A0 =A0 return 0;
> -}
> -arch_initcall(irq_late_init);
> -
> =A0#ifdef CONFIG_VIRQ_DEBUG
> =A0static int virq_debug_show(struct seq_file *m, void *private)
> =A0{
> --
> 1.7.0.4
>
>



--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 24/37] powerpc: return early if irq_host lookup type is wrong
  2011-05-11  5:29 ` [PATCH 24/37] powerpc: return early if irq_host lookup type is wrong Milton Miller
@ 2011-05-11 19:03   ` Grant Likely
  0 siblings, 0 replies; 51+ messages in thread
From: Grant Likely @ 2011-05-11 19:03 UTC (permalink / raw)
  To: Milton Miller; +Cc: Thomas Gleixner, linuxppc-dev

On Wed, May 11, 2011 at 7:29 AM, Milton Miller <miltonm@bga.com> wrote:
> If for some reason the code incrorectly calls the wrong function to
> manage the revmap, not only should we warn, we should take action.
> However, in the paths we expect to be taken every delivered interrupt
> change to WARN_ON_ONCE. =A0Use the if (WARN_ON(x)) format to get the
> unlikely for free.
>
> Signed-off-by: Milton Miller <miltonm@bga.com>

Looks right.

Reviewed-by: Grant Likely <grant.likely@secretlab.ca>

> ---
> =A0arch/powerpc/kernel/irq.c | =A0 12 +++++++-----
> =A01 files changed, 7 insertions(+), 5 deletions(-)
>
> diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
> index f42e869..4a5aa8c 100644
> --- a/arch/powerpc/kernel/irq.c
> +++ b/arch/powerpc/kernel/irq.c
> @@ -814,8 +814,7 @@ void irq_dispose_mapping(unsigned int virq)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return;
>
> =A0 =A0 =A0 =A0host =3D irq_map[virq].host;
> - =A0 =A0 =A0 WARN_ON (host =3D=3D NULL);
> - =A0 =A0 =A0 if (host =3D=3D NULL)
> + =A0 =A0 =A0 if (WARN_ON(host =3D=3D NULL))
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return;
>
> =A0 =A0 =A0 =A0/* Never unmap legacy interrupts */
> @@ -898,7 +897,8 @@ unsigned int irq_radix_revmap_lookup(struct irq_host =
*host,
> =A0 =A0 =A0 =A0struct irq_map_entry *ptr;
> =A0 =A0 =A0 =A0unsigned int virq;
>
> - =A0 =A0 =A0 WARN_ON(host->revmap_type !=3D IRQ_HOST_MAP_TREE);
> + =A0 =A0 =A0 if (WARN_ON_ONCE(host->revmap_type !=3D IRQ_HOST_MAP_TREE))
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return irq_find_mapping(host, hwirq);
>
> =A0 =A0 =A0 =A0/*
> =A0 =A0 =A0 =A0 * No rcu_read_lock(ing) needed, the ptr returned can't go=
 under us
> @@ -922,7 +922,8 @@ unsigned int irq_radix_revmap_lookup(struct irq_host =
*host,
> =A0void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 irq_hw_number_t h=
wirq)
> =A0{
> - =A0 =A0 =A0 WARN_ON(host->revmap_type !=3D IRQ_HOST_MAP_TREE);
> + =A0 =A0 =A0 if (WARN_ON(host->revmap_type !=3D IRQ_HOST_MAP_TREE))
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return;
>
> =A0 =A0 =A0 =A0if (virq !=3D NO_IRQ) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0mutex_lock(&revmap_trees_mutex);
> @@ -937,7 +938,8 @@ unsigned int irq_linear_revmap(struct irq_host *host,
> =A0{
> =A0 =A0 =A0 =A0unsigned int *revmap;
>
> - =A0 =A0 =A0 WARN_ON(host->revmap_type !=3D IRQ_HOST_MAP_LINEAR);
> + =A0 =A0 =A0 if (WARN_ON_ONCE(host->revmap_type !=3D IRQ_HOST_MAP_LINEAR=
))
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return irq_find_mapping(host, hwirq);
>
> =A0 =A0 =A0 =A0/* Check revmap bounds */
> =A0 =A0 =A0 =A0if (unlikely(hwirq >=3D host->revmap_data.linear.size))
> --
> 1.7.0.4
>
>



--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 27/37] powerpc fsl_msi: don't abuse platform_data for driver_data
  2011-05-11  5:30 ` [PATCH 27/37] powerpc fsl_msi: don't abuse platform_data for driver_data Milton Miller
@ 2011-05-11 19:05   ` Grant Likely
  0 siblings, 0 replies; 51+ messages in thread
From: Grant Likely @ 2011-05-11 19:05 UTC (permalink / raw)
  To: Milton Miller; +Cc: Thomas Gleixner, linuxppc-dev

On Wed, May 11, 2011 at 7:30 AM, Milton Miller <miltonm@bga.com> wrote:
> The msi platform device driver was abusing dev.platform_data for its
> platform_driver_data. =A0Use the correct pointer for storage.
>
> Platform_data is supposed to be for platforms to communicate to drivers
> parameters that are not otherwise discoverable. =A0Its lifetime matches
> the platform_device not the platform device driver. =A0It is generally
> not needed for drivers that only support systems with device trees.
>
> Signed-off-by: Milton Miller <miltonm@bga.com>

Acked-by: Grant Likely <grant.likely@secretlab.ca>

> ---
> ---
> =A0arch/powerpc/sysdev/fsl_msi.c | =A0 =A04 ++--
> =A01 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.=
c
> index d5679dc..077776c 100644
> --- a/arch/powerpc/sysdev/fsl_msi.c
> +++ b/arch/powerpc/sysdev/fsl_msi.c
> @@ -253,7 +253,7 @@ unlock:
>
> =A0static int fsl_of_msi_remove(struct platform_device *ofdev)
> =A0{
> - =A0 =A0 =A0 struct fsl_msi *msi =3D ofdev->dev.platform_data;
> + =A0 =A0 =A0 struct fsl_msi *msi =3D platform_get_drvdata(ofdev);
> =A0 =A0 =A0 =A0int virq, i;
> =A0 =A0 =A0 =A0struct fsl_msi_cascade_data *cascade_data;
>
> @@ -327,7 +327,7 @@ static int __devinit fsl_of_msi_probe(struct platform=
_device *dev)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0dev_err(&dev->dev, "No memory for MSI stru=
cture\n");
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return -ENOMEM;
> =A0 =A0 =A0 =A0}
> - =A0 =A0 =A0 dev->dev.platform_data =3D msi;
> + =A0 =A0 =A0 platform_set_drvdata(dev, msi);
>
> =A0 =A0 =A0 =A0msi->irqhost =3D irq_alloc_host(dev->dev.of_node, IRQ_HOST=
_MAP_LINEAR,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0NR_MSI_IRQS, &fsl_msi_host_ops, 0);
> --
> 1.7.0.4
>
>



--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 29/37] powerpc: mpc5121_ads_cpld: remove use of NO_IRQ_IGNORE
  2011-05-11  5:30 ` [PATCH 29/37] powerpc: mpc5121_ads_cpld: remove use of NO_IRQ_IGNORE Milton Miller
@ 2011-05-11 19:07   ` Grant Likely
  0 siblings, 0 replies; 51+ messages in thread
From: Grant Likely @ 2011-05-11 19:07 UTC (permalink / raw)
  To: Milton Miller; +Cc: Thomas Gleixner, linuxppc-dev

On Wed, May 11, 2011 at 7:30 AM, Milton Miller <miltonm@bga.com> wrote:
> As NO_IRQ_IGNORE is only used between the static function cpld_pic_get_ir=
q
> and its caller cpld_pic_cascade, and cpld_pic_cascade only uses it to
> suppress calling handle_generic_irq, we can change these uses to NO_IRQ
> and remove the extra tests and pathlength in cpld_pic_cascade.
>
> Signed-off-by: Milton Miller <miltonm@bga.com>

Acked-by: Grant Likely <grant.likely@secretlab.ca>

> ---
> ---
> =A0arch/powerpc/platforms/512x/mpc5121_ads_cpld.c | =A0 =A06 +++---
> =A01 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c b/arch/powerp=
c/platforms/512x/mpc5121_ads_cpld.c
> index a8bc0d4..9f09319 100644
> --- a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
> +++ b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
> @@ -97,7 +97,7 @@ cpld_pic_get_irq(int offset, u8 ignore, u8 __iomem *sta=
tusp,
> =A0 =A0 =A0 =A0status |=3D (ignore | mask);
>
> =A0 =A0 =A0 =A0if (status =3D=3D 0xff)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 return NO_IRQ_IGNORE;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return NO_IRQ;
>
> =A0 =A0 =A0 =A0cpld_irq =3D ffz(status) + offset;
>
> @@ -109,14 +109,14 @@ cpld_pic_cascade(unsigned int irq, struct irq_desc =
*desc)
> =A0{
> =A0 =A0 =A0 =A0irq =3D cpld_pic_get_irq(0, PCI_IGNORE, &cpld_regs->pci_st=
atus,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0&cpld_regs->pci_mask);
> - =A0 =A0 =A0 if (irq !=3D NO_IRQ && irq !=3D NO_IRQ_IGNORE) {
> + =A0 =A0 =A0 if (irq !=3D NO_IRQ) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0generic_handle_irq(irq);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return;
> =A0 =A0 =A0 =A0}
>
> =A0 =A0 =A0 =A0irq =3D cpld_pic_get_irq(8, MISC_IGNORE, &cpld_regs->misc_=
status,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0&cpld_regs->misc_mask);
> - =A0 =A0 =A0 if (irq !=3D NO_IRQ && irq !=3D NO_IRQ_IGNORE) {
> + =A0 =A0 =A0 if (irq !=3D NO_IRQ) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0generic_handle_irq(irq);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return;
> =A0 =A0 =A0 =A0}
> --
> 1.7.0.4
>
>



--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 30/37] powerpc: mpc62xx_pic: fix get_irq handling of NO_IRQ
  2011-05-11  5:30 ` [PATCH 30/37] powerpc: mpc62xx_pic: fix get_irq handling of NO_IRQ Milton Miller
@ 2011-05-11 19:08   ` Grant Likely
  0 siblings, 0 replies; 51+ messages in thread
From: Grant Likely @ 2011-05-11 19:08 UTC (permalink / raw)
  To: Milton Miller; +Cc: Thomas Gleixner, linuxppc-dev

On Wed, May 11, 2011 at 7:30 AM, Milton Miller <miltonm@bga.com> wrote:
> If none of irq category bits were set mpc52xx_get_irq() would pass
> NO_IRQ_IGNORE (-1) to irq_linear_revmap, which does an unsigned compare
> and declares the interrupt above the linear map range. =A0It then punts
> to irq_find_mapping, which performs a linear search of all irqs,
> which will likely miss and only then return NO_IRQ.
>
> If no status bit is set, then we should return NO_IRQ directly.
> The interrupt should not be suppressed from spurious counting, in fact
> that is the definition of supurious.
>
> Signed-off-by: Milton Miller <miltonm@bga.com>

Acked-by: Grant Likely <grant.likely@secretlab.ca>

> ---
> ---
> =A0arch/powerpc/platforms/52xx/mpc52xx_pic.c | =A0 =A04 +++-
> =A01 files changed, 3 insertions(+), 1 deletions(-)
>
> diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/pla=
tforms/52xx/mpc52xx_pic.c
> index bb61181..1a9a495 100644
> --- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
> +++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
> @@ -486,7 +486,7 @@ void __init mpc52xx_init_irq(void)
> =A0unsigned int mpc52xx_get_irq(void)
> =A0{
> =A0 =A0 =A0 =A0u32 status;
> - =A0 =A0 =A0 int irq =3D NO_IRQ_IGNORE;
> + =A0 =A0 =A0 int irq;
>
> =A0 =A0 =A0 =A0status =3D in_be32(&intr->enc_status);
> =A0 =A0 =A0 =A0if (status & 0x00000400) { =A0 =A0 =A0/* critical */
> @@ -509,6 +509,8 @@ unsigned int mpc52xx_get_irq(void)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} else {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0irq |=3D (MPC52xx_IRQ_L1_P=
ERP << MPC52xx_IRQ_L1_OFFSET);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0}
> + =A0 =A0 =A0 } else {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return NO_IRQ;
> =A0 =A0 =A0 =A0}
>
> =A0 =A0 =A0 =A0return irq_linear_revmap(mpc52xx_irqhost, irq);
> --
> 1.7.0.4
>
>



--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 33/37] powerpc: spider-pic: get pic from chip_data instead of irq_map
  2011-05-11  5:30 ` [PATCH 33/37] powerpc: spider-pic: get pic from chip_data instead of irq_map Milton Miller
@ 2011-05-11 19:13   ` Grant Likely
  0 siblings, 0 replies; 51+ messages in thread
From: Grant Likely @ 2011-05-11 19:13 UTC (permalink / raw)
  To: Milton Miller; +Cc: Thomas Gleixner, linuxppc-dev

On Wed, May 11, 2011 at 7:30 AM, Milton Miller <miltonm@bga.com> wrote:
> Building on Grant's efforts to remove the irq_map array, this patch
> moves spider-pics use of virq_to_host() to use irq_data_get_chip_data
> and sets the irq chip data in the map call, like most other interrupt
> controllers in powerpc.

Looks good to me.

g.

>
> Signed-off-by: Milton Miller <miltonm@bga.com>
> ---
> ---
> =A0arch/powerpc/platforms/cell/spider-pic.c | =A0 13 +++++++------
> =A01 files changed, 7 insertions(+), 6 deletions(-)
>
> diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/plat=
forms/cell/spider-pic.c
> index 34d2b99..442c28c 100644
> --- a/arch/powerpc/platforms/cell/spider-pic.c
> +++ b/arch/powerpc/platforms/cell/spider-pic.c
> @@ -68,9 +68,9 @@ struct spider_pic {
> =A0};
> =A0static struct spider_pic spider_pics[SPIDER_CHIP_COUNT];
>
> -static struct spider_pic *spider_virq_to_pic(unsigned int virq)
> +static struct spider_pic *spider_irq_data_to_pic(struct irq_data *d)
> =A0{
> - =A0 =A0 =A0 return virq_to_host(virq)->host_data;
> + =A0 =A0 =A0 return irq_data_get_irq_chip_data(d);
> =A0}
>
> =A0static void __iomem *spider_get_irq_config(struct spider_pic *pic,
> @@ -81,7 +81,7 @@ static void __iomem *spider_get_irq_config(struct spide=
r_pic *pic,
>
> =A0static void spider_unmask_irq(struct irq_data *d)
> =A0{
> - =A0 =A0 =A0 struct spider_pic *pic =3D spider_virq_to_pic(d->irq);
> + =A0 =A0 =A0 struct spider_pic *pic =3D spider_irq_data_to_pic(d);
> =A0 =A0 =A0 =A0void __iomem *cfg =3D spider_get_irq_config(pic, irqd_to_h=
wirq(d));
>
> =A0 =A0 =A0 =A0out_be32(cfg, in_be32(cfg) | 0x30000000u);
> @@ -89,7 +89,7 @@ static void spider_unmask_irq(struct irq_data *d)
>
> =A0static void spider_mask_irq(struct irq_data *d)
> =A0{
> - =A0 =A0 =A0 struct spider_pic *pic =3D spider_virq_to_pic(d->irq);
> + =A0 =A0 =A0 struct spider_pic *pic =3D spider_irq_data_to_pic(d);
> =A0 =A0 =A0 =A0void __iomem *cfg =3D spider_get_irq_config(pic, irqd_to_h=
wirq(d));
>
> =A0 =A0 =A0 =A0out_be32(cfg, in_be32(cfg) & ~0x30000000u);
> @@ -97,7 +97,7 @@ static void spider_mask_irq(struct irq_data *d)
>
> =A0static void spider_ack_irq(struct irq_data *d)
> =A0{
> - =A0 =A0 =A0 struct spider_pic *pic =3D spider_virq_to_pic(d->irq);
> + =A0 =A0 =A0 struct spider_pic *pic =3D spider_irq_data_to_pic(d);
> =A0 =A0 =A0 =A0unsigned int src =3D irqd_to_hwirq(d);
>
> =A0 =A0 =A0 =A0/* Reset edge detection logic if necessary
> @@ -116,7 +116,7 @@ static void spider_ack_irq(struct irq_data *d)
> =A0static int spider_set_irq_type(struct irq_data *d, unsigned int type)
> =A0{
> =A0 =A0 =A0 =A0unsigned int sense =3D type & IRQ_TYPE_SENSE_MASK;
> - =A0 =A0 =A0 struct spider_pic *pic =3D spider_virq_to_pic(d->irq);
> + =A0 =A0 =A0 struct spider_pic *pic =3D spider_irq_data_to_pic(d);
> =A0 =A0 =A0 =A0unsigned int hw =3D irqd_to_hwirq(d);
> =A0 =A0 =A0 =A0void __iomem *cfg =3D spider_get_irq_config(pic, hw);
> =A0 =A0 =A0 =A0u32 old_mask;
> @@ -171,6 +171,7 @@ static struct irq_chip spider_pic =3D {
> =A0static int spider_host_map(struct irq_host *h, unsigned int virq,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0irq_hw_number_t hw)
> =A0{
> + =A0 =A0 =A0 irq_set_chip_data(virq, h->host_data);
> =A0 =A0 =A0 =A0irq_set_chip_and_handler(virq, &spider_pic, handle_level_i=
rq);
>
> =A0 =A0 =A0 =A0/* Set default irq type */
> --
> 1.7.0.4
>
>



--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 35/37] powerpc: add virq_is_host to reduce virq_to_host usage
  2011-05-11  5:30 ` [PATCH 35/37] powerpc: add virq_is_host to reduce virq_to_host usage Milton Miller
@ 2011-05-11 19:16   ` Grant Likely
  0 siblings, 0 replies; 51+ messages in thread
From: Grant Likely @ 2011-05-11 19:16 UTC (permalink / raw)
  To: Milton Miller; +Cc: Thomas Gleixner, linuxppc-dev

On Wed, May 11, 2011 at 7:30 AM, Milton Miller <miltonm@bga.com> wrote:
> Some irq_host implementations are using virq_to_host to check if
> they are the irq_host for a virtual irq. =A0To allow us to make space
> versus time tradeoffs, replace this usage with an assertive
> virq_is_host that confirms or denies the irq is associated with the
> given irq_host.
>
> Signed-off-by: Milton Miller <miltonm@bga.com>

Acked-by: Grant Likely <grant.likely@secretlab.ca>

> ---
> =A0arch/powerpc/include/asm/irq.h =A0 =A0 =A0 =A0 | =A0 =A01 +
> =A0arch/powerpc/kernel/irq.c =A0 =A0 =A0 =A0 =A0 =A0 =A0| =A0 =A06 ++++++
> =A0arch/powerpc/sysdev/xics/xics-common.c | =A0 =A02 +-
> =A03 files changed, 8 insertions(+), 1 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/ir=
q.h
> index 6f4a3ef..a65d170 100644
> --- a/arch/powerpc/include/asm/irq.h
> +++ b/arch/powerpc/include/asm/irq.h
> @@ -128,6 +128,7 @@ struct irq_host {
> =A0struct irq_data;
> =A0extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d);
> =A0extern irq_hw_number_t virq_to_hw(unsigned int virq);
> +extern bool virq_is_host(unsigned int virq, struct irq_host *host);
> =A0extern struct irq_host *virq_to_host(unsigned int virq);
>
> =A0/**
> diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
> index 0715a09..73cf290 100644
> --- a/arch/powerpc/kernel/irq.c
> +++ b/arch/powerpc/kernel/irq.c
> @@ -510,6 +510,12 @@ irq_hw_number_t virq_to_hw(unsigned int virq)
> =A0}
> =A0EXPORT_SYMBOL_GPL(virq_to_hw);
>
> +bool virq_is_host(unsigned int virq, struct irq_host *host)
> +{
> + =A0 =A0 =A0 return irq_map[virq].host =3D=3D host;
> +}
> +EXPORT_SYMBOL_GPL(virq_is_host);
> +
> =A0struct irq_host *virq_to_host(unsigned int virq)
> =A0{
> =A0 =A0 =A0 =A0return irq_map[virq].host;
> diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev=
/xics/xics-common.c
> index 43b2a79..445c5a0 100644
> --- a/arch/powerpc/sysdev/xics/xics-common.c
> +++ b/arch/powerpc/sysdev/xics/xics-common.c
> @@ -213,7 +213,7 @@ void xics_migrate_irqs_away(void)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* We can't set affinity on ISA interrupts=
 */
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (virq < NUM_ISA_INTERRUPTS)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0continue;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (virq_to_host(virq) !=3D xics_host)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!virq_is_host(virq, xics_host))
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0continue;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0irq =3D (unsigned int)virq_to_hw(virq);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* We need to get IPIs still. */
> --
> 1.7.0.4
>
>



--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 36/37] powerpc: remove virq_to_host
  2011-05-11  5:30 ` [PATCH 36/37] powerpc: remove virq_to_host Milton Miller
@ 2011-05-11 19:17   ` Grant Likely
  0 siblings, 0 replies; 51+ messages in thread
From: Grant Likely @ 2011-05-11 19:17 UTC (permalink / raw)
  To: Milton Miller; +Cc: Thomas Gleixner, linuxppc-dev

On Wed, May 11, 2011 at 7:30 AM, Milton Miller <miltonm@bga.com> wrote:
> The only references to the irq_map[].host field are internal to
> arch/powerpc/kernel/irq.c
>
> Signed-off-by: Milton Miller <miltonm@bga.com>

Acked-by: Grant Likely <grant.likely@secretlab.ca>

> ---
> ---
> =A0arch/powerpc/include/asm/irq.h | =A0 =A01 -
> =A0arch/powerpc/kernel/irq.c =A0 =A0 =A0| =A0 =A06 ------
> =A02 files changed, 0 insertions(+), 7 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/ir=
q.h
> index a65d170..1bff591 100644
> --- a/arch/powerpc/include/asm/irq.h
> +++ b/arch/powerpc/include/asm/irq.h
> @@ -129,7 +129,6 @@ struct irq_data;
> =A0extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d);
> =A0extern irq_hw_number_t virq_to_hw(unsigned int virq);
> =A0extern bool virq_is_host(unsigned int virq, struct irq_host *host);
> -extern struct irq_host *virq_to_host(unsigned int virq);
>
> =A0/**
> =A0* irq_alloc_host - Allocate a new irq_host data structure
> diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
> index 73cf290..4368b5e 100644
> --- a/arch/powerpc/kernel/irq.c
> +++ b/arch/powerpc/kernel/irq.c
> @@ -516,12 +516,6 @@ bool virq_is_host(unsigned int virq, struct irq_host=
 *host)
> =A0}
> =A0EXPORT_SYMBOL_GPL(virq_is_host);
>
> -struct irq_host *virq_to_host(unsigned int virq)
> -{
> - =A0 =A0 =A0 return irq_map[virq].host;
> -}
> -EXPORT_SYMBOL_GPL(virq_to_host);
> -
> =A0static int default_irq_host_match(struct irq_host *h, struct device_no=
de *np)
> =A0{
> =A0 =A0 =A0 =A0return h->of_node !=3D NULL && h->of_node =3D=3D np;
> --
> 1.7.0.4
>
>



--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 37/37] powerpc: make IRQ_NOREQUEST last to clear, first to set
  2011-05-11  5:30 ` [PATCH 37/37] powerpc: make IRQ_NOREQUEST last to clear, first to set Milton Miller
@ 2011-05-11 19:18   ` Grant Likely
  2011-05-12  8:31     ` Milton Miller
  0 siblings, 1 reply; 51+ messages in thread
From: Grant Likely @ 2011-05-11 19:18 UTC (permalink / raw)
  To: Milton Miller; +Cc: Thomas Gleixner, linuxppc-dev

On Wed, May 11, 2011 at 7:30 AM, Milton Miller <miltonm@bga.com> wrote:
> When allocating irqs, wait to clear the IRQ_NOREQUEST flag until the
> host map hook has been called.
>
> When freeing irqs, set the IRQ_NOREQUEST flag before calling the host
> unmap hook.

A description describing why this change is being made would be
appreciated here.

g.

>
> Signed-off-by: Milton Miller <miltonm@bga.com>
> ---
> =A0arch/powerpc/kernel/irq.c | =A0 14 +++++++-------
> =A01 files changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
> index 4368b5e..a24d37d 100644
> --- a/arch/powerpc/kernel/irq.c
> +++ b/arch/powerpc/kernel/irq.c
> @@ -586,14 +586,14 @@ struct irq_host *irq_alloc_host(struct device_node =
*of_node,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0irq_map[i].host =3D host;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0smp_wmb();
>
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* Clear norequest flags */
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 irq_clear_status_flags(i, I=
RQ_NOREQUEST);
> -
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* Legacy flags are left t=
o default at this point,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 * one can then use irq_cr=
eate_mapping() to
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 * explicitly change them
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 */
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0ops->map(host, i, i);
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* Clear norequest flags */
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 irq_clear_status_flags(i, I=
RQ_NOREQUEST);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0}
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break;
> =A0 =A0 =A0 =A0case IRQ_HOST_MAP_LINEAR:
> @@ -664,8 +664,6 @@ static int irq_setup_virq(struct irq_host *host, unsi=
gned int virq,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0goto error;
> =A0 =A0 =A0 =A0}
>
> - =A0 =A0 =A0 irq_clear_status_flags(virq, IRQ_NOREQUEST);
> -
> =A0 =A0 =A0 =A0/* map it */
> =A0 =A0 =A0 =A0smp_wmb();
> =A0 =A0 =A0 =A0irq_map[virq].hwirq =3D hwirq;
> @@ -676,6 +674,8 @@ static int irq_setup_virq(struct irq_host *host, unsi=
gned int virq,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0goto errdesc;
> =A0 =A0 =A0 =A0}
>
> + =A0 =A0 =A0 irq_clear_status_flags(virq, IRQ_NOREQUEST);
> +
> =A0 =A0 =A0 =A0return 0;
>
> =A0errdesc:
> @@ -819,6 +819,8 @@ void irq_dispose_mapping(unsigned int virq)
> =A0 =A0 =A0 =A0if (host->revmap_type =3D=3D IRQ_HOST_MAP_LEGACY)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return;
>
> + =A0 =A0 =A0 irq_set_status_flags(virq, IRQ_NOREQUEST);
> +
> =A0 =A0 =A0 =A0/* remove chip and handler */
> =A0 =A0 =A0 =A0irq_set_chip_and_handler(virq, NULL, NULL);
>
> @@ -848,8 +850,6 @@ void irq_dispose_mapping(unsigned int virq)
> =A0 =A0 =A0 =A0smp_mb();
> =A0 =A0 =A0 =A0irq_map[virq].hwirq =3D host->inval_irq;
>
> - =A0 =A0 =A0 irq_set_status_flags(virq, IRQ_NOREQUEST);
> -
> =A0 =A0 =A0 =A0irq_free_descs(virq, 1);
> =A0 =A0 =A0 =A0/* Free it */
> =A0 =A0 =A0 =A0irq_free_virt(virq, 1);
> --
> 1.7.0.4
>
>



--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code
  2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
                   ` (36 preceding siblings ...)
  2011-05-11  5:30 ` [PATCH 37/37] powerpc: make IRQ_NOREQUEST last to clear, first to set Milton Miller
@ 2011-05-11 19:40 ` Grant Likely
  37 siblings, 0 replies; 51+ messages in thread
From: Grant Likely @ 2011-05-11 19:40 UTC (permalink / raw)
  To: Milton Miller; +Cc: Thomas Gleixner, linuxppc-dev

On Wed, May 11, 2011 at 7:43 AM, Milton Miller <miltonm@bga.com> wrote:
[...]
> After doing a bunch of grep's on arch/sh, I think the interesting
> parts of super8 interrupt handling that Thomas referred to are in
> drivers/sh/intc. =A0For some reason they populate the radix tree first
> with a descriptor of their common interrupt controler abstraction
> then walk the tree, replacing the tagged elements with the pointer
> to their equivalent to irq_map. =A0I do not yet understand the purpose
> of this two phase allocation.

BTW, you can also write a patch now that eliminates irq_map entirely.
I just talked to tglx today and we agree in principle to move the
hwirq value and irq_domain pointer directly into irq_data (and hence
directly accessible from the irq_desc).  The final form of irq_domain
is still up in the air, but you could do an initial patch that leaves
it as platform defined, and it can be followed up with a patch series
that creates a common irq_domain definition.

g.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 37/37] powerpc: make IRQ_NOREQUEST last to clear, first to set
  2011-05-11 19:18   ` Grant Likely
@ 2011-05-12  8:31     ` Milton Miller
  0 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-05-12  8:31 UTC (permalink / raw)
  To: Grant Likely; +Cc: Thomas Gleixner, linuxppc-dev

On Wed, 11 May 2011 about 21:18:11 +0200, Grant Likely wrote:
> On Wed, May 11, 2011 at 7:30 AM, Milton Miller <miltonm@bga.com> wrote:
> > When allocating irqs, wait to clear the IRQ_NOREQUEST flag until the
> > host map hook has been called.
> >
> > When freeing irqs, set the IRQ_NOREQUEST flag before calling the host
> > unmap hook.
> 
> A description describing why this change is being made would be
> appreciated here.
> 
> g.

You are right.  #insert <late addition to series but made cut>

When creating an irq, don't allow a concurent driver request until
we have caled map, which will likley call set_chip_and_handler to
change the irq_chip and its operations.

Similarly, when tearing down an IRQ, make sure no new uses come
along while we change the irq back to the nop chip and then reset
the descriptor to freed status.

If this is acceptable I'll let Ben update the changelog unless
he asks me to resend.

milton
> 
> >
> > Signed-off-by: Milton Miller <miltonm@bga.com>
> > ---
> > arch/powerpc/kernel/irq.c |  14 +++++++-------
> > 1 files changed, 7 insertions(+), 7 deletions(-)
> >
> > diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
> > index 4368b5e..a24d37d 100644
> > --- a/arch/powerpc/kernel/irq.c
> > +++ b/arch/powerpc/kernel/irq.c
> > @@ -586,14 +586,14 @@ struct irq_host *irq_alloc_host(struct device_node *of_node,
> >            irq_map[i].host = host;
> >            smp_wmb();
> >
> > -            /* Clear norequest flags */
> > -            irq_clear_status_flags(i, IRQ_NOREQUEST);
> > -
> >            /* Legacy flags are left to default at this point,
> >             * one can then use irq_create_mapping() to
> >             * explicitly change them
> >             */
> >            ops->map(host, i, i);
> > +
> > +            /* Clear norequest flags */
> > +            irq_clear_status_flags(i, IRQ_NOREQUEST);
> >        }
> >        break;
> >    case IRQ_HOST_MAP_LINEAR:
> > @@ -664,8 +664,6 @@ static int irq_setup_virq(struct irq_host *host, unsigned int virq,
> >        goto error;
> >    }
> >
> > -    irq_clear_status_flags(virq, IRQ_NOREQUEST);
> > -
> >    /* map it */
> >    smp_wmb();
> >    irq_map[virq].hwirq = hwirq;
> > @@ -676,6 +674,8 @@ static int irq_setup_virq(struct irq_host *host, unsigned int virq,
> >        goto errdesc;
> >    }
> >
> > +    irq_clear_status_flags(virq, IRQ_NOREQUEST);
> > +
> >    return 0;
> >
> > errdesc:
> > @@ -819,6 +819,8 @@ void irq_dispose_mapping(unsigned int virq)
> >    if (host->revmap_type == IRQ_HOST_MAP_LEGACY)
> >        return;
> >
> > +    irq_set_status_flags(virq, IRQ_NOREQUEST);
> > +
> >    /* remove chip and handler */
> >    irq_set_chip_and_handler(virq, NULL, NULL);
> >
> > @@ -848,8 +850,6 @@ void irq_dispose_mapping(unsigned int virq)
> >    smp_mb();
> >    irq_map[virq].hwirq = host->inval_irq;
> >
> > -    irq_set_status_flags(virq, IRQ_NOREQUEST);
> > -
> >    irq_free_descs(virq, 1);
> >    /* Free it */
> >    irq_free_virt(virq, 1);
> > --
> > 1.7.0.4
> >
> >

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 19/37] powerpc: consolidate ipi message mux and demux
  2011-05-11  5:29 ` [PATCH 19/37] powerpc: consolidate ipi message mux and demux Milton Miller
@ 2011-05-19  6:57   ` Benjamin Herrenschmidt
  2011-05-19  6:58     ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 51+ messages in thread
From: Benjamin Herrenschmidt @ 2011-05-19  6:57 UTC (permalink / raw)
  To: Milton Miller; +Cc: linuxppc-dev

On Wed, 2011-05-11 at 00:29 -0500, Milton Miller wrote:
> Consolidate the mux and demux of ipi messages into smp.c and call
> a new smp_ops callback to actually trigger the ipi.

 .../...

I'm merging the whole series.  I had to do some fixups to this one and
the one adding the CONFIG option, missing cell & wsp bits among others,
but mostly trivial.

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 19/37] powerpc: consolidate ipi message mux and demux
  2011-05-19  6:57   ` Benjamin Herrenschmidt
@ 2011-05-19  6:58     ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 51+ messages in thread
From: Benjamin Herrenschmidt @ 2011-05-19  6:58 UTC (permalink / raw)
  To: Milton Miller; +Cc: linuxppc-dev

On Thu, 2011-05-19 at 16:57 +1000, Benjamin Herrenschmidt wrote:
> On Wed, 2011-05-11 at 00:29 -0500, Milton Miller wrote:
> > Consolidate the mux and demux of ipi messages into smp.c and call
> > a new smp_ops callback to actually trigger the ipi.
> 
>  .../...
> 
> I'm merging the whole series.  I had to do some fixups to this one and
> the one adding the CONFIG option, missing cell & wsp bits among others,
> but mostly trivial.

I forgot to mention... I dropped the change to include/linux/smp.h to
remove the unused MSG_ flags for now. It will not have been in -next
long enough to hit Linus via my tree, just in case somebody started
using the flags while we were not looking :-)

I suggest you send it to Linus directly after he pulls my tree during
the merge window.

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 51+ messages in thread

end of thread, other threads:[~2011-05-19  6:58 UTC | newest]

Thread overview: 51+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-11  5:43 [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Milton Miller
2011-05-11  5:28 ` [PATCH 01/37] powerpc: fix memory corruption from unallocated slaves Milton Miller
2011-05-11  5:28 ` [PATCH 02/37] powerpc: don't search for paca in freed memory Milton Miller
2011-05-11  5:28 ` [PATCH 03/37] powerpc/kdump64: Don't reference freed memory as pacas Milton Miller
2011-05-11  5:28 ` [PATCH 04/37] powerpc/iseries: cleanup and fix secondary startup Milton Miller
2011-05-11  5:28 ` [PATCH 05/37] powerpc: Respect nr_cpu_ids when calling set_cpu_possible and set_cpu_present Milton Miller
2011-05-11  5:28 ` [PATCH 06/37] powerpc: use nr_cpu_ids in initial paca allocation Milton Miller
2011-05-11  5:28 ` [PATCH 07/37] powerpc: call no-longer static setup_nr_cpu_ids instead of replicating it Milton Miller
2011-05-11  5:28 ` [PATCH 08/37] powerpc: mpic: limit NR_CPUS loop to 32 bit Milton Miller
2011-05-11  5:29 ` [PATCH 09/37] powerpc: mpic: break cpumask abstraction earlier Milton Miller
2011-05-11  5:29 ` [PATCH 10/37] powerpc: remove call sites of MSG_ALL_BUT_SELF Milton Miller
2011-05-11  5:29 ` [PATCH 11/37] powerpc: remove checks for MSG_ALL and MSG_ALL_BUT_SELF Milton Miller
2011-05-11  5:29 ` [PATCH 12/37] linux/smp.h: remove unused MSG_ flags Milton Miller
2011-05-11  5:29 ` [PATCH 13/37] powerpc/mpic: simplify ipi cpu mask handling Milton Miller
2011-05-11  5:29 ` [PATCH 14/37] powerpc: remove powermac/pic.h Milton Miller
2011-05-11  5:29 ` [PATCH 15/37] powerpc: remove alloc_maybe_bootmem for zalloc version Milton Miller
2011-05-11  5:29 ` [PATCH 16/37] powerpc: remove stubbed beat smp support Milton Miller
2011-05-11  5:29 ` [PATCH 17/37] powerpc cell: use smp_request_message_ipi Milton Miller
2011-05-11  5:29 ` [PATCH 18/37] powerpc: move smp_ops_t from machdep.h to smp.h Milton Miller
2011-05-11  5:29 ` [PATCH 19/37] powerpc: consolidate ipi message mux and demux Milton Miller
2011-05-19  6:57   ` Benjamin Herrenschmidt
2011-05-19  6:58     ` Benjamin Herrenschmidt
2011-05-11  5:29 ` [PATCH 20/37] powerpc: add kconfig for muxed smp ipi support Milton Miller
2011-05-11  5:29 ` [PATCH 21/37] powerpc: use bytes instead of bitops in smp ipi multiplexing Milton Miller
2011-05-11  5:29 ` [PATCH 22/37] powerpc: xics: cleanup xics_host_map and ipi Milton Miller
2011-05-11  5:29 ` [PATCH 23/37] powerpc: radix trees are available before init_IRQ Milton Miller
2011-05-11 19:00   ` Grant Likely
2011-05-11  5:29 ` [PATCH 24/37] powerpc: return early if irq_host lookup type is wrong Milton Miller
2011-05-11 19:03   ` Grant Likely
2011-05-11  5:30 ` [PATCH 25/37] powerpc: remove trival irq_host_ops.unmap Milton Miller
2011-05-11  5:30 ` [PATCH 26/37] powerpc: remove i8259 irq_host_ops->unmap Milton Miller
2011-05-11  5:30 ` [PATCH 27/37] powerpc fsl_msi: don't abuse platform_data for driver_data Milton Miller
2011-05-11 19:05   ` Grant Likely
2011-05-11  5:30 ` [PATCH 28/37] powerpc: fsl_msi: use chip_data not handler_data Milton Miller
2011-05-11  5:30 ` [PATCH 29/37] powerpc: mpc5121_ads_cpld: remove use of NO_IRQ_IGNORE Milton Miller
2011-05-11 19:07   ` Grant Likely
2011-05-11  5:30 ` [PATCH 30/37] powerpc: mpc62xx_pic: fix get_irq handling of NO_IRQ Milton Miller
2011-05-11 19:08   ` Grant Likely
2011-05-11  5:30 ` [PATCH 31/37] powerpc: psurge: create a irq_host for secondary cpus Milton Miller
2011-05-11  5:30 ` [PATCH 32/37] powerpc: remove irq_host_ops->remap hook Milton Miller
2011-05-11  5:30 ` [PATCH 33/37] powerpc: spider-pic: get pic from chip_data instead of irq_map Milton Miller
2011-05-11 19:13   ` Grant Likely
2011-05-11  5:30 ` [PATCH 34/37] powerpc: axon_msi: validate msi irq via chip_data Milton Miller
2011-05-11  5:30 ` [PATCH 35/37] powerpc: add virq_is_host to reduce virq_to_host usage Milton Miller
2011-05-11 19:16   ` Grant Likely
2011-05-11  5:30 ` [PATCH 36/37] powerpc: remove virq_to_host Milton Miller
2011-05-11 19:17   ` Grant Likely
2011-05-11  5:30 ` [PATCH 37/37] powerpc: make IRQ_NOREQUEST last to clear, first to set Milton Miller
2011-05-11 19:18   ` Grant Likely
2011-05-12  8:31     ` Milton Miller
2011-05-11 19:40 ` [PATCH 00/37] fix paca memory usage and NR_CPU loops, factor ipi and simplify irq code Grant Likely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).