LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [RFC 0/2] Memoryless nodes and kworker
From: Tejun Heo @ 2014-07-18 18:58 UTC (permalink / raw)
  To: Nish Aravamudan
  Cc: Fenghua Yu, Tony Luck, linux-ia64, Nishanth Aravamudan,
	linux-kernel@vger.kernel.org, Linux Memory Management List,
	David Rientjes, Joonsoo Kim, linuxppc-dev, Jiang Liu, Wanpeng Li
In-Reply-To: <CAOhV88Mby_vrLPtRsRNO724-_ABEL06Fc1mMwjgq7LWw-uxeAw@mail.gmail.com>

Hello,

On Fri, Jul 18, 2014 at 11:47:08AM -0700, Nish Aravamudan wrote:
> Why are any callers of the format kthread_create_on_node(...,
> cpu_to_node(cpu), ...) not using kthread_create_on_cpu(..., cpu, ...)?

Ah, okay, that's because unbound workers are NUMA node affine, not
CPU.

> It seems like an additional reasonable approach would be to provide a
> suitable _cpu() API for the allocators. I'm not sure why saying that
> callers should know about NUMA (in order to call cpu_to_node() in every
> caller) is any better than saying that callers should know about memoryless
> nodes (in order to call cpu_to_mem() in every caller instead) -- when at

It is better because that's what they want to express - "I'm on this
memory node, please allocate memory on or close to this one".  That's
what the caller cares about.  Calling with cpu could be an option but
you'll eventually run into cases where you end up having to map back
NUMA node id to a CPU on it, which will probably feel at least a bit
silly.  There are things which really are per-NUMA node.

So, let's please express what needs to be expressed.  Massaging around
it can be useful at times but that doesn't seem to be the case here.

Thanks.

-- 
tejun

^ permalink raw reply

* Re: [PATCH v3] arm64, ia64, ppc, s390, sh, tile, um, x86, mm: Remove default gate area
From: H. Peter Anvin @ 2014-07-18 18:36 UTC (permalink / raw)
  To: Andy Lutomirski, Richard Weinberger, Andrew Morton
  Cc: linux-ia64@vger.kernel.org, linux-sh@vger.kernel.org,
	Catalin Marinas, Heiko Carstens, linux-mm@kvack.org,
	Paul Mackerras, linux-arch, linux-s390@vger.kernel.org, X86 ML,
	Ingo Molnar, Fenghua Yu,
	user-mode-linux-devel@lists.sourceforge.net, Will Deacon,
	Jeff Dike, Chris Metcalf, Thomas Gleixner,
	linux-arm-kernel@lists.infradead.org, Tony Luck, Nathan Lynch,
	linux-kernel@vger.kernel.org, Martin Schwidefsky,
	linux390@de.ibm.com, linuxppc-dev
In-Reply-To: <CALCETrXve-=N5yzqDw2YQee4BmC6sb8GYWYJcV2780V38OuJiQ@mail.gmail.com>

On 07/18/2014 09:53 AM, Andy Lutomirski wrote:
> 
> Splitting this will be annoying: I'd probably have to add a flag asking for
> the new behavior, update all the arches, then remove the flag.  The chance
> of screwing up bisectability in the process seems pretty high.  This seems
> like overkill for a patch that mostly deletes code.
> 
> Akpm, can you take this?
> 

I'm fine with it as-is.

Acked-by: H. Peter Anvin <hpa@linux.intel.com>

^ permalink raw reply

* [PATCH] Add support for hardware threads on e6500.
From: Scott Wood @ 2014-07-18 21:40 UTC (permalink / raw)
  To: linuxppc-dev

From: Andy Fleming <afleming@freescale.com>

The general idea is that each core will release all of its
threads into the secondary thread startup code, which will
eventually wait in the secondary core holding area, for the
appropriate bit in the PACA to be set. The kick_cpu function
pointer will set that bit in the PACA, and thus "release"
the core/thread to boot. We also need to do a few things that
U-Boot normally does for CPUs (like enable branch prediction).

Signed-off-by: Andy Fleming <afleming@freescale.com>
[scottwood@freescale.com: various changes, including only enabling
 threads if Linux wants to kick them]
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
 arch/powerpc/include/asm/cputable.h   |  2 +-
 arch/powerpc/include/asm/ppc-opcode.h |  9 ++++++++
 arch/powerpc/include/asm/reg_booke.h  | 27 ++++++++++++++++++++++
 arch/powerpc/kernel/head_64.S         | 22 ++++++++++++++++++
 arch/powerpc/kernel/prom.c            | 10 ++++-----
 arch/powerpc/kernel/setup-common.c    |  6 +++--
 arch/powerpc/kernel/setup_64.c        |  6 ++++-
 arch/powerpc/platforms/85xx/smp.c     | 42 +++++++++++++++++++++++++++++++++++
 8 files changed, 114 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index bc23477..e91dec8 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -396,7 +396,7 @@ extern const char *powerpc_base_platform;
 	    CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \
 	    CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
 	    CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV | CPU_FTR_ALTIVEC_COMP | \
-	    CPU_FTR_CELL_TB_BUG)
+	    CPU_FTR_CELL_TB_BUG | CPU_FTR_SMT)
 #define CPU_FTRS_GENERIC_32	(CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN)
 
 /* 64-bit CPUs */
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
index 3132bb9..e316dad 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -150,8 +150,10 @@
 #define PPC_INST_MCRXR_MASK		0xfc0007fe
 #define PPC_INST_MFSPR_PVR		0x7c1f42a6
 #define PPC_INST_MFSPR_PVR_MASK		0xfc1fffff
+#define PPC_INST_MFTMR			0x7c0002dc
 #define PPC_INST_MSGSND			0x7c00019c
 #define PPC_INST_MSGSNDP		0x7c00011c
+#define PPC_INST_MTTMR			0x7c0003dc
 #define PPC_INST_NOP			0x60000000
 #define PPC_INST_POPCNTB		0x7c0000f4
 #define PPC_INST_POPCNTB_MASK		0xfc0007fe
@@ -369,4 +371,11 @@
 #define TABORT(r)		stringify_in_c(.long PPC_INST_TABORT \
 					       | __PPC_RA(r))
 
+/* book3e thread control instructions */
+#define TMRN(x)			((((x) & 0x1f) << 16) | (((x) & 0x3e0) << 6))
+#define MTTMR(tmr, r)		stringify_in_c(.long PPC_INST_MTTMR | \
+					       TMRN(tmr) | ___PPC_RS(r))
+#define MFTMR(tmr, r)		stringify_in_c(.long PPC_INST_MFTMR | \
+					       TMRN(tmr) | ___PPC_RT(r))
+
 #endif /* _ASM_POWERPC_PPC_OPCODE_H */
diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h
index 6148292..cc5f395 100644
--- a/arch/powerpc/include/asm/reg_booke.h
+++ b/arch/powerpc/include/asm/reg_booke.h
@@ -15,6 +15,8 @@
 #ifndef __ASM_POWERPC_REG_BOOKE_H__
 #define __ASM_POWERPC_REG_BOOKE_H__
 
+#include <asm/ppc-opcode.h>
+
 /* Machine State Register (MSR) Fields */
 #define MSR_GS		(1<<28) /* Guest state */
 #define MSR_UCLE	(1<<26)	/* User-mode cache lock enable */
@@ -598,6 +600,13 @@
 /* Bit definitions for L1CSR2. */
 #define L1CSR2_DCWS	0x40000000	/* Data Cache write shadow */
 
+/* Bit definitions for BUCSR. */
+#define BUCSR_STAC_EN	0x01000000	/* Segment Target Address Cache */
+#define BUCSR_LS_EN	0x00400000	/* Link Stack */
+#define BUCSR_BBFI	0x00000200	/* Branch Buffer flash invalidate */
+#define BUCSR_BPEN	0x00000001	/* Branch prediction enable */
+#define BUCSR_INIT	(BUCSR_STAC_EN | BUCSR_LS_EN | BUCSR_BBFI | BUCSR_BPEN)
+
 /* Bit definitions for L2CSR0. */
 #define L2CSR0_L2E	0x80000000	/* L2 Cache Enable */
 #define L2CSR0_L2PE	0x40000000	/* L2 Cache Parity/ECC Enable */
@@ -721,5 +730,23 @@
 #define MMUBE1_VBE4		0x00000002
 #define MMUBE1_VBE5		0x00000001
 
+#define TMRN_IMSR0	0x120	/* Initial MSR Register 0 (e6500) */
+#define TMRN_IMSR1	0x121	/* Initial MSR Register 1 (e6500) */
+#define TMRN_INIA0	0x140	/* Next Instruction Address Register 0 */
+#define TMRN_INIA1	0x141	/* Next Instruction Address Register 1 */
+#define SPRN_TENSR	0x1b5	/* Thread Enable Status Register */
+#define SPRN_TENS	0x1b6	/* Thread Enable Set Register */
+#define SPRN_TENC	0x1b7	/* Thread Enable Clear Register */
+
+#define TEN_THREAD(x)	(1 << (x))
+
+#ifndef __ASSEMBLY__
+#define mftmr(rn)	({unsigned long rval; \
+			asm volatile(MFTMR(rn, %0) : "=r" (rval)); rval;})
+#define mttmr(rn, v)	asm volatile(MTTMR(rn, %0) : \
+				     : "r" ((unsigned long)(v)) \
+				     : "memory")
+#endif /* !__ASSEMBLY__ */
+
 #endif /* __ASM_POWERPC_REG_BOOKE_H__ */
 #endif /* __KERNEL__ */
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index a95145d..36ff6f0 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -180,6 +180,28 @@ exception_marker:
 #include "exceptions-64s.S"
 #endif
 
+#ifdef CONFIG_PPC_BOOK3E
+_GLOBAL(fsl_secondary_thread_init)
+	/* Enable branch prediction */
+	lis     r3,BUCSR_INIT@h
+	ori     r3,r3,BUCSR_INIT@l
+	mtspr   SPRN_BUCSR,r3
+	isync
+
+	/*
+	 * Fix PIR to match the linear numbering in the device tree.
+	 *
+	 * On e6500, the reset value of PIR uses the low three bits for
+	 * the thread within a core, and the upper bits for the core
+	 * number.  There are two threads per core, so shift everything
+	 * but the low bit right by two bits so that the cpu numbering is
+	 * continuous.
+	 */
+	mfspr	r3, SPRN_PIR
+	rlwimi	r3, r3, 30, 2, 30
+	mtspr	SPRN_PIR, r3
+#endif
+
 _GLOBAL(generic_secondary_thread_init)
 	mr	r24,r3
 
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 613a860..0448b1e 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -309,12 +309,10 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
 
 	/* Get physical cpuid */
 	intserv = of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s", &len);
-	if (intserv) {
-		nthreads = len / sizeof(int);
-	} else {
-		intserv = of_get_flat_dt_prop(node, "reg", NULL);
-		nthreads = 1;
-	}
+	if (!intserv)
+		intserv = of_get_flat_dt_prop(node, "reg", &len);
+
+	nthreads = len / sizeof(int);
 
 	/*
 	 * Now see if any of these threads match our boot cpu.
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index e5b022c..1b0e260 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -456,18 +456,20 @@ void __init smp_setup_cpu_maps(void)
 		intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s",
 				&len);
 		if (intserv) {
-			nthreads = len / sizeof(int);
 			DBG("    ibm,ppc-interrupt-server#s -> %d threads\n",
 			    nthreads);
 		} else {
 			DBG("    no ibm,ppc-interrupt-server#s -> 1 thread\n");
-			intserv = of_get_property(dn, "reg", NULL);
+			intserv = of_get_property(dn, "reg", &len);
 			if (!intserv) {
 				cpu_be = cpu_to_be32(cpu);
 				intserv = &cpu_be;	/* assume logical == phys */
+				len = 4;
 			}
 		}
 
+		nthreads = len / sizeof(int);
+
 		for (j = 0; j < nthreads && cpu < nr_cpu_ids; j++) {
 			bool avail;
 
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index ee082d7..6d06947 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -507,7 +507,11 @@ void __init setup_system(void)
 	check_smt_enabled();
 	setup_tlb_core_data();
 
-#ifdef CONFIG_SMP
+	/*
+	 * Freescale Book3e parts spin in a loop provided by firmware,
+	 * so smp_release_cpus() does nothing for them
+	 */
+#if defined(CONFIG_SMP) && !defined(CONFIG_PPC_FSL_BOOK3E)
 	/* Release secondary cpus out of their spinloops at 0x60 now that
 	 * we can map physical -> logical CPU ids
 	 */
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
index ba093f5..d7111d9 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -28,6 +28,7 @@
 #include <asm/dbell.h>
 #include <asm/fsl_guts.h>
 #include <asm/code-patching.h>
+#include <asm/cputhreads.h>
 
 #include <sysdev/fsl_soc.h>
 #include <sysdev/mpic.h>
@@ -168,6 +169,22 @@ static inline u32 read_spin_table_addr_l(void *spin_table)
 	return in_be32(&((struct epapr_spin_table *)spin_table)->addr_l);
 }
 
+static void wake_hw_thread(void *info)
+{
+	void fsl_secondary_thread_init(void);
+	unsigned long imsr1, inia1;
+	int nr = *(const int *)info;
+
+	imsr1 = (u32)MSR_KERNEL;
+	inia1 = *(unsigned long *)fsl_secondary_thread_init;
+
+	mttmr(TMRN_IMSR1, imsr1);
+	mttmr(TMRN_INIA1, inia1);
+	mtspr(SPRN_TENS, TEN_THREAD(1));
+
+	smp_generic_kick_cpu(nr);
+}
+
 static int smp_85xx_kick_cpu(int nr)
 {
 	unsigned long flags;
@@ -183,6 +200,31 @@ static int smp_85xx_kick_cpu(int nr)
 
 	pr_debug("smp_85xx_kick_cpu: kick CPU #%d\n", nr);
 
+#ifdef CONFIG_PPC64
+	/* Threads don't use the spin table */
+	if (cpu_thread_in_core(nr) != 0) {
+		int primary = cpu_first_thread_sibling(nr);
+
+		if (WARN_ON_ONCE(!cpu_has_feature(CPU_FTR_SMT)))
+			return -ENOENT;
+
+		if (cpu_thread_in_core(nr) != 1) {
+			pr_err("%s: cpu %d: invalid hw thread %d\n",
+			       __func__, nr, cpu_thread_in_core(nr));
+			return -ENOENT;
+		}
+
+		if (!cpu_online(primary)) {
+			pr_err("%s: cpu %d: primary %d not online\n",
+			       __func__, nr, primary);
+			return -ENOENT;
+		}
+
+		smp_call_function_single(primary, wake_hw_thread, &nr, 0);
+		return 0;
+	}
+#endif
+
 	np = of_get_cpu_node(nr, NULL);
 	cpu_rel_addr = of_get_property(np, "cpu-release-addr", NULL);
 
-- 
1.9.1

^ permalink raw reply related

* Re: [PATCH] powerpc: Add cputable definition for POWER8 DD1
From: Benjamin Herrenschmidt @ 2014-07-18 23:12 UTC (permalink / raw)
  To: Michael Neuling; +Cc: paulus, Joel Stanley, preeti, linuxppc-dev, anton
In-Reply-To: <1405660235.7952.5.camel@ale.ozlabs.ibm.com>

On Fri, 2014-07-18 at 15:10 +1000, Michael Neuling wrote:
> On Fri, 2014-07-18 at 11:41 +0930, Joel Stanley wrote:
> > These processors do not currently support doorbell IPIs, so remove them
> > from the feature list if we are at DD 1.xx for the 0x004d part.
> 
> We GAed with DD2.1 and generally we don't upstream anything that isn't
> GAed.  Plus, if you wanna go down this path, you are going to have to
> fix a lot more bugs than this one (not that our early chips had bugs or
> anything).  
> 
> I suggested you crush your crappy DD1 parts into cubes and ask for some
> shiny new DD2.1 parts.

This is Venice, not Murano. We are going to have some of these guys
out there with the initial batch of dev boards.

.../..

> Humm, well doorbells worked on DD1 so i'm not sure this is entirely your
> problem.  There was an issue related to powersave that Ian posted a fix
> for but we never needed it as the issue was fixed before GA.
> 
> http://patchwork.ozlabs.org/patch/240338/
> 
> So NAK again.

Actually he did what I asked him to do :-)

Between Ian's workaround and just disabling DB on DD1, I prefer just
disabling DB on DD1. The fix is more crappy obscure asm to carry around
and I think it might cause spurrious DBs on non-broken CPUs.

Cheers,
Ben.

> Mikey
> 
> > Fixes: d4e58e5928f8 (powerpc/powernv: Enable POWER8 doorbell IPIs)
> > Signed-off-by: Joel Stanley <joel@jms.id.au>
> > ---
> >  arch/powerpc/include/asm/cputable.h |  1 +
> >  arch/powerpc/kernel/cputable.c      | 20 ++++++++++++++++++++
> >  2 files changed, 21 insertions(+)
> > 
> > diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
> > index bc23477..0fdd7ee 100644
> > --- a/arch/powerpc/include/asm/cputable.h
> > +++ b/arch/powerpc/include/asm/cputable.h
> > @@ -447,6 +447,7 @@ extern const char *powerpc_base_platform;
> >  	    CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \
> >  	    CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP)
> >  #define CPU_FTRS_POWER8E (CPU_FTRS_POWER8 | CPU_FTR_PMAO_BUG)
> > +#define CPU_FTRS_POWER8_DD1 (CPU_FTRS_POWER8 & ~CPU_FTR_DBELL)
> >  #define CPU_FTRS_CELL	(CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
> >  	    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
> >  	    CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
> > diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
> > index 965291b..0c15764 100644
> > --- a/arch/powerpc/kernel/cputable.c
> > +++ b/arch/powerpc/kernel/cputable.c
> > @@ -527,6 +527,26 @@ static struct cpu_spec __initdata cpu_specs[] = {
> >  		.machine_check_early	= __machine_check_early_realmode_p8,
> >  		.platform		= "power8",
> >  	},
> > +	{	/* Power8 DD1: Does not support doorbell IPIs */
> > +		.pvr_mask		= 0xffffff00,
> > +		.pvr_value		= 0x004d0100,
> > +		.cpu_name		= "POWER8 (raw)",
> > +		.cpu_features		= CPU_FTRS_POWER8_DD1,
> > +		.cpu_user_features	= COMMON_USER_POWER8,
> > +		.cpu_user_features2	= COMMON_USER2_POWER8,
> > +		.mmu_features		= MMU_FTRS_POWER8,
> > +		.icache_bsize		= 128,
> > +		.dcache_bsize		= 128,
> > +		.num_pmcs		= 6,
> > +		.pmc_type		= PPC_PMC_IBM,
> > +		.oprofile_cpu_type	= "ppc64/power8",
> > +		.oprofile_type		= PPC_OPROFILE_INVALID,
> > +		.cpu_setup		= __setup_cpu_power8,
> > +		.cpu_restore		= __restore_cpu_power8,
> > +		.flush_tlb		= __flush_tlb_power8,
> > +		.machine_check_early	= __machine_check_early_realmode_p8,
> > +		.platform		= "power8",
> > +	},
> >  	{	/* Power8 */
> >  		.pvr_mask		= 0xffff0000,
> >  		.pvr_value		= 0x004d0000,

^ permalink raw reply

* [PATCH] powerpc: Fix bugs in emulate_step()
From: Paul Mackerras @ 2014-07-19  7:47 UTC (permalink / raw)
  To: linuxppc-dev

This fixes some bugs in emulate_step().  First, the setting of the carry
bit for the arithmetic right-shift instructions was not correct on 64-bit
machines because we were masking with a mask of type int rather than
unsigned long.  Secondly, the sld (shift left doubleword) instruction was
using the wrong instruction field for the register containing the shift
count.

Signed-off-by: Paul Mackerras <paulus@samba.org>
---
 arch/powerpc/lib/sstep.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index 412dd46..5c09f36 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -1198,7 +1198,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
 			sh = regs->gpr[rb] & 0x3f;
 			ival = (signed int) regs->gpr[rd];
 			regs->gpr[ra] = ival >> (sh < 32 ? sh : 31);
-			if (ival < 0 && (sh >= 32 || (ival & ((1 << sh) - 1)) != 0))
+			if (ival < 0 && (sh >= 32 || (ival & ((1ul << sh) - 1)) != 0))
 				regs->xer |= XER_CA;
 			else
 				regs->xer &= ~XER_CA;
@@ -1208,7 +1208,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
 			sh = rb;
 			ival = (signed int) regs->gpr[rd];
 			regs->gpr[ra] = ival >> sh;
-			if (ival < 0 && (ival & ((1 << sh) - 1)) != 0)
+			if (ival < 0 && (ival & ((1ul << sh) - 1)) != 0)
 				regs->xer |= XER_CA;
 			else
 				regs->xer &= ~XER_CA;
@@ -1216,7 +1216,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
 
 #ifdef __powerpc64__
 		case 27:	/* sld */
-			sh = regs->gpr[rd] & 0x7f;
+			sh = regs->gpr[rb] & 0x7f;
 			if (sh < 64)
 				regs->gpr[ra] = regs->gpr[rd] << sh;
 			else
@@ -1235,7 +1235,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
 			sh = regs->gpr[rb] & 0x7f;
 			ival = (signed long int) regs->gpr[rd];
 			regs->gpr[ra] = ival >> (sh < 64 ? sh : 63);
-			if (ival < 0 && (sh >= 64 || (ival & ((1 << sh) - 1)) != 0))
+			if (ival < 0 && (sh >= 64 || (ival & ((1ul << sh) - 1)) != 0))
 				regs->xer |= XER_CA;
 			else
 				regs->xer &= ~XER_CA;
@@ -1246,7 +1246,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
 			sh = rb | ((instr & 2) << 4);
 			ival = (signed long int) regs->gpr[rd];
 			regs->gpr[ra] = ival >> sh;
-			if (ival < 0 && (ival & ((1 << sh) - 1)) != 0)
+			if (ival < 0 && (ival & ((1ul << sh) - 1)) != 0)
 				regs->xer |= XER_CA;
 			else
 				regs->xer &= ~XER_CA;
-- 
2.0.1

^ permalink raw reply related

* [RESEND PATCH] powerpc/fsl-pci: Correct use of ! and &
From: Himangi Saraogi @ 2014-07-19 21:49 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, linuxppc-dev,
	linux-kernel
  Cc: julia.lawall

In commit ae91d60ba88ef0bdb1b5e9b2363bd52fc45d2af7, a bug was fixed that
involved converting !x & y to !(x & y).  The code below shows the same
pattern, and thus should perhaps be fixed in the same way.

This is not tested and clearly changes the semantics, so it is only
something to consider.

The Coccinelle semantic patch that makes this change is as follows:

// <smpl>
@@ expression E1,E2; @@
(
  !E1 & !E2
|
- !E1 & E2
+ !(E1 & E2)
)
// </smpl>

Signed-off-by: Himangi Saraogi <himangi774@gmail.com>
---
 arch/powerpc/sysdev/fsl_pci.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 4bd091a..c507767 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -853,8 +853,8 @@ u64 fsl_pci_immrbar_base(struct pci_controller *hose)
 		in = pcie->cfg_type0 + PEX_RC_INWIN_BASE;
 		for (i = 0; i < 4; i++) {
 			/* not enabled, skip */
-			if (!in_le32(&in[i].ar) & PEX_RCIWARn_EN)
-				 continue;
+			if (!(in_le32(&in[i].ar) & PEX_RCIWARn_EN))
+				continue;
 
 			if (get_immrbase() == in_le32(&in[i].tar))
 				return (u64)in_le32(&in[i].barh) << 32 |
-- 
1.9.1

^ permalink raw reply related

* [RESEND PATCH] powerpc/mpic_msgr: Use kcalloc and correct the argument to sizeof
From: Himangi Saraogi @ 2014-07-19 21:53 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, linuxppc-dev,
	linux-kernel
  Cc: julia.lawall

mpic_msgrs has type struct mpic_msgr **, not struct mpic_msgr *, so the
elements of the array should have pointer type, not structure type.
The advantage of kcalloc is, that will prevent integer overflows which
could result from the multiplication of number of elements and size and
it is also a bit nicer to read.

The Coccinelle semantic patch that makes the first change is as follows:

// <smpl>
@disable sizeof_type_expr@
type T;
T **x;
@@

  x =
  <+...sizeof(
- T
+ *x
  )...+>
// </smpl>

Signed-off-by: Himangi Saraogi <himangi774@gmail.com>
Acked-by: Julia Lawall <julia.lawall@lip6.fr>
---
 arch/powerpc/sysdev/mpic_msgr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/sysdev/mpic_msgr.c b/arch/powerpc/sysdev/mpic_msgr.c
index 2c9b52a..7bdf3cc 100644
--- a/arch/powerpc/sysdev/mpic_msgr.c
+++ b/arch/powerpc/sysdev/mpic_msgr.c
@@ -184,7 +184,7 @@ static int mpic_msgr_probe(struct platform_device *dev)
 		dev_info(&dev->dev, "Found %d message registers\n",
 				mpic_msgr_count);
 
-		mpic_msgrs = kzalloc(sizeof(struct mpic_msgr) * mpic_msgr_count,
+		mpic_msgrs = kcalloc(mpic_msgr_count, sizeof(*mpic_msgrs),
 							 GFP_KERNEL);
 		if (!mpic_msgrs) {
 			dev_err(&dev->dev,
-- 
1.9.1

^ permalink raw reply related

* [PATCH -next] powerpc: Fix return value check in hsta_msi_probe()
From: weiyj_lk @ 2014-07-20  7:20 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Grant Likely, Rob Herring,
	Alistair Popple
  Cc: Wei Yongjun, linuxppc-dev

From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>

In case of error, the function ioremap() returns NULL
not ERR_PTR(). The IS_ERR() test in the return value
check should be replaced with NULL test.


Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
---
 arch/powerpc/sysdev/ppc4xx_hsta_msi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/sysdev/ppc4xx_hsta_msi.c b/arch/powerpc/sysdev/ppc4xx_hsta_msi.c
index 11c8884..14c25c5 100644
--- a/arch/powerpc/sysdev/ppc4xx_hsta_msi.c
+++ b/arch/powerpc/sysdev/ppc4xx_hsta_msi.c
@@ -150,7 +150,7 @@ static int hsta_msi_probe(struct platform_device *pdev)
 	ppc4xx_hsta_msi.address = mem->start;
 	ppc4xx_hsta_msi.data = ioremap(mem->start, resource_size(mem));
 	ppc4xx_hsta_msi.irq_count = irq_count;
-	if (IS_ERR(ppc4xx_hsta_msi.data)) {
+	if (!ppc4xx_hsta_msi.data) {
 		dev_err(dev, "Unable to map memory\n");
 		return -ENOMEM;
 	}

^ permalink raw reply related

* [PATCH 00/30] drivers/net: remove unnecessary break after return
From: Fabian Frederick @ 2014-07-20 14:16 UTC (permalink / raw)
  To: linux-kernel
  Cc: brcm80211-dev-list, e1000-devel, netdev, linux-wireless,
	Fabian Frederick, joe, linuxppc-dev, davem

Second patchset after "remove unnecessary break after goto" addressing break redundancy on drivers/net branch
(suggested by Joe Perches)

Fabian Frederick (30):
  dlci: remove unnecessary break after return
  eth_v10: remove unnecessary break after return
  brcm80211: remove unnecessary break after return
  mwl8k: remove unnecessary break after return
  rtlwifi: remove unnecessary break after return
  rtlwifi: rtl8192ce: remove unnecessary break after return
  rtlwifi: rtl8192se: remove unnecessary break after return
  rtlwifi: rtl8723ae: remove unnecessary break after return
  rtlwifi: rtl8723be: remove unnecessary break after return
  rtlwifi: rtl8188ee: remove unnecessary break after return
  prism54: remove unnecessary break after return
  cw1200: remove unnecessary break after return
  airo: remove unnecessary break after return
  ath6kl: remove unnecessary break after return
  carl9170: remove unnecessary break after return
  i40e: remove unnecessary break after return
  e1000: remove unnecessary break after return
  ixgbe: remove unnecessary break after return
  e1000e: remove unnecessary break after return
  igb: remove unnecessary break after return
  8390: remove unnecessary break after return
  net: tulip: remove unnecessary break after return
  bna: remove unnecessary break after return
  sis900: remove unnecessary break after return
  niu: remove unnecessary break after return
  ucc_geth: remove unnecessary break after return
  atl1e: remove unnecessary break after return
  atlx: remove unnecessary break after return
  atl1c: remove unnecessary break after return
  ps3_gelic: remove unnecessary break after return

 drivers/net/cris/eth_v10.c                          | 1 -
 drivers/net/ethernet/8390/mac8390.c                 | 8 --------
 drivers/net/ethernet/atheros/atl1c/atl1c_hw.c       | 2 --
 drivers/net/ethernet/atheros/atl1e/atl1e_hw.c       | 1 -
 drivers/net/ethernet/atheros/atlx/atl1.c            | 1 -
 drivers/net/ethernet/atheros/atlx/atl2.c            | 3 ---
 drivers/net/ethernet/brocade/bna/cna_fwimg.c        | 4 ----
 drivers/net/ethernet/dec/tulip/de4x5.c              | 1 -
 drivers/net/ethernet/freescale/ucc_geth.c           | 2 --
 drivers/net/ethernet/intel/e1000/e1000_ethtool.c    | 3 ---
 drivers/net/ethernet/intel/e1000/e1000_hw.c         | 2 --
 drivers/net/ethernet/intel/e1000e/82571.c           | 4 ----
 drivers/net/ethernet/intel/e1000e/ethtool.c         | 2 --
 drivers/net/ethernet/intel/e1000e/ich8lan.c         | 1 -
 drivers/net/ethernet/intel/e1000e/mac.c             | 1 -
 drivers/net/ethernet/intel/i40e/i40e_common.c       | 1 -
 drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c  | 1 -
 drivers/net/ethernet/intel/igb/e1000_82575.c        | 1 -
 drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c     | 1 -
 drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c    | 2 --
 drivers/net/ethernet/sis/sis900.c                   | 1 -
 drivers/net/ethernet/sun/niu.c                      | 1 -
 drivers/net/ethernet/toshiba/ps3_gelic_wireless.c   | 7 -------
 drivers/net/wan/dlci.c                              | 1 -
 drivers/net/wireless/airo.c                         | 1 -
 drivers/net/wireless/ath/ath6kl/init.c              | 1 -
 drivers/net/wireless/ath/carl9170/phy.c             | 1 -
 drivers/net/wireless/brcm80211/brcmfmac/p2p.c       | 1 -
 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c | 1 -
 drivers/net/wireless/cw1200/fwio.c                  | 1 -
 drivers/net/wireless/mwl8k.c                        | 5 -----
 drivers/net/wireless/prism54/oid_mgt.c              | 1 -
 drivers/net/wireless/rtlwifi/core.c                 | 1 -
 drivers/net/wireless/rtlwifi/rtl8188ee/pwrseqcmd.c  | 1 -
 drivers/net/wireless/rtlwifi/rtl8192ce/hw.c         | 1 -
 drivers/net/wireless/rtlwifi/rtl8192se/fw.c         | 3 ---
 drivers/net/wireless/rtlwifi/rtl8192se/hw.c         | 1 -
 drivers/net/wireless/rtlwifi/rtl8723ae/hw.c         | 1 -
 drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.c  | 1 -
 39 files changed, 73 deletions(-)

-- 
1.9.1

^ permalink raw reply

* [PATCH 26/30] ucc_geth: remove unnecessary break after return
From: Fabian Frederick @ 2014-07-20 14:27 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev, Fabian Frederick, joe, linuxppc-dev, davem
In-Reply-To: <1405866475-24754-1-git-send-email-fabf@skynet.be>

Signed-off-by: Fabian Frederick <fabf@skynet.be>
---
 drivers/net/ethernet/freescale/ucc_geth.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index 36fc429..8ceaf7a 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -2396,7 +2396,6 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 		if (netif_msg_ifup(ugeth))
 			pr_err("Bad number of Rx threads value\n");
 		return -EINVAL;
-		break;
 	}
 
 	switch (ug_info->numThreadsTx) {
@@ -2419,7 +2418,6 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 		if (netif_msg_ifup(ugeth))
 			pr_err("Bad number of Tx threads value\n");
 		return -EINVAL;
-		break;
 	}
 
 	/* Calculate rx_extended_features */
-- 
1.9.1

^ permalink raw reply related

* Re: [PATCH v3 0/3] dmaengine: mpc512x: add device tree binding document and DMA channel lookup
From: Alexander Popov @ 2014-07-20 19:18 UTC (permalink / raw)
  To: Mark Rutland, Gerhard Sittig, Dan Williams, Vinod Koul,
	Lars-Peter Clausen, Arnd Bergmann, Anatolij Gustschin,
	Andy Shevchenko, Alexander Popov, linuxppc-dev@lists.ozlabs.org,
	dmaengine@vger.kernel.org, devicetree@vger.kernel.org
In-Reply-To: <1403693580-9449-1-git-send-email-a13xp0p0v88@gmail.com>

Hello!

2014-06-25 14:52 GMT+04:00 Alexander Popov <a13xp0p0v88@gmail.com>:
> This patch series introduces a device tree binding document for
> the MPC512x DMA controller and adds device tree based DMA channel lookup
> for it.
>
> This version contains the improved device tree binding document:
> #dma-cells is made a required property, as it must be according
> dma/dma.txt document.

Could I have a feedback, please?
Thanks!

> Alexander Popov (3):
>   dmaengine: mpc512x: add device tree binding document
>   dmaengine: of: add common xlate function for matching by channel id
>   dmaengine: mpc512x: register for device tree channel lookup
>
>  .../devicetree/bindings/dma/mpc512x-dma.txt        | 29 ++++++++++++++++++
>  arch/powerpc/boot/dts/mpc5121.dtsi                 |  1 +
>  drivers/dma/mpc512x_dma.c                          | 13 +++++++-
>  drivers/dma/of-dma.c                               | 35 ++++++++++++++++++++++
>  include/linux/of_dma.h                             |  4 +++
>  5 files changed, 81 insertions(+), 1 deletion(-)
>  create mode 100644 Documentation/devicetree/bindings/dma/mpc512x-dma.txt
>
> --
> 1.8.4.2
>

^ permalink raw reply

* [PATCH v2 6/7] memory-hotplug: sh: suitable memory should go to ZONE_MOVABLE
From: Wang Nan @ 2014-07-21  3:46 UTC (permalink / raw)
  To: Ingo Molnar, Yinghai Lu, Mel Gorman, Andrew Morton, Dave Hansen,
	Zhang Yanfei
  Cc: wangnan0, linux-ia64, peifeiyue, linux-sh, x86, linux-kernel,
	linux-mm, linuxppc-dev
In-Reply-To: <1405914402-66212-1-git-send-email-wangnan0@huawei.com>

This patch introduces zone_for_memory() to arch_add_memory() on sh to
ensure new, higher memory added into ZONE_MOVABLE if movable zone has
already setup.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Zhang Yanfei <zhangyanfei@cn.fujitsu.com>
Cc: Dave Hansen <dave.hansen@intel.com>
---
 arch/sh/mm/init.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index 2d089fe..2790b6a 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -495,8 +495,9 @@ int arch_add_memory(int nid, u64 start, u64 size)
 	pgdat = NODE_DATA(nid);
 
 	/* We only have ZONE_NORMAL, so this is easy.. */
-	ret = __add_pages(nid, pgdat->node_zones + ZONE_NORMAL,
-				start_pfn, nr_pages);
+	ret = __add_pages(nid, pgdat->node_zones +
+			zone_for_memory(nid, start, size, ZONE_NORMAL),
+			start_pfn, nr_pages);
 	if (unlikely(ret))
 		printk("%s: Failed, __add_pages() == %d\n", __func__, ret);
 
-- 
1.8.4

^ permalink raw reply related

* [PATCH v2 4/7] memory-hotplug: ia64: suitable memory should go to ZONE_MOVABLE
From: Wang Nan @ 2014-07-21  3:46 UTC (permalink / raw)
  To: Ingo Molnar, Yinghai Lu, Mel Gorman, Andrew Morton, Dave Hansen,
	Zhang Yanfei
  Cc: wangnan0, linux-ia64, peifeiyue, linux-sh, x86, linux-kernel,
	linux-mm, linuxppc-dev
In-Reply-To: <1405914402-66212-1-git-send-email-wangnan0@huawei.com>

This patch introduces zone_for_memory() to arch_add_memory() on ia64 to
ensure new, higher memory added into ZONE_MOVABLE if movable zone has
already setup.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Zhang Yanfei <zhangyanfei@cn.fujitsu.com>
Cc: Dave Hansen <dave.hansen@intel.com>
---
 arch/ia64/mm/init.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index 25c3502..892d43e 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -631,7 +631,8 @@ int arch_add_memory(int nid, u64 start, u64 size)
 
 	pgdat = NODE_DATA(nid);
 
-	zone = pgdat->node_zones + ZONE_NORMAL;
+	zone = pgdat->node_zones +
+		zone_for_memory(nid, start, size, ZONE_NORMAL);
 	ret = __add_pages(nid, zone, start_pfn, nr_pages);
 
 	if (ret)
-- 
1.8.4

^ permalink raw reply related

* [PATCH v2 3/7] memory-hotplug: x86_32: suitable memory should go to ZONE_MOVABLE
From: Wang Nan @ 2014-07-21  3:46 UTC (permalink / raw)
  To: Ingo Molnar, Yinghai Lu, Mel Gorman, Andrew Morton, Dave Hansen,
	Zhang Yanfei
  Cc: wangnan0, linux-ia64, peifeiyue, linux-sh, x86, linux-kernel,
	linux-mm, linuxppc-dev
In-Reply-To: <1405914402-66212-1-git-send-email-wangnan0@huawei.com>

This patch introduces zone_for_memory() to arch_add_memory() on x86_32
to ensure new, higher memory added into ZONE_MOVABLE if movable zone has
already setup.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Zhang Yanfei <zhangyanfei@cn.fujitsu.com>
Cc: Dave Hansen <dave.hansen@intel.com>
---
 arch/x86/mm/init_32.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index e395048..7d05565 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -825,7 +825,8 @@ void __init mem_init(void)
 int arch_add_memory(int nid, u64 start, u64 size)
 {
 	struct pglist_data *pgdata = NODE_DATA(nid);
-	struct zone *zone = pgdata->node_zones + ZONE_HIGHMEM;
+	struct zone *zone = pgdata->node_zones +
+		zone_for_memory(nid, start, size, ZONE_HIGHMEM);
 	unsigned long start_pfn = start >> PAGE_SHIFT;
 	unsigned long nr_pages = size >> PAGE_SHIFT;
 
-- 
1.8.4

^ permalink raw reply related

* [PATCH v2 2/7] memory-hotplug: x86_64: suitable memory should go to ZONE_MOVABLE
From: Wang Nan @ 2014-07-21  3:46 UTC (permalink / raw)
  To: Ingo Molnar, Yinghai Lu, Mel Gorman, Andrew Morton, Dave Hansen,
	Zhang Yanfei
  Cc: wangnan0, linux-ia64, peifeiyue, linux-sh, x86, linux-kernel,
	linux-mm, linuxppc-dev
In-Reply-To: <1405914402-66212-1-git-send-email-wangnan0@huawei.com>

This patch introduces zone_for_memory() to arch_add_memory() on x86_64
to ensure new, higher memory added into ZONE_MOVABLE if movable zone has
already setup.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Zhang Yanfei <zhangyanfei@cn.fujitsu.com>
Cc: Dave Hansen <dave.hansen@intel.com>
---
 arch/x86/mm/init_64.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index df1a992..5621c47 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -691,7 +691,8 @@ static void  update_end_of_memory_vars(u64 start, u64 size)
 int arch_add_memory(int nid, u64 start, u64 size)
 {
 	struct pglist_data *pgdat = NODE_DATA(nid);
-	struct zone *zone = pgdat->node_zones + ZONE_NORMAL;
+	struct zone *zone = pgdat->node_zones +
+		zone_for_memory(nid, start, size, ZONE_NORMAL);
 	unsigned long start_pfn = start >> PAGE_SHIFT;
 	unsigned long nr_pages = size >> PAGE_SHIFT;
 	int ret;
-- 
1.8.4

^ permalink raw reply related

* [PATCH v2 0/7] memory-hotplug: suitable memory should go to ZONE_MOVABLE
From: Wang Nan @ 2014-07-21  3:46 UTC (permalink / raw)
  To: Ingo Molnar, Yinghai Lu, Mel Gorman, Andrew Morton, Dave Hansen,
	Zhang Yanfei
  Cc: wangnan0, linux-ia64, peifeiyue, linux-sh, x86, linux-kernel,
	linux-mm, linuxppc-dev

This series of patches fix a problem when adding memory in bad manner.
For example: for a x86_64 machine booted with "mem=400M" and with 2GiB
memory installed, following commands cause problem:

  # echo 0x40000000 > /sys/devices/system/memory/probe
 [   28.613895] init_memory_mapping: [mem 0x40000000-0x47ffffff]
  # echo 0x48000000 > /sys/devices/system/memory/probe
 [   28.693675] init_memory_mapping: [mem 0x48000000-0x4fffffff]
  # echo online_movable > /sys/devices/system/memory/memory9/state
  # echo 0x50000000 > /sys/devices/system/memory/probe 
 [   29.084090] init_memory_mapping: [mem 0x50000000-0x57ffffff]
  # echo 0x58000000 > /sys/devices/system/memory/probe 
 [   29.151880] init_memory_mapping: [mem 0x58000000-0x5fffffff]
  # echo online_movable > /sys/devices/system/memory/memory11/state
  # echo online> /sys/devices/system/memory/memory8/state
  # echo online> /sys/devices/system/memory/memory10/state
  # echo offline> /sys/devices/system/memory/memory9/state
 [   30.558819] Offlined Pages 32768
  # free
              total       used       free     shared    buffers     cached
 Mem:        780588 18014398509432020     830552          0          0      51180
 -/+ buffers/cache: 18014398509380840     881732
 Swap:            0          0          0

This is because the above commands probe higher memory after online a
section with online_movable, which causes ZONE_HIGHMEM (or ZONE_NORMAL
for systems without ZONE_HIGHMEM) overlaps ZONE_MOVABLE.

After the second online_movable, the problem can be observed from
zoneinfo:

 # cat /proc/zoneinfo
...
Node 0, zone  Movable
  pages free     65491
        min      250
        low      312
        high     375
        scanned  0
        spanned  18446744073709518848
        present  65536
        managed  65536
...

This series of patches solve the problem by checking ZONE_MOVABLE when
choosing zone for new memory. If new memory is inside or higher than
ZONE_MOVABLE, makes it go there instead.

After applying this series of patches, following are free and zoneinfo
result (after offlining memory9):

bash-4.2# free
              total       used       free     shared    buffers     cached
 Mem:        780956      80112     700844          0          0      51180
 -/+ buffers/cache:      28932     752024
 Swap:            0          0          0

bash-4.2# cat /proc/zoneinfo

Node 0, zone      DMA
  pages free     3389
        min      14
        low      17
        high     21
        scanned  0
        spanned  4095
        present  3998
        managed  3977
    nr_free_pages 3389
...
  start_pfn:         1
  inactive_ratio:    1
Node 0, zone    DMA32
  pages free     73724
        min      341
        low      426
        high     511
        scanned  0
        spanned  98304
        present  98304
        managed  92958
    nr_free_pages 73724
...
  start_pfn:         4096
  inactive_ratio:    1
Node 0, zone   Normal
  pages free     32630
        min      120
        low      150
        high     180
        scanned  0
        spanned  32768
        present  32768
        managed  32768
    nr_free_pages 32630
...
  start_pfn:         262144
  inactive_ratio:    1
Node 0, zone  Movable
  pages free     65476
        min      241
        low      301
        high     361
        scanned  0
        spanned  98304
        present  65536
        managed  65536
    nr_free_pages 65476
...
  start_pfn:         294912
  inactive_ratio:    1

v1 -> v2:
 - introduce zone_for_memory() to arch independent code to make arch
   dependent code simpler, following Dave Hansen's comments.
 - Paste free and zoneinfo result in patch 0 as a response to
   Zhang Yanfei.
 - Fix a problem in tile to add memory into ZONE_HIGHMEM by default.

Wang Nan (7):
  memory-hotplug: add zone_for_memory() for selecting zone for new
    memory
  memory-hotplug: x86_64: suitable memory should go to ZONE_MOVABLE
  memory-hotplug: x86_32: suitable memory should go to ZONE_MOVABLE
  memory-hotplug: ia64: suitable memory should go to ZONE_MOVABLE
  memory-hotplug: ppc: suitable memory should go to ZONE_MOVABLE
  memory-hotplug: sh: suitable memory should go to ZONE_MOVABLE
  memory-hotplug: tile: suitable memory should go to ZONE_MOVABLE

 arch/ia64/mm/init.c            |  3 ++-
 arch/powerpc/mm/mem.c          |  3 ++-
 arch/sh/mm/init.c              |  5 +++--
 arch/tile/mm/init.c            |  3 ++-
 arch/x86/mm/init_32.c          |  3 ++-
 arch/x86/mm/init_64.c          |  3 ++-
 include/linux/memory_hotplug.h |  1 +
 mm/memory_hotplug.c            | 28 ++++++++++++++++++++++++++++
 8 files changed, 42 insertions(+), 7 deletions(-)

-- 
1.8.4

^ permalink raw reply

* [PATCH v2 1/7] memory-hotplug: add zone_for_memory() for selecting zone for new memory
From: Wang Nan @ 2014-07-21  3:46 UTC (permalink / raw)
  To: Ingo Molnar, Yinghai Lu, Mel Gorman, Andrew Morton, Dave Hansen,
	Zhang Yanfei
  Cc: wangnan0, linux-ia64, peifeiyue, linux-sh, x86, linux-kernel,
	linux-mm, linuxppc-dev
In-Reply-To: <1405914402-66212-1-git-send-email-wangnan0@huawei.com>

This patch introduces a zone_for_memory function in arch independent
code for arch_add_memory() using.

Many arch_add_memory() function simply selects ZONE_HIGHMEM or
ZONE_NORMAL and add new memory into it. However, with the existance of
ZONE_MOVABLE, the selection method should be carefully considered: if
new, higher memory is added after ZONE_MOVABLE is setup, the default
zone and ZONE_MOVABLE may overlap each other.

should_add_memory_movable() checks the status of ZONE_MOVABLE. If it has
already contain memory, compare the address of new memory and movable
memory. If new memory is higher than movable, it should be added into
ZONE_MOVABLE instead of default zone.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Zhang Yanfei <zhangyanfei@cn.fujitsu.com>
Cc: Dave Hansen <dave.hansen@intel.com>
---
 include/linux/memory_hotplug.h |  1 +
 mm/memory_hotplug.c            | 28 ++++++++++++++++++++++++++++
 2 files changed, 29 insertions(+)

diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
index 010d125..3de3d02 100644
--- a/include/linux/memory_hotplug.h
+++ b/include/linux/memory_hotplug.h
@@ -258,6 +258,7 @@ static inline void remove_memory(int nid, u64 start, u64 size) {}
 extern int walk_memory_range(unsigned long start_pfn, unsigned long end_pfn,
 		void *arg, int (*func)(struct memory_block *, void *));
 extern int add_memory(int nid, u64 start, u64 size);
+extern int zone_for_memory(int nid, u64 start, u64 size, int zone_default);
 extern int arch_add_memory(int nid, u64 start, u64 size);
 extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages);
 extern bool is_memblock_offlined(struct memory_block *mem);
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 469bbf5..348fda7 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -1156,6 +1156,34 @@ static int check_hotplug_memory_range(u64 start, u64 size)
 	return 0;
 }
 
+/*
+ * If movable zone has already been setup, newly added memory should be check.
+ * If its address is higher than movable zone, it should be added as movable.
+ * Without this check, movable zone may overlap with other zone.
+ */
+static int should_add_memory_movable(int nid, u64 start, u64 size)
+{
+	unsigned long start_pfn = start >> PAGE_SHIFT;
+	pg_data_t *pgdat = NODE_DATA(nid);
+	struct zone *movable_zone = pgdat->node_zones + ZONE_MOVABLE;
+
+	if (zone_is_empty(movable_zone))
+		return 0;
+
+	if (movable_zone->zone_start_pfn <= start_pfn)
+		return 1;
+
+	return 0;
+}
+
+int zone_for_memory(int nid, u64 start, u64 size, int zone_default)
+{
+	if (should_add_memory_movable(nid, start, size))
+		return ZONE_MOVABLE;
+
+	return zone_default;
+}
+
 /* we are OK calling __meminit stuff here - we have CONFIG_MEMORY_HOTPLUG */
 int __ref add_memory(int nid, u64 start, u64 size)
 {
-- 
1.8.4

^ permalink raw reply related

* [PATCH v2 5/7] memory-hotplug: ppc: suitable memory should go to ZONE_MOVABLE
From: Wang Nan @ 2014-07-21  3:46 UTC (permalink / raw)
  To: Ingo Molnar, Yinghai Lu, Mel Gorman, Andrew Morton, Dave Hansen,
	Zhang Yanfei
  Cc: wangnan0, linux-ia64, peifeiyue, linux-sh, x86, linux-kernel,
	linux-mm, linuxppc-dev
In-Reply-To: <1405914402-66212-1-git-send-email-wangnan0@huawei.com>

This patch introduces zone_for_memory() to arch_add_memory() on powerpc
to ensure new, higher memory added into ZONE_MOVABLE if movable zone has
already setup.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Zhang Yanfei <zhangyanfei@cn.fujitsu.com>
Cc: Dave Hansen <dave.hansen@intel.com>
---
 arch/powerpc/mm/mem.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 2c8e90f..e0f7a18 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -128,7 +128,8 @@ int arch_add_memory(int nid, u64 start, u64 size)
 		return -EINVAL;
 
 	/* this should work for most non-highmem platforms */
-	zone = pgdata->node_zones;
+	zone = pgdata->node_zones +
+		zone_for_memory(nid, start, size, 0);
 
 	return __add_pages(nid, zone, start_pfn, nr_pages);
 }
-- 
1.8.4

^ permalink raw reply related

* [PATCH v2 7/7] memory-hotplug: tile: suitable memory should go to ZONE_MOVABLE
From: Wang Nan @ 2014-07-21  3:46 UTC (permalink / raw)
  To: Ingo Molnar, Yinghai Lu, Mel Gorman, Andrew Morton, Dave Hansen,
	Zhang Yanfei
  Cc: wangnan0, linux-ia64, peifeiyue, linux-sh, x86, linux-kernel,
	linux-mm, linuxppc-dev
In-Reply-To: <1405914402-66212-1-git-send-email-wangnan0@huawei.com>

This patch introduces zone_for_memory() to arch_add_memory() on tile to
ensure new, higher memory added into ZONE_MOVABLE if movable zone has
already setup.

This patch also fix a problem: on tile, new memory should be added into
ZONE_HIGHMEM by default, not MAX_NR_ZONES-1, which is ZONE_MOVABLE.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Zhang Yanfei <zhangyanfei@cn.fujitsu.com>
Cc: Dave Hansen <dave.hansen@intel.com>
---
 arch/tile/mm/init.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/tile/mm/init.c b/arch/tile/mm/init.c
index bfb3127..22ac6c1 100644
--- a/arch/tile/mm/init.c
+++ b/arch/tile/mm/init.c
@@ -872,7 +872,8 @@ void __init mem_init(void)
 int arch_add_memory(u64 start, u64 size)
 {
 	struct pglist_data *pgdata = &contig_page_data;
-	struct zone *zone = pgdata->node_zones + MAX_NR_ZONES-1;
+	struct zone *zone = pgdata->node_zones +
+		zone_for_memory(nid, start, size, ZONE_HIGHMEM);
 	unsigned long start_pfn = start >> PAGE_SHIFT;
 	unsigned long nr_pages = size >> PAGE_SHIFT;
 
-- 
1.8.4

^ permalink raw reply related

* Re: [PATCH 00/30] drivers/net: remove unnecessary break after return
From: David Miller @ 2014-07-21  4:31 UTC (permalink / raw)
  To: fabf
  Cc: brcm80211-dev-list, e1000-devel, netdev, linux-wireless,
	linux-kernel, joe, linuxppc-dev
In-Reply-To: <1405865801-18806-1-git-send-email-fabf@skynet.be>

From: Fabian Frederick <fabf@skynet.be>
Date: Sun, 20 Jul 2014 16:16:08 +0200

> Second patchset after "remove unnecessary break after goto" addressing break redundancy on drivers/net branch
> (suggested by Joe Perches)

All applied except the i40e patch, which did not apply to net-next at all.

^ permalink raw reply

* [PATCH 1/3] selftests/powerpc: Count instructions under scheduler pressure
From: Michael Ellerman @ 2014-07-21  4:34 UTC (permalink / raw)
  To: linuxppc-dev

Have a task eat some cpu while we are counting instructions to create
some scheduler pressure. The idea being to try and unearth any bugs we
have in counting that only appear when context switching is happening.

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 tools/testing/selftests/powerpc/pmu/Makefile             | 2 +-
 tools/testing/selftests/powerpc/pmu/count_instructions.c | 8 +++++++-
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/powerpc/pmu/Makefile b/tools/testing/selftests/powerpc/pmu/Makefile
index b9ff0db42c79..9c1ae4a9aa53 100644
--- a/tools/testing/selftests/powerpc/pmu/Makefile
+++ b/tools/testing/selftests/powerpc/pmu/Makefile
@@ -2,7 +2,7 @@ noarg:
 	$(MAKE) -C ../
 
 PROGS := count_instructions
-EXTRA_SOURCES := ../harness.c event.c
+EXTRA_SOURCES := ../harness.c event.c lib.c
 
 all: $(PROGS) sub_all
 
diff --git a/tools/testing/selftests/powerpc/pmu/count_instructions.c b/tools/testing/selftests/powerpc/pmu/count_instructions.c
index 312b4f0fd27c..5e241e14f204 100644
--- a/tools/testing/selftests/powerpc/pmu/count_instructions.c
+++ b/tools/testing/selftests/powerpc/pmu/count_instructions.c
@@ -12,6 +12,7 @@
 
 #include "event.h"
 #include "utils.h"
+#include "lib.h"
 
 extern void thirty_two_instruction_loop(u64 loops);
 
@@ -90,7 +91,7 @@ static u64 determine_overhead(struct event *events)
 	return overhead;
 }
 
-static int count_instructions(void)
+static int test_body(void)
 {
 	struct event events[2];
 	u64 overhead;
@@ -129,6 +130,11 @@ static int count_instructions(void)
 	return 0;
 }
 
+static int count_instructions(void)
+{
+	return eat_cpu(test_body);
+}
+
 int main(void)
 {
 	return test_harness(count_instructions, "count_instructions");
-- 
1.9.1

^ permalink raw reply related

* [PATCH 2/3] selftests/powerpc: Count more instructions
From: Michael Ellerman @ 2014-07-21  4:34 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1405917282-31599-1-git-send-email-mpe@ellerman.id.au>

Although we expect some small discrepancies for very large counts, we
seem to be able to count up to 64G instructions without too much skew, so
do so.

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 tools/testing/selftests/powerpc/pmu/count_instructions.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/tools/testing/selftests/powerpc/pmu/count_instructions.c b/tools/testing/selftests/powerpc/pmu/count_instructions.c
index 5e241e14f204..56572f0b1eb2 100644
--- a/tools/testing/selftests/powerpc/pmu/count_instructions.c
+++ b/tools/testing/selftests/powerpc/pmu/count_instructions.c
@@ -124,6 +124,12 @@ static int test_body(void)
 	/* Run for 1G instructions */
 	FAIL_IF(do_count_loop(events, 0x40000000, overhead, true));
 
+	/* Run for 16G instructions */
+	FAIL_IF(do_count_loop(events, 0x400000000, overhead, true));
+
+	/* Run for 64G instructions */
+	FAIL_IF(do_count_loop(events, 0x1000000000, overhead, true));
+
 	event_close(&events[0]);
 	event_close(&events[1]);
 
-- 
1.9.1

^ permalink raw reply related

* [PATCH 3/3] selftests/powerpc: Count decimal numbers of instructions
From: Michael Ellerman @ 2014-07-21  4:34 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1405917282-31599-1-git-send-email-mpe@ellerman.id.au>

This just makes it easier to visually compare the expected vs actual
values, as well as the raw result from instructions.

Before:

  instructions: result 68719476753 running/enabled 13101961654
  cycles: result 38077343785 running/enabled 13101725752
  Looped for 68719476736 instructions, overhead 17
  Expected 68719476753
  Actual   68719476753
  Delta    0, 0.000000%
  success: count_instructions

After:
  instructions: result 64000000016 running/enabled 12197599964
  cycles: result 35412471674 running/enabled 12197534110
  Looped for 64000000000 instructions, overhead 16
  Expected 64000000016
  Actual   64000000016
  Delta    0, 0.000000%
  success: count_instructions

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 .../selftests/powerpc/pmu/count_instructions.c     | 24 +++++++++++-----------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/tools/testing/selftests/powerpc/pmu/count_instructions.c b/tools/testing/selftests/powerpc/pmu/count_instructions.c
index 56572f0b1eb2..4622117b24c0 100644
--- a/tools/testing/selftests/powerpc/pmu/count_instructions.c
+++ b/tools/testing/selftests/powerpc/pmu/count_instructions.c
@@ -112,23 +112,23 @@ static int test_body(void)
 	overhead = determine_overhead(events);
 	printf("Overhead of null loop: %llu instructions\n", overhead);
 
-	/* Run for 1M instructions */
-	FAIL_IF(do_count_loop(events, 0x100000, overhead, true));
+	/* Run for 1Mi instructions */
+	FAIL_IF(do_count_loop(events, 1000000, overhead, true));
 
-	/* Run for 10M instructions */
-	FAIL_IF(do_count_loop(events, 0xa00000, overhead, true));
+	/* Run for 10Mi instructions */
+	FAIL_IF(do_count_loop(events, 10000000, overhead, true));
 
-	/* Run for 100M instructions */
-	FAIL_IF(do_count_loop(events, 0x6400000, overhead, true));
+	/* Run for 100Mi instructions */
+	FAIL_IF(do_count_loop(events, 100000000, overhead, true));
 
-	/* Run for 1G instructions */
-	FAIL_IF(do_count_loop(events, 0x40000000, overhead, true));
+	/* Run for 1Bi instructions */
+	FAIL_IF(do_count_loop(events, 1000000000, overhead, true));
 
-	/* Run for 16G instructions */
-	FAIL_IF(do_count_loop(events, 0x400000000, overhead, true));
+	/* Run for 16Bi instructions */
+	FAIL_IF(do_count_loop(events, 16000000000, overhead, true));
 
-	/* Run for 64G instructions */
-	FAIL_IF(do_count_loop(events, 0x1000000000, overhead, true));
+	/* Run for 64Bi instructions */
+	FAIL_IF(do_count_loop(events, 64000000000, overhead, true));
 
 	event_close(&events[0]);
 	event_close(&events[1]);
-- 
1.9.1

^ permalink raw reply related

* [PATCH v3 4/6] powerpc/powernv: Handle compound PE
From: Gavin Shan @ 2014-07-21  4:42 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: yan, Gavin Shan
In-Reply-To: <1405917755-28830-1-git-send-email-gwshan@linux.vnet.ibm.com>

The patch introduces 3 PHB callbacks: compound PE state retrieval,
force freezing and unfreezing compound PE. The PCI config accessors
and PowerNV EEH backend can use them in subsequent patches.

We don't export the capability of compound PE to EEH core, which
helps avoiding more complexity to EEH core.

Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/powernv/pci-ioda.c | 143 ++++++++++++++++++++++++++++++
 arch/powerpc/platforms/powernv/pci.h      |   3 +
 2 files changed, 146 insertions(+)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 2b659d9..0381a78 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -347,6 +347,146 @@ static void __init pnv_ioda_parse_m64_window(struct pnv_phb *phb)
 	phb->pick_m64_pe = pnv_ioda2_pick_m64_pe;
 }
 
+static void pnv_ioda_freeze_pe(struct pnv_phb *phb, int pe_no)
+{
+	struct pnv_ioda_pe *pe = &phb->ioda.pe_array[pe_no];
+	struct pnv_ioda_pe *slave;
+	s64 rc;
+
+	/* Fetch master PE */
+	if (pe->flags & PNV_IODA_PE_SLAVE) {
+		pe = pe->master;
+		WARN_ON(!pe || !(pe->flags & PNV_IODA_PE_MASTER));
+		pe_no = pe->pe_number;
+	}
+
+	/* Freeze master PE */
+	rc = opal_pci_eeh_freeze_set(phb->opal_id,
+				     pe_no,
+				     OPAL_EEH_ACTION_SET_FREEZE_ALL);
+	if (rc != OPAL_SUCCESS) {
+		pr_warn("%s: Failure %lld freezing PHB#%x-PE#%x\n",
+			__func__, rc, phb->hose->global_number, pe_no);
+		return;
+	}
+
+	/* Freeze slave PEs */
+	if (!(pe->flags & PNV_IODA_PE_MASTER))
+		return;
+
+	list_for_each_entry(slave, &pe->slaves, list) {
+		rc = opal_pci_eeh_freeze_set(phb->opal_id,
+					     slave->pe_number,
+					     OPAL_EEH_ACTION_SET_FREEZE_ALL);
+		if (rc != OPAL_SUCCESS)
+			pr_warn("%s: Failure %lld freezing PHB#%x-PE#%x\n",
+				__func__, rc, phb->hose->global_number,
+				slave->pe_number);
+	}
+}
+
+int pnv_ioda_unfreeze_pe(struct pnv_phb *phb, int pe_no, int opt)
+{
+	struct pnv_ioda_pe *pe, *slave;
+	s64 rc;
+
+	/* Find master PE */
+	pe = &phb->ioda.pe_array[pe_no];
+	if (pe->flags & PNV_IODA_PE_SLAVE) {
+		pe = pe->master;
+		WARN_ON(!pe || !(pe->flags & PNV_IODA_PE_MASTER));
+		pe_no = pe->pe_number;
+	}
+
+	/* Clear frozen state for master PE */
+	rc = opal_pci_eeh_freeze_clear(phb->opal_id, pe_no, opt);
+	if (rc != OPAL_SUCCESS) {
+		pr_warn("%s: Failure %lld clear %d on PHB#%x-PE#%x\n",
+			__func__, rc, opt, phb->hose->global_number, pe_no);
+		return -EIO;
+	}
+
+	if (!(pe->flags & PNV_IODA_PE_MASTER))
+		return 0;
+
+	/* Clear frozen state for slave PEs */
+	list_for_each_entry(slave, &pe->slaves, list) {
+		rc = opal_pci_eeh_freeze_clear(phb->opal_id,
+					     slave->pe_number,
+					     opt);
+		if (rc != OPAL_SUCCESS) {
+			pr_warn("%s: Failure %lld clear %d on PHB#%x-PE#%x\n",
+				__func__, rc, opt, phb->hose->global_number,
+				slave->pe_number);
+			return -EIO;
+		}
+	}
+
+	return 0;
+}
+
+static int pnv_ioda_get_pe_state(struct pnv_phb *phb, int pe_no)
+{
+	struct pnv_ioda_pe *slave, *pe;
+	u8 fstate, state;
+	__be16 pcierr;
+	s64 rc;
+
+	/* Sanity check on PE number */
+	if (pe_no < 0 || pe_no >= phb->ioda.total_pe)
+		return OPAL_EEH_STOPPED_PERM_UNAVAIL;
+
+	/*
+	 * Fetch the master PE and the PE instance might be
+	 * not initialized yet.
+	 */
+	pe = &phb->ioda.pe_array[pe_no];
+	if (pe->flags & PNV_IODA_PE_SLAVE) {
+		pe = pe->master;
+		WARN_ON(!pe || !(pe->flags & PNV_IODA_PE_MASTER));
+		pe_no = pe->pe_number;
+	}
+
+	/* Check the master PE */
+	rc = opal_pci_eeh_freeze_status(phb->opal_id, pe_no,
+					&state, &pcierr, NULL);
+	if (rc != OPAL_SUCCESS) {
+		pr_warn("%s: Failure %lld getting "
+			"PHB#%x-PE#%x state\n",
+			__func__, rc,
+			phb->hose->global_number, pe_no);
+		return OPAL_EEH_STOPPED_TEMP_UNAVAIL;
+	}
+
+	/* Check the slave PE */
+	if (!(pe->flags & PNV_IODA_PE_MASTER))
+		return state;
+
+	list_for_each_entry(slave, &pe->slaves, list) {
+		rc = opal_pci_eeh_freeze_status(phb->opal_id,
+						slave->pe_number,
+						&fstate,
+						&pcierr,
+						NULL);
+		if (rc != OPAL_SUCCESS) {
+			pr_warn("%s: Failure %lld getting "
+				"PHB#%x-PE#%x state\n",
+				__func__, rc,
+				phb->hose->global_number, slave->pe_number);
+			return OPAL_EEH_STOPPED_TEMP_UNAVAIL;
+		}
+
+		/*
+		 * Override the result based on the ascending
+		 * priority.
+		 */
+		if (fstate > state)
+			state = fstate;
+	}
+
+	return state;
+}
+
 /* Currently those 2 are only used when MSIs are enabled, this will change
  * but in the meantime, we need to protect them to avoid warnings
  */
@@ -1626,6 +1766,9 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np,
 
 
 	phb->hose->ops = &pnv_pci_ops;
+	phb->get_pe_state = pnv_ioda_get_pe_state;
+	phb->freeze_pe = pnv_ioda_freeze_pe;
+	phb->unfreeze_pe = pnv_ioda_unfreeze_pe;
 #ifdef CONFIG_EEH
 	phb->eeh_ops = &ioda_eeh_ops;
 #endif
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h
index def7171..b160e6b 100644
--- a/arch/powerpc/platforms/powernv/pci.h
+++ b/arch/powerpc/platforms/powernv/pci.h
@@ -128,6 +128,9 @@ struct pnv_phb {
 	int (*init_m64)(struct pnv_phb *phb);
 	void (*alloc_m64_pe)(struct pnv_phb *phb);
 	int (*pick_m64_pe)(struct pnv_phb *phb, struct pci_bus *bus, int all);
+	int (*get_pe_state)(struct pnv_phb *phb, int pe_no);
+	void (*freeze_pe)(struct pnv_phb *phb, int pe_no);
+	int (*unfreeze_pe)(struct pnv_phb *phb, int pe_no, int opt);
 
 	union {
 		struct {
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH v3 2/6] powerpc/powernv: Allow to freeze PE
From: Gavin Shan @ 2014-07-21  4:42 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: yan, Gavin Shan
In-Reply-To: <1405917755-28830-1-git-send-email-gwshan@linux.vnet.ibm.com>

The patch synchronizes header file with firmware to have new OPAL
API opal_pci_eeh_freeze_set(), which is used to freeze the specified
PE in order to support "compound" PE.

Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
---
v3: separate API to freeze PE
---
 arch/powerpc/include/asm/opal.h                | 9 ++++++++-
 arch/powerpc/platforms/powernv/opal-wrappers.S | 1 +
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index ae885cc..49bab65 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -147,6 +147,7 @@ struct opal_sg_list {
 #define OPAL_SET_PARAM				90
 #define OPAL_DUMP_RESEND			91
 #define OPAL_DUMP_INFO2				94
+#define OPAL_PCI_EEH_FREEZE_SET			97
 
 #ifndef __ASSEMBLY__
 
@@ -170,7 +171,11 @@ enum OpalFreezeState {
 enum OpalEehFreezeActionToken {
 	OPAL_EEH_ACTION_CLEAR_FREEZE_MMIO = 1,
 	OPAL_EEH_ACTION_CLEAR_FREEZE_DMA = 2,
-	OPAL_EEH_ACTION_CLEAR_FREEZE_ALL = 3
+	OPAL_EEH_ACTION_CLEAR_FREEZE_ALL = 3,
+
+	OPAL_EEH_ACTION_SET_FREEZE_MMIO = 1,
+	OPAL_EEH_ACTION_SET_FREEZE_DMA  = 2,
+	OPAL_EEH_ACTION_SET_FREEZE_ALL  = 3
 };
 
 enum OpalPciStatusToken {
@@ -764,6 +769,8 @@ int64_t opal_pci_eeh_freeze_status(uint64_t phb_id, uint64_t pe_number,
 				   __be64 *phb_status);
 int64_t opal_pci_eeh_freeze_clear(uint64_t phb_id, uint64_t pe_number,
 				  uint64_t eeh_action_token);
+int64_t opal_pci_eeh_freeze_set(uint64_t phb_id, uint64_t pe_number,
+				uint64_t eeh_action_token);
 int64_t opal_pci_shpc(uint64_t phb_id, uint64_t shpc_action, uint8_t *state);
 
 
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S
index 4abbff2..7943c8a 100644
--- a/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -86,6 +86,7 @@ OPAL_CALL(opal_get_xive,			OPAL_GET_XIVE);
 OPAL_CALL(opal_register_exception_handler,	OPAL_REGISTER_OPAL_EXCEPTION_HANDLER);
 OPAL_CALL(opal_pci_eeh_freeze_status,		OPAL_PCI_EEH_FREEZE_STATUS);
 OPAL_CALL(opal_pci_eeh_freeze_clear,		OPAL_PCI_EEH_FREEZE_CLEAR);
+OPAL_CALL(opal_pci_eeh_freeze_set,		OPAL_PCI_EEH_FREEZE_SET);
 OPAL_CALL(opal_pci_shpc,			OPAL_PCI_SHPC);
 OPAL_CALL(opal_pci_phb_mmio_enable,		OPAL_PCI_PHB_MMIO_ENABLE);
 OPAL_CALL(opal_pci_set_phb_mem_window,		OPAL_PCI_SET_PHB_MEM_WINDOW);
-- 
1.8.3.2

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox