LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH REPOST 1/3] powerpc/vphn: clarify the H_HOME_NODE_ASSOCIATIVITY API
From: Greg Kurz @ 2014-11-17 17:42 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Paul Mackerras
In-Reply-To: <20141117174216.7717.10926.stgit@bahia.local>

The number of values returned by the H_HOME_NODE_ASSOCIATIVITY h_call deserves
to be explicitly defined, for a better understanding of the code.

Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
---
 arch/powerpc/mm/numa.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index b9d1dfd..1425517 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -1401,11 +1401,15 @@ static int update_cpu_associativity_changes_mask(void)
 	return cpumask_weight(changes);
 }
 
+/* The H_HOME_NODE_ASSOCIATIVITY h_call returns 6 64-bit registers.
+ */
+#define VPHN_REGISTER_COUNT 6
+
 /*
  * 6 64-bit registers unpacked into 12 32-bit associativity values. To form
  * the complete property we have to add the length in the first cell.
  */
-#define VPHN_ASSOC_BUFSIZE (6*sizeof(u64)/sizeof(u32) + 1)
+#define VPHN_ASSOC_BUFSIZE (VPHN_REGISTER_COUNT*sizeof(u64)/sizeof(u32) + 1)
 
 /*
  * Convert the associativity domain numbers returned from the hypervisor
@@ -1463,7 +1467,7 @@ static long hcall_vphn(unsigned long cpu, __be32 *associativity)
 	int i;
 
 	rc = plpar_hcall9(H_HOME_NODE_ASSOCIATIVITY, retbuf, flags, hwcpu);
-	for (i = 0; i < 6; i++)
+	for (i = 0; i < VPHN_REGISTER_COUNT; i++)
 		retbuf[i] = cpu_to_be64(retbuf[i]);
 	vphn_unpack_associativity(retbuf, associativity);
 

^ permalink raw reply related

* [PATCH REPOST 2/3] powerpc/vphn: simplify the parsing code
From: Greg Kurz @ 2014-11-17 17:42 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Paul Mackerras
In-Reply-To: <20141117174216.7717.10926.stgit@bahia.local>

According to PAPR+ 14.11.6.1 H_HOME_NODE_ASSOCIATIVITY, the hypervisor is
supposed to pack significant fields first and fill the remaining unused
fields with "all ones". It means that the first unused field can be viewed
as an end-of-list marker.
The "ibm,associativity" property in the DT isn't padded with ones and no
code in arch/powerpc/mm/numa.c seems to expect the associativity array
to be padded either.

This patch simply ends the parsing when we reach the first unused field.

Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
---
 arch/powerpc/mm/numa.c |   20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 1425517..e30c469 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -1417,7 +1417,7 @@ static int update_cpu_associativity_changes_mask(void)
  */
 static int vphn_unpack_associativity(const long *packed, __be32 *unpacked)
 {
-	int i, nr_assoc_doms = 0;
+	int i;
 	const __be16 *field = (const __be16 *) packed;
 
 #define VPHN_FIELD_UNUSED	(0xffff)
@@ -1425,33 +1425,29 @@ static int vphn_unpack_associativity(const long *packed, __be32 *unpacked)
 #define VPHN_FIELD_MASK		(~VPHN_FIELD_MSB)
 
 	for (i = 1; i < VPHN_ASSOC_BUFSIZE; i++) {
-		if (be16_to_cpup(field) == VPHN_FIELD_UNUSED) {
-			/* All significant fields processed, and remaining
-			 * fields contain the reserved value of all 1's.
-			 * Just store them.
+		if (be16_to_cpup(field) == VPHN_FIELD_UNUSED)
+			/* All significant fields processed.
 			 */
-			unpacked[i] = *((__be32 *)field);
-			field += 2;
-		} else if (be16_to_cpup(field) & VPHN_FIELD_MSB) {
+			break;
+
+		if (be16_to_cpup(field) & VPHN_FIELD_MSB) {
 			/* Data is in the lower 15 bits of this field */
 			unpacked[i] = cpu_to_be32(
 				be16_to_cpup(field) & VPHN_FIELD_MASK);
 			field++;
-			nr_assoc_doms++;
 		} else {
 			/* Data is in the lower 15 bits of this field
 			 * concatenated with the next 16 bit field
 			 */
 			unpacked[i] = *((__be32 *)field);
 			field += 2;
-			nr_assoc_doms++;
 		}
 	}
 
 	/* The first cell contains the length of the property */
-	unpacked[0] = cpu_to_be32(nr_assoc_doms);
+	unpacked[0] = cpu_to_be32(i - 1);
 
-	return nr_assoc_doms;
+	return i - 1;
 }
 
 /*

^ permalink raw reply related

* [PATCH REPOST 3/3] powerpc/vphn: move endianness fixing to vphn_unpack_associativity()
From: Greg Kurz @ 2014-11-17 17:42 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Paul Mackerras
In-Reply-To: <20141117174216.7717.10926.stgit@bahia.local>

The first argument to vphn_unpack_associativity() is a const long *, but the
parsing code expects __be64 values actually. This is inconsistent. We should
either pass a const __be64 * or change vphn_unpack_associativity() so that
it fixes endianness by itself.

This patch does the latter, since the caller doesn't need to know about
endianness and this allows to fix significant 64-bit values only. Please
note that the previous code was able to cope with 32-bit fields being split
accross two consecutives 64-bit values. Since PAPR+ doesn't say this cannot
happen, the behaviour was kept. It requires extra checking to know when fixing
is needed though.

Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
---
 arch/powerpc/mm/numa.c |   42 +++++++++++++++++++++++++++++-------------
 1 file changed, 29 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index e30c469..903ef27 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -1417,30 +1417,49 @@ static int update_cpu_associativity_changes_mask(void)
  */
 static int vphn_unpack_associativity(const long *packed, __be32 *unpacked)
 {
-	int i;
-	const __be16 *field = (const __be16 *) packed;
+	int i, j, k;
+	union {
+		__be64 packed[VPHN_REGISTER_COUNT];
+		__be16 field[VPHN_REGISTER_COUNT * 4];
+	} fixed;
 
 #define VPHN_FIELD_UNUSED	(0xffff)
 #define VPHN_FIELD_MSB		(0x8000)
 #define VPHN_FIELD_MASK		(~VPHN_FIELD_MSB)
 
-	for (i = 1; i < VPHN_ASSOC_BUFSIZE; i++) {
-		if (be16_to_cpup(field) == VPHN_FIELD_UNUSED)
+	for (i = 1, j = 0, k = 0; i < VPHN_ASSOC_BUFSIZE;) {
+		u16 field;
+
+		if (j % 4 == 0) {
+			fixed.packed[k] = cpu_to_be64(packed[k]);
+			k++;
+		}
+
+		field = be16_to_cpu(fixed.field[j]);
+
+		if (field == VPHN_FIELD_UNUSED)
 			/* All significant fields processed.
 			 */
 			break;
 
-		if (be16_to_cpup(field) & VPHN_FIELD_MSB) {
+		if (field & VPHN_FIELD_MSB) {
 			/* Data is in the lower 15 bits of this field */
-			unpacked[i] = cpu_to_be32(
-				be16_to_cpup(field) & VPHN_FIELD_MASK);
-			field++;
+			unpacked[i++] = cpu_to_be32(field & VPHN_FIELD_MASK);
+			j++;
 		} else {
 			/* Data is in the lower 15 bits of this field
 			 * concatenated with the next 16 bit field
 			 */
-			unpacked[i] = *((__be32 *)field);
-			field += 2;
+			if (unlikely(j % 4 == 3)) {
+				/* The next field is to be copied from the next
+				 * 64-bit input value. We must fix it now.
+				 */
+				fixed.packed[k] = cpu_to_be64(packed[k]);
+				k++;
+			}
+
+			unpacked[i++] = *((__be32 *)&fixed.field[j]);
+			j += 2;
 		}
 	}
 
@@ -1460,11 +1479,8 @@ static long hcall_vphn(unsigned long cpu, __be32 *associativity)
 	long retbuf[PLPAR_HCALL9_BUFSIZE] = {0};
 	u64 flags = 1;
 	int hwcpu = get_hard_smp_processor_id(cpu);
-	int i;
 
 	rc = plpar_hcall9(H_HOME_NODE_ASSOCIATIVITY, retbuf, flags, hwcpu);
-	for (i = 0; i < VPHN_REGISTER_COUNT; i++)
-		retbuf[i] = cpu_to_be64(retbuf[i]);
 	vphn_unpack_associativity(retbuf, associativity);
 
 	return rc;

^ permalink raw reply related

* Re: [PATCH] powerpc: mitigate impact of decrementer reset
From: Paul E. McKenney @ 2014-11-17 19:18 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev, Paul Clarke
In-Reply-To: <1415846532.28703.3.camel@concordia>

On Thu, Nov 13, 2014 at 01:42:12PM +1100, Michael Ellerman wrote:
> On Mon, 2014-11-10 at 14:58 -0600, Paul Clarke wrote:
> > On 11/10/2014 04:08 AM, Benjamin Herrenschmidt wrote:
> > > On Tue, 2014-10-07 at 14:13 -0500, Paul Clarke wrote:
> > >> This patch short-circuits the reset of the decrementer, exiting after
> > >> the decrementer reset, but before the housekeeping tasks if the only
> > >> need for the interrupt is simply to reset it.  After this patch,
> > >> the latency spike was measured at about 150 nanoseconds.
> > >
> > > Doesn't this break the irq_work stuff ? We trigger it with a set_dec(1);
> > > and your patch will probably cause it to be skipped...
> > 
> > You're right.
> 
> Yeah, thanks Ben, that would have been bad.
> 
> So we'll need to come up with a different approach.
> 
> > I'm confused by the division between timer_interrupt() and 
> > __timer_interrupt().  The former is called with interrupts disabled (and 
> > enables them), but also calls irq_enter()/irq_exit().  Why are those 
> > calls not in __timer_interrupt()?  (If they were, the short-circuit 
> > logic might be a bit easier to put directly in __timer_interrupt(), 
> > which would eliminate any duplicate code.)
> > 
> > It looks like __timer_interrupt is only called directly by the broadcast 
> > timer IPI handler.  (Why is __timer_interrupt not static?)  Does this 
> > path not need irq_enter/irq_exit?
> 
> I think I answered most of this in the other mail I just sent, but let me know
> if not.
> 
> And __timer_interrupt() is static, if you have a new enough kernel :)

If I am understanding this correctly, it underscores the need for more
bits in the decrementer register.  :-/

							Thanx, Paul

^ permalink raw reply

* [PATCH net-next] PPC: bpf_jit_comp: Unify BPF_MOD | BPF_X and BPF_DIV | BPF_X
From: Denis Kirjanov @ 2014-11-17 20:07 UTC (permalink / raw)
  To: netdev
  Cc: Philippe Bergheaud, linuxppc-dev, Denis Kirjanov, Daniel Borkmann,
	Alexei Starovoitov

Reduce duplicated code by unifying
BPF_ALU | BPF_MOD | BPF_X and BPF_ALU | BPF_DIV | BPF_X

CC: Alexei Starovoitov<alexei.starovoitov@gmail.com>
CC: Daniel Borkmann<dborkman@redhat.com>
CC: Philippe Bergheaud<felix@linux.vnet.ibm.com>
Signed-off-by: Denis Kirjanov <kda@linux-powerpc.org>
---
 arch/powerpc/net/bpf_jit_comp.c | 27 ++++++++-------------------
 1 file changed, 8 insertions(+), 19 deletions(-)

diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index d3fa80d..1ca125b 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -181,6 +181,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
 			}
 			break;
 		case BPF_ALU | BPF_MOD | BPF_X: /* A %= X; */
+		case BPF_ALU | BPF_DIV | BPF_X: /* A /= X; */
 			ctx->seen |= SEEN_XREG;
 			PPC_CMPWI(r_X, 0);
 			if (ctx->pc_ret0 != -1) {
@@ -190,9 +191,13 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
 				PPC_LI(r_ret, 0);
 				PPC_JMP(exit_addr);
 			}
-			PPC_DIVWU(r_scratch1, r_A, r_X);
-			PPC_MUL(r_scratch1, r_X, r_scratch1);
-			PPC_SUB(r_A, r_A, r_scratch1);
+			if (code == (BPF_ALU | BPF_MOD | BPF_X)) {
+				PPC_DIVWU(r_scratch1, r_A, r_X);
+				PPC_MUL(r_scratch1, r_X, r_scratch1);
+				PPC_SUB(r_A, r_A, r_scratch1);
+			} else {
+				PPC_DIVWU(r_A, r_A, r_X);
+			}
 			break;
 		case BPF_ALU | BPF_MOD | BPF_K: /* A %= K; */
 			PPC_LI32(r_scratch2, K);
@@ -200,22 +205,6 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
 			PPC_MUL(r_scratch1, r_scratch2, r_scratch1);
 			PPC_SUB(r_A, r_A, r_scratch1);
 			break;
-		case BPF_ALU | BPF_DIV | BPF_X: /* A /= X; */
-			ctx->seen |= SEEN_XREG;
-			PPC_CMPWI(r_X, 0);
-			if (ctx->pc_ret0 != -1) {
-				PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]);
-			} else {
-				/*
-				 * Exit, returning 0; first pass hits here
-				 * (longer worst-case code size).
-				 */
-				PPC_BCC_SHORT(COND_NE, (ctx->idx*4)+12);
-				PPC_LI(r_ret, 0);
-				PPC_JMP(exit_addr);
-			}
-			PPC_DIVWU(r_A, r_A, r_X);
-			break;
 		case BPF_ALU | BPF_DIV | BPF_K: /* A /= K */
 			if (K == 1)
 				break;
-- 
2.1.0

^ permalink raw reply related

* [PATCH v2 0/6] pseries: Move memory hotplug to the kernel
From: Nathan Fontenot @ 2014-11-17 21:44 UTC (permalink / raw)
  To: linuxppc-dev@lists.ozlabs.org

In order to better support device hotplug (cpu, memory, and pci) in the
PowerVM and PowerKVM environments, the handling of device hotplug
could be updated so that the act of hotplugging a device occurs entirely
in the kernel. This patch set begins to address this by moving
memory hotplug to the kernel. Patches to follow will do the same
for cpu and pci devices.

To provide background, the current handling of memory hotplug is
handled by the drmgr command. This command is invoked when memory
add/remove requests are made at the HMC and conveyed to a partition
through the RSCT framework. The drmgr command then performs parts
of the hotplug in user-space and makes requests to the kernel to perform
other pieces. This is not really ideal, we can do everything in the
kernel and do it faster.

In this patchset, hotplug events will now be communicated to the kernel
in the form of rtas hotplug events. For PowerKVM systems this is done
by qemu using the ras epow interrupt. For PowerVM systems the drmgr
command will be updated to create a rtas hotplug event and send it to
the kernel via a new /sys/kernel/dlpar interface. Both of these
entry points for hotplug rtas events then call a common routine
for handling rtas hotplug events.

-Nathan

Patch 1/6
- Add definition of hotplug rtas event sections.

Patch 2/6
- Update struct of_drconf_cell to use __be64/__be32
 
Patch 3/6
- Export the dlpar_[acquire|release]drc() routines.

Patch 4/6
- Create the new /sys/kernel/dlpar interface

Patch 5/6
- Implement memory hotplug add in the kernel.

Patch 6/6
- Implement memory hotplug remove in the kernel.

 include/asm/prom.h                 |   10 
 include/asm/rtas.h                 |   26 ++
 platforms/pseries/dlpar.c          |   72 +++++
 platforms/pseries/hotplug-memory.c |  469 ++++++++++++++++++++++++++++++++++++-
 platforms/pseries/pseries.h        |   12 
 5 files changed, 576 insertions(+), 13 deletions(-)

^ permalink raw reply

* [PATCH v2 1/6] pseries: Define rtas hotplug event sections
From: Nathan Fontenot @ 2014-11-17 21:48 UTC (permalink / raw)
  To: linuxppc-dev@lists.ozlabs.org
In-Reply-To: <546A6C23.1080800@linux.vnet.ibm.com>

In order to handle device hotplug in the kernel on pseries hotplug
notifications will be communicated to the kernel in the form of a
rtas hotplug events. This patch adds the definition of rtas hotplug event
sections.

Signed-off-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/rtas.h |   26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index b390f55..77e112e 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -273,6 +273,7 @@ inline uint32_t rtas_ext_event_company_id(struct rtas_ext_event_log_v6 *ext_log)
 #define PSERIES_ELOG_SECT_ID_MANUFACT_INFO	(('M' << 8) | 'I')
 #define PSERIES_ELOG_SECT_ID_CALL_HOME		(('C' << 8) | 'H')
 #define PSERIES_ELOG_SECT_ID_USER_DEF		(('U' << 8) | 'D')
+#define PSERIES_ELOG_SECT_ID_HOTPLUG		(('H' << 8) | 'P')
 
 /* Vendor specific Platform Event Log Format, Version 6, section header */
 struct pseries_errorlog {
@@ -296,6 +297,31 @@ inline uint16_t pseries_errorlog_length(struct pseries_errorlog *sect)
 	return be16_to_cpu(sect->length);
 }
 
+/* RTAS pseries hotplug errorlog section */
+struct pseries_hp_errorlog {
+	u8	resource;
+	u8	action;
+	u8	id_type;
+	u8	reserved;
+	union {
+		__be32	drc_index;
+		__be32	drc_count;
+		char	drc_name[1];
+	} _drc_u;
+};
+
+#define PSERIES_HP_ELOG_RESOURCE_CPU	1
+#define PSERIES_HP_ELOG_RESOURCE_MEM	2
+#define PSERIES_HP_ELOG_RESOURCE_SLOT	3
+#define PSERIES_HP_ELOG_RESOURCE_PHB	4
+
+#define PSERIES_HP_ELOG_ACTION_ADD	1
+#define PSERIES_HP_ELOG_ACTION_REMOVE	2
+
+#define PSERIES_HP_ELOG_ID_DRC_NAME	1
+#define PSERIES_HP_ELOG_ID_DRC_INDEX	2
+#define PSERIES_HP_ELOG_ID_DRC_COUNT	3
+
 struct pseries_errorlog *get_pseries_errorlog(struct rtas_error_log *log,
 					      uint16_t section_id);
 

^ permalink raw reply related

* [PATCH v2 2/6] pseries: Update of_drconf_cell struct for endian-ness
From: Nathan Fontenot @ 2014-11-17 21:50 UTC (permalink / raw)
  To: linuxppc-dev@lists.ozlabs.org
In-Reply-To: <546A6C23.1080800@linux.vnet.ibm.com>

The of_drconf_cell defines each LMB for a system in the device tree property
ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory. The values are
in BE format by definition, this patch updates the of_drconf_cell struct
to reflect the proper endian-ness.

Signed-off-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/prom.h |   10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index 7f436ba..6f1cbe3 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -85,11 +85,11 @@ extern int of_get_ibm_chip_id(struct device_node *np);
  * ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory
  */
 struct of_drconf_cell {
-	u64	base_addr;
-	u32	drc_index;
-	u32	reserved;
-	u32	aa_index;
-	u32	flags;
+	__be64	base_addr;
+	__be32	drc_index;
+	__be32	reserved;
+	__be32	aa_index;
+	__be32	flags;
 };
 
 #define DRCONF_MEM_ASSIGNED	0x00000008

^ permalink raw reply related

* [PATCH v2 3/6] pseries: Create new device hotplug entry point
From: Nathan Fontenot @ 2014-11-17 21:51 UTC (permalink / raw)
  To: linuxppc-dev@lists.ozlabs.org, Michael Ellerman
In-Reply-To: <546A6C23.1080800@linux.vnet.ibm.com>

Create a new entry point for device hotplug on pseries that will
work for both PowerVM and PowerKVM systems.

The current process to hotplug (or dlpar) devices (generally the same
process for memory, cpu, and pci devices) on PowerVM systems is initiated
from the HMC, which communicates the request to the partitions through
the RSCT framework. The RSCT framework then invokes the drmgr command.
The drmgr command performs the hotplug operation by doing some pieces,
such as most of the rtas calls and device tree parsing, in userspace
and make requests to the kernel to online/offline the device, update the
device tree and add/remove the device.

For PowerKVM the approach for device hotplug is to follow what is currently
being done for pci hotplug. A hotplug request is initiated from the host,
QEMU then generates an EPOW interrupt to the guest which causes the guest
to make the rtas,check-exception call. In QEMU, the rtas,check-exception call
returns a rtas hotplug event to the guest.

Please note that the current pci hotplug path for PowerKVM involves the
kernel receiving the rtas hotplug event, passing it to rtas_errd in
userspace, and having rtas_errd invoke drmgr. The drmgr command then
handles the request as described above for PowerVM systems. This is to
be updated to perform pci completely in the kernel in a later patch set.

There is no need for this circuitous route, we should handle the entire
hotplug of devices in the kernel. What I am planning is to enable this
by moving the code to handle device hotplug from drmgr into the kernel to
provide a single path for both PowerVM and PowerKVM systems. This patch
provides the common entry point. For PowerKVM a future update to the kernel
rtas code will recognize rtas hotplug events returned from
rtas,check-exception calls and use the common entry point to handle device
hotplug entirely in the kernel.

For PowerVM systems, this patch creates the /sys/kernel/dlpar file that rtas
hotplug events can be written to by drmgr and passed to the common entry point.
There is no chance of updating how we receive hotplug requests on PowerVM
systems.

Signed-off-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/pseries/dlpar.c          |   72 ++++++++++++++++++++++-
 arch/powerpc/platforms/pseries/hotplug-memory.c |   19 ++++++
 arch/powerpc/platforms/pseries/pseries.h        |   10 +++
 3 files changed, 99 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
index c22bb1b..ec825d3 100644
--- a/arch/powerpc/platforms/pseries/dlpar.c
+++ b/arch/powerpc/platforms/pseries/dlpar.c
@@ -10,6 +10,8 @@
  * 2 as published by the Free Software Foundation.
  */
 
+#define pr_fmt(fmt)	"dlpar: " fmt
+
 #include <linux/kernel.h>
 #include <linux/notifier.h>
 #include <linux/spinlock.h>
@@ -535,13 +537,79 @@ static ssize_t dlpar_cpu_release(const char *buf, size_t count)
 	return count;
 }
 
+#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
+
+static int handle_dlpar_errorlog(struct rtas_error_log *error_log)
+{
+	struct pseries_errorlog *pseries_log;
+	struct pseries_hp_errorlog *hp_elog;
+	int rc;
+
+	pseries_log = get_pseries_errorlog(error_log,
+					   PSERIES_ELOG_SECT_ID_HOTPLUG);
+	if (!pseries_log || (pseries_log->length == 0))
+		return -EINVAL;
+
+	hp_elog = (struct pseries_hp_errorlog *)pseries_log->data;
+
+	/* Go ahead and convert the hotplug type to the correct endianness
+	 * to avoid converting it everywhere we use it.
+	 */
+	switch (hp_elog->id_type) {
+	case PSERIES_HP_ELOG_ID_DRC_COUNT:
+		hp_elog->_drc_u.drc_count =
+					be32_to_cpu(hp_elog->_drc_u.drc_count);
+	case PSERIES_HP_ELOG_ID_DRC_INDEX:
+		hp_elog->_drc_u.drc_index =
+					be32_to_cpu(hp_elog->_drc_u.drc_index);
+	}
+
+	switch (hp_elog->resource) {
+	case PSERIES_HP_ELOG_RESOURCE_MEM:
+		rc = dlpar_memory(hp_elog);
+		break;
+	default:
+		pr_warn_ratelimited("Invalid resource (%d) specified\n",
+				    hp_elog->resource);
+		rc = -EINVAL;
+		break;
+	}
+
+	return rc;
+}
+
+static ssize_t dlpar_store(struct file *filp, struct kobject *kobj,
+			   struct bin_attribute *bin_attr, char *buf,
+			   loff_t pos, size_t count)
+{
+	struct rtas_error_log *error_log;
+	int rc;
+
+	error_log = kmalloc(count, GFP_KERNEL);
+	if (!error_log)
+		return -ENOMEM;
+
+	memcpy(error_log, buf, count);
+
+	rc = handle_dlpar_errorlog(error_log);
+	kfree(error_log);
+	return rc ? rc : count;
+}
+
+static BIN_ATTR(dlpar, S_IWUSR, NULL, dlpar_store, 0);
+
 static int __init pseries_dlpar_init(void)
 {
+	int rc;
+
+#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
 	ppc_md.cpu_probe = dlpar_cpu_probe;
 	ppc_md.cpu_release = dlpar_cpu_release;
+#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
 
-	return 0;
+	rc = sysfs_create_bin_file(kernel_kobj, &bin_attr_dlpar);
+
+	return rc;
 }
 machine_device_initcall(pseries, pseries_dlpar_init);
 
-#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index 3cb256c..69d178b 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -9,6 +9,8 @@
  *      2 of the License, or (at your option) any later version.
  */
 
+#define pr_fmt(fmt)	"pseries-hotplug-mem: " fmt
+
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/memblock.h>
@@ -134,6 +136,23 @@ static inline int pseries_remove_mem_node(struct device_node *np)
 }
 #endif /* CONFIG_MEMORY_HOTREMOVE */
 
+int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
+{
+	int rc = 0;
+
+	lock_device_hotplug();
+
+	switch (hp_elog->action) {
+	default:
+		pr_err("Invalid action (%d) specified\n", hp_elog->action);
+		rc = -EINVAL;
+		break;
+	}
+
+	unlock_device_hotplug();
+	return rc;
+}
+
 static int pseries_add_mem_node(struct device_node *np)
 {
 	const char *type;
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
index 239bee5..40e0339 100644
--- a/arch/powerpc/platforms/pseries/pseries.h
+++ b/arch/powerpc/platforms/pseries/pseries.h
@@ -11,6 +11,7 @@
 #define _PSERIES_PSERIES_H
 
 #include <linux/interrupt.h>
+#include <asm/rtas.h>
 
 struct device_node;
 
@@ -63,6 +64,15 @@ extern int dlpar_detach_node(struct device_node *);
 int dlpar_acquire_drc(u32 drc_index);
 int dlpar_release_drc(u32 drc_index);
 
+#ifdef CONFIG_MEMORY_HOTPLUG
+int dlpar_memory(struct pseries_hp_errorlog *hp_elog);
+#else
+static inline int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
+{
+	return -EOPNOTSUPP;
+}
+#endif
+
 /* PCI root bridge prepare function override for pseries */
 struct pci_host_bridge;
 int pseries_root_bridge_prepare(struct pci_host_bridge *bridge);

^ permalink raw reply related

* [PATCH v2 4/6] pseries: Export the acquire/release drc index routines
From: Nathan Fontenot @ 2014-11-17 21:53 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <546A6C23.1080800@linux.vnet.ibm.com>

Export the routines to acquire and release a drc index.

Signed-off-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/pseries/pseries.h |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
index 1796c54..239bee5 100644
--- a/arch/powerpc/platforms/pseries/pseries.h
+++ b/arch/powerpc/platforms/pseries/pseries.h
@@ -60,6 +60,8 @@ extern struct device_node *dlpar_configure_connector(__be32,
 						struct device_node *);
 extern int dlpar_attach_node(struct device_node *);
 extern int dlpar_detach_node(struct device_node *);
+int dlpar_acquire_drc(u32 drc_index);
+int dlpar_release_drc(u32 drc_index);
 
 /* PCI root bridge prepare function override for pseries */
 struct pci_host_bridge;

^ permalink raw reply related

* [PATCH v2 5/6] pseries: Implement memory hotplug add in the kernel
From: Nathan Fontenot @ 2014-11-17 21:54 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <546A6C23.1080800@linux.vnet.ibm.com>

Move handling of memory hotplug add on pseries completely into the kernel.

The current memory hotplug add path involves the drmgr command doing part
of this work in userspace and requesting the kernel to do additional pieces.
This patch allows us to handle the act completely in the kernel via rtas
hotplug events. This allows us to perform the operation faster and provide
a common memory hotplug add path for PowerVM and PowerKVM systems.

The patch does introduce a static rtas_hp_event variable that is set to
true when updating the device tree during memory hotplug initiated from
a rtas hotplug event. This is needed because we do not need to do the
work in the of notifier, this work is already performed in handling the
hotplug request. At a later time we can remove this when we deprecate the
previous method of memory hotplug.

Signed-off-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/pseries/hotplug-memory.c |  244 +++++++++++++++++++++++
 1 file changed, 243 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index 69d178b..b57d42b 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -16,6 +16,7 @@
 #include <linux/memblock.h>
 #include <linux/memory.h>
 #include <linux/memory_hotplug.h>
+#include <linux/slab.h>
 
 #include <asm/firmware.h>
 #include <asm/machdep.h>
@@ -23,6 +24,8 @@
 #include <asm/sparsemem.h>
 #include "pseries.h"
 
+static bool rtas_hp_event;
+
 unsigned long pseries_memory_block_size(void)
 {
 	struct device_node *np;
@@ -66,6 +69,52 @@ unsigned long pseries_memory_block_size(void)
 	return memblock_size;
 }
 
+static void dlpar_free_drconf_property(struct property *prop)
+{
+	kfree(prop->name);
+	kfree(prop->value);
+	kfree(prop);
+}
+
+static struct property *dlpar_clone_drconf_property(struct device_node *dn)
+{
+	struct property *prop, *new_prop;
+
+	prop = of_find_property(dn, "ibm,dynamic-memory", NULL);
+	if (!prop)
+		return NULL;
+
+	new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL);
+	if (!new_prop)
+		return NULL;
+
+	new_prop->name = kstrdup(prop->name, GFP_KERNEL);
+	new_prop->value = kmalloc(prop->length, GFP_KERNEL);
+	if (!new_prop->name || !new_prop->value) {
+		dlpar_free_drconf_property(new_prop);
+		return NULL;
+	}
+
+	memcpy(new_prop->value, prop->value, prop->length);
+	new_prop->length = prop->length;
+
+	return new_prop;
+}
+
+static struct memory_block *lmb_to_memblock(struct of_drconf_cell *lmb)
+{
+	unsigned long section_nr;
+	struct mem_section *mem_sect;
+	struct memory_block *mem_block;
+	u64 phys_addr = be64_to_cpu(lmb->base_addr);
+
+	section_nr = pfn_to_section_nr(PFN_DOWN(phys_addr));
+	mem_sect = __nr_to_section(section_nr);
+
+	mem_block = find_memory_block(mem_sect);
+	return mem_block;
+}
+
 #ifdef CONFIG_MEMORY_HOTREMOVE
 static int pseries_remove_memblock(unsigned long base, unsigned int memblock_size)
 {
@@ -136,19 +185,209 @@ static inline int pseries_remove_mem_node(struct device_node *np)
 }
 #endif /* CONFIG_MEMORY_HOTREMOVE */
 
+static int dlpar_add_lmb(struct of_drconf_cell *lmb)
+{
+	struct memory_block *mem_block;
+	u64 phys_addr;
+	uint32_t drc_index;
+	unsigned long pages_per_block;
+	unsigned long block_sz;
+	int nid, sections_per_block;
+	int rc;
+
+	if (be32_to_cpu(lmb->flags) & DRCONF_MEM_ASSIGNED)
+		return -EINVAL;
+
+	phys_addr = be64_to_cpu(lmb->base_addr);
+	drc_index = be32_to_cpu(lmb->drc_index);
+	block_sz = memory_block_size_bytes();
+	sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE;
+	pages_per_block = PAGES_PER_SECTION * sections_per_block;
+
+	if (phys_addr & ((pages_per_block << PAGE_SHIFT) - 1))
+		return -EINVAL;
+
+	rc = dlpar_acquire_drc(drc_index);
+	if (rc)
+		return rc;
+
+	/* Find the node id for this address */
+	nid = memory_add_physaddr_to_nid(phys_addr);
+
+	/* Add the memory */
+	rc = add_memory(nid, phys_addr, block_sz);
+	if (rc) {
+		dlpar_release_drc(drc_index);
+		return rc;
+	}
+
+	/* Register this block of memory */
+	rc = memblock_add(phys_addr, block_sz);
+	if (rc) {
+		remove_memory(nid, phys_addr, block_sz);
+		dlpar_release_drc(drc_index);
+		return rc;
+	}
+
+	mem_block = lmb_to_memblock(lmb);
+	if (!mem_block) {
+		remove_memory(nid, phys_addr, block_sz);
+		dlpar_release_drc(drc_index);
+		return -EINVAL;
+	}
+
+	rc = device_online(&mem_block->dev);
+	put_device(&mem_block->dev);
+	if (rc) {
+		remove_memory(nid, phys_addr, block_sz);
+		dlpar_release_drc(drc_index);
+		return rc;
+	}
+
+	lmb->flags |= cpu_to_be32(DRCONF_MEM_ASSIGNED);
+	return 0;
+}
+
+static int dlpar_memory_add_by_count(struct pseries_hp_errorlog *hp_elog,
+				     struct property *prop)
+{
+	struct of_drconf_cell *lmbs;
+	uint32_t num_lmbs;
+	__be32 *p;
+	int i, lmbs_to_add;
+	int lmbs_available = 0;
+	int lmbs_added = 0;
+	int rc;
+
+	lmbs_to_add = be32_to_cpu(hp_elog->_drc_u.drc_count);
+	pr_info("Attempting to hot-add %d LMB(s)\n", lmbs_to_add);
+
+	if (lmbs_to_add == 0)
+		return -EINVAL;
+
+	p = prop->value;
+	num_lmbs = be32_to_cpu(*p++);
+	lmbs = (struct of_drconf_cell *)p;
+
+	/* Validate that there are enough LMBs to satisfy the request */
+	for (i = 0; i < num_lmbs; i++) {
+		if (!(be32_to_cpu(lmbs[i].flags) & DRCONF_MEM_ASSIGNED))
+			lmbs_available++;
+	}
+
+	if (lmbs_available < lmbs_to_add)
+		return -EINVAL;
+
+	for (i = 0; i < num_lmbs; i++) {
+		if (lmbs_to_add == lmbs_added)
+			break;
+
+		rc = dlpar_add_lmb(&lmbs[i]);
+		if (rc)
+			continue;
+
+		lmbs_added++;
+		pr_info("Memory at %llx (drc index %x) has been hot-added\n",
+			be64_to_cpu(lmbs[i].base_addr),
+			be32_to_cpu(lmbs[i].drc_index));
+
+		/* Mark this lmb so we can remove it later if all of the
+		 * requested LMBs cannot be added.
+		 */
+		lmbs[i].reserved = 1;
+	}
+
+	if (lmbs_added != lmbs_to_add) {
+		/* TODO: remove added lmbs */
+		rc = -EINVAL;
+	}
+
+	/* Clear the reserved fields */
+	for (i = 0; i < num_lmbs; i++)
+		lmbs[i].reserved = 0;
+
+	return rc;
+}
+
+static int dlpar_memory_add_by_index(struct pseries_hp_errorlog *hp_elog,
+				     struct property *prop)
+{
+	struct of_drconf_cell *lmbs;
+	uint32_t num_lmbs, drc_index;
+	__be32 *p;
+	int i, lmb_found;
+	int rc;
+
+	drc_index = be32_to_cpu(hp_elog->_drc_u.drc_index);
+	pr_info("Attempting to hot-add LMB, drc index %x\n", drc_index);
+
+	p = prop->value;
+	num_lmbs = be32_to_cpu(*p++);
+	lmbs = (struct of_drconf_cell *)p;
+
+	lmb_found = 0;
+	for (i = 0; i < num_lmbs; i++) {
+		if (lmbs[i].drc_index == hp_elog->_drc_u.drc_index) {
+			lmb_found = 1;
+			rc = dlpar_add_lmb(&lmbs[i]);
+			break;
+		}
+	}
+
+	if (!lmb_found)
+		rc = -EINVAL;
+
+	if (rc)
+		pr_info("Failed to hot-add memory, drc index %x\n", drc_index);
+	else
+		pr_info("Memory at %llx (drc index %x) has been hot-added\n",
+			be64_to_cpu(lmbs[i].base_addr), drc_index);
+
+	return rc;
+}
+
 int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
 {
-	int rc = 0;
+	struct device_node *dn;
+	struct property *prop;
+	int rc;
 
 	lock_device_hotplug();
 
+	dn = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
+	if (!dn)
+		return -EINVAL;
+
+	prop = dlpar_clone_drconf_property(dn);
+	if (!prop) {
+		of_node_put(dn);
+		return -EINVAL;
+	}
+
 	switch (hp_elog->action) {
+	case PSERIES_HP_ELOG_ACTION_ADD:
+		if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_COUNT)
+			rc = dlpar_memory_add_by_count(hp_elog, prop);
+		else if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_INDEX)
+			rc = dlpar_memory_add_by_index(hp_elog, prop);
+		else
+			rc = -EINVAL;
+		break;
 	default:
 		pr_err("Invalid action (%d) specified\n", hp_elog->action);
 		rc = -EINVAL;
 		break;
 	}
 
+	if (rc)
+		dlpar_free_drconf_property(prop);
+	else {
+		rtas_hp_event = true;
+		of_update_property(dn, prop);
+		rtas_hp_event = false;
+	}
+
+	of_node_put(dn);
 	unlock_device_hotplug();
 	return rc;
 }
@@ -193,6 +432,9 @@ static int pseries_update_drconf_memory(struct of_prop_reconfig *pr)
 	__be32 *p;
 	int i, rc = -EINVAL;
 
+	if (rtas_hp_event)
+		return 0;
+
 	memblock_size = pseries_memory_block_size();
 	if (!memblock_size)
 		return -EINVAL;

^ permalink raw reply related

* [PATCH v2 6/6] pseries: Implement memory hotplug remove in the kernel
From: Nathan Fontenot @ 2014-11-17 21:56 UTC (permalink / raw)
  To: linuxppc-dev@lists.ozlabs.org
In-Reply-To: <546A6C23.1080800@linux.vnet.ibm.com>

Move handling of memory hotplug remove on pseries completely into the kernel.

The current memory hotplug remove path involves the drmgr command doing part
of this work in userspace and requesting the kernel to do additional pieces.
This patch allows us to handle the act completely in the kernel via rtas
hotplug events. This allows us to perform the operation faster and provide
a common memory hotplug remove path for PowerVM and PowerKVM systems.

Signed-off-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/pseries/hotplug-memory.c |  206 ++++++++++++++++++++++-
 1 file changed, 201 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index b57d42b..c8189e8 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -173,6 +173,179 @@ static int pseries_remove_mem_node(struct device_node *np)
 	pseries_remove_memblock(base, lmb_size);
 	return 0;
 }
+
+static int lmb_is_removable(struct of_drconf_cell *lmb)
+{
+	int i, scns_per_block;
+	int rc = 1;
+	unsigned long pfn, block_sz;
+	u64 phys_addr;
+
+	if (!(be32_to_cpu(lmb->flags) & DRCONF_MEM_ASSIGNED))
+		return -1;
+
+	phys_addr = be64_to_cpu(lmb->base_addr);
+	block_sz = memory_block_size_bytes();
+	scns_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE;
+
+	for (i = 0; i < scns_per_block; i++) {
+		pfn = PFN_DOWN(phys_addr);
+		if (!pfn_present(pfn))
+			continue;
+
+		rc &= is_mem_section_removable(pfn, PAGES_PER_SECTION);
+		phys_addr += MIN_MEMORY_BLOCK_SIZE;
+	}
+
+	return rc;
+}
+
+static int dlpar_add_lmb(struct of_drconf_cell *);
+
+static int dlpar_remove_lmb(struct of_drconf_cell *lmb)
+{
+	struct memory_block *mem_block;
+	unsigned long block_sz;
+	u64 phys_addr;
+	uint32_t drc_index;
+	int nid, rc;
+
+	if (!lmb_is_removable(lmb))
+		return -EINVAL;
+
+	phys_addr = be64_to_cpu(lmb->base_addr);
+	drc_index = be32_to_cpu(lmb->drc_index);
+
+	mem_block = lmb_to_memblock(lmb);
+	if (!mem_block)
+		return -EINVAL;
+
+	rc = device_offline(&mem_block->dev);
+	put_device(&mem_block->dev);
+	if (rc)
+		return rc;
+
+	block_sz = pseries_memory_block_size();
+	nid = memory_add_physaddr_to_nid(phys_addr);
+
+	remove_memory(nid, phys_addr, block_sz);
+
+	/* Update memory regions for memory remove */
+	memblock_remove(phys_addr, block_sz);
+
+	dlpar_release_drc(drc_index);
+
+	lmb->flags &= cpu_to_be32(~DRCONF_MEM_ASSIGNED);
+	pr_info("Memory at %llx (drc index %x) has been hot-removed\n",
+		be64_to_cpu(lmb->base_addr), drc_index);
+
+	return 0;
+}
+
+static int dlpar_memory_remove_by_count(struct pseries_hp_errorlog *hp_elog,
+					struct property *prop)
+{
+	struct of_drconf_cell *lmbs;
+	int lmbs_to_remove, lmbs_removed = 0;
+	int lmbs_available = 0;
+	uint32_t num_lmbs;
+	__be32 *p;
+	int i, rc;
+
+	lmbs_to_remove = be32_to_cpu(hp_elog->_drc_u.drc_count);
+	pr_info("Attempting to hot-remove %d LMB(s)\n", lmbs_to_remove);
+
+	if (lmbs_to_remove == 0)
+		return -EINVAL;
+
+	p = prop->value;
+	num_lmbs = be32_to_cpu(*p++);
+	lmbs = (struct of_drconf_cell *)p;
+
+	/* Validate that there are enough LMBs to satisfy the request */
+	for (i = 0; i < num_lmbs; i++) {
+		if (be32_to_cpu(lmbs[i].flags) & DRCONF_MEM_ASSIGNED)
+			lmbs_available++;
+	}
+
+	if (lmbs_available < lmbs_to_remove)
+		return -EINVAL;
+
+	for (i = 0; i < num_lmbs; i++) {
+		if (lmbs_to_remove == lmbs_removed)
+			break;
+
+		rc = dlpar_remove_lmb(&lmbs[i]);
+		if (rc)
+			continue;
+
+		lmbs_removed++;
+
+		/* Mark this lmb so we can add it later if all of the
+		 * requested LMBs cannot be removed.
+		 */
+		lmbs[i].reserved = 1;
+	}
+
+	if (lmbs_removed != lmbs_to_remove) {
+		pr_err("Memory hot-remove failed, adding LMB's back\n");
+
+		for (i = 0; i < num_lmbs; i++) {
+			if (!lmbs[i].reserved)
+				continue;
+
+			rc = dlpar_add_lmb(&lmbs[i]);
+			if (rc)
+				pr_err("Failed to add LMB back, drc index %x\n",
+				       be32_to_cpu(lmbs[i].drc_index));
+
+			lmbs[i].reserved = 0;
+		}
+		rc = -EINVAL;
+	} else {
+		/* remove any reserved markings */
+		for (i = 0; i < num_lmbs; i++)
+			lmbs[i].reserved = 0;
+	}
+
+	return rc;
+}
+
+static int dlpar_memory_remove_by_index(struct pseries_hp_errorlog *hp_elog,
+					struct property *prop)
+{
+	struct of_drconf_cell *lmbs;
+	uint32_t num_lmbs, drc_index;
+	int lmb_found;
+	__be32 *p;
+	int i, rc;
+
+	drc_index = be32_to_cpu(hp_elog->_drc_u.drc_index);
+	pr_info("Attempting to hot-remove LMB, drc index %x\n", drc_index);
+
+	p = prop->value;
+	num_lmbs = be32_to_cpu(*p++);
+	lmbs = (struct of_drconf_cell *)p;
+
+	lmb_found = 0;
+	for (i = 0; i < num_lmbs; i++) {
+		if (lmbs[i].drc_index == hp_elog->_drc_u.drc_index) {
+			lmb_found = 1;
+			rc = dlpar_remove_lmb(&lmbs[i]);
+			break;
+		}
+	}
+
+	if (!lmb_found)
+		rc = -EINVAL;
+
+	if (rc)
+		pr_info("Failed to hot-remove memory, drc index %x\n",
+			drc_index);
+
+	return rc;
+}
+
 #else
 static inline int pseries_remove_memblock(unsigned long base,
 					  unsigned int memblock_size)
@@ -183,6 +356,11 @@ static inline int pseries_remove_mem_node(struct device_node *np)
 {
 	return 0;
 }
+static inline int dlpar_memory_remove(struct pseries_hp_errorlog *hp_elog)
+{
+	return -EOPNOTSUPP;
+}
+
 #endif /* CONFIG_MEMORY_HOTREMOVE */
 
 static int dlpar_add_lmb(struct of_drconf_cell *lmb)
@@ -298,14 +476,24 @@ static int dlpar_memory_add_by_count(struct pseries_hp_errorlog *hp_elog,
 	}
 
 	if (lmbs_added != lmbs_to_add) {
-		/* TODO: remove added lmbs */
+		pr_err("Memory hot-add failed, removing any added LMBs\n");
+
+		for (i = 0; i < num_lmbs; i++) {
+			if (!lmbs[i].reserved)
+				continue;
+
+			rc = dlpar_remove_lmb(&lmbs[i]);
+			if (rc)
+				pr_err("Failed to remove LMB, drc index %x\n",
+				       be32_to_cpu(lmbs[i].drc_index));
+		}
 		rc = -EINVAL;
+	} else {
+		/* Clear the reserved fields */
+		for (i = 0; i < num_lmbs; i++)
+			lmbs[i].reserved = 0;
 	}
 
-	/* Clear the reserved fields */
-	for (i = 0; i < num_lmbs; i++)
-		lmbs[i].reserved = 0;
-
 	return rc;
 }
 
@@ -373,6 +561,14 @@ int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
 		else
 			rc = -EINVAL;
 		break;
+	case PSERIES_HP_ELOG_ACTION_REMOVE:
+		if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_COUNT)
+			rc = dlpar_memory_remove_by_count(hp_elog, prop);
+		else if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_INDEX)
+			rc = dlpar_memory_remove_by_index(hp_elog, prop);
+		else
+			rc = -EINVAL;
+		break;
 	default:
 		pr_err("Invalid action (%d) specified\n", hp_elog->action);
 		rc = -EINVAL;

^ permalink raw reply related

* Re: [PATCH 2/2] powerpc/mpc85xx: Add DPAA Q/BMan support to device tree(s)
From: Scott Wood @ 2014-11-17 22:13 UTC (permalink / raw)
  To: Emil Medve; +Cc: linuxppc-dev, Geoff Thorpe, Poonam Aggrwal, Chunhe Lan
In-Reply-To: <5469CE79.7090406@Freescale.com>

On Mon, 2014-11-17 at 04:31 -0600, Emil Medve wrote:
> Hello Scott,
> 
> 
> On 11/13/2014 03:42 PM, Scott Wood wrote:
> > On Thu, 2014-11-13 at 03:21 -0600, Emil Medve wrote:
> >> From: Kumar Gala <galak@kernel.crashing.org>
> >>
> >> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
> >> Signed-off-by: Geoff Thorpe <Geoff.Thorpe@freescale.com>
> >> Signed-off-by: Hai-Ying Wang <Haiying.Wang@freescale.com>
> >> Signed-off-by: Chunhe Lan <Chunhe.Lan@freescale.com>
> >> Signed-off-by: Poonam Aggrwal <poonam.aggrwal@freescale.com>
> >> Signed-off-by: Emil Medve <Emilian.Medve@Freescale.com>
> >> Change-Id: If643fa5ba0a903aef8f5056a2c90ebecc995b760
> > 
> > I suspect these patches are changed quite a bit from Kumar's version...
> 
> Across SDK releases I've been trying retain the authors names and the
> 'Signed-off-by' list is the only place that can accommodate them all.
> Kumar is the first author, and besides this exercise the most significant
> 
> > It's good to note changes after the listed author has stopped being
> > involved, so they don't get the blame for anything they wouldn't have
> > put in there.
> 
> Bah. Most of the sordid history is lost

You don't need the full history.  If Kumar wrote most of it then he
should stay as the From: line, but maybe put a line before your signoff,
something like:
[Emil: various updates]
to indicate it wasn't passed on as is, as is recommended in
Documentation/SubmittingPatches.

> > no-map and reusable don't make sense together.  How can the OS reuse the
> > memory if it can't map it?
> 
> Perhaps I've been reading/speculating(?) too much about it. Now granted
> the code is still young (?), but in between "under the control of the
> device driver using the region" and "the device driver(s) owning the
> region need to be able to reclaim it back" it sort of made sense

No-map says to never map the region except under control of the driver.
Reusable says it's ok to use the region (which implies mapping) outside
the control of the driver, except when the driver claims the region via
some unspecified mechanism.

FWIW, the one place I can find in the code that currently insists on
"reusable" rejects regions with "no-map" (rmem_cma_setup), and the one
place I can find that currently insists on "no-map" rejects regions with
"reusable" (rmem_dma_setup).

> > no-map is burdensome (and I believe not yet implemented) on mpc85xx,
> > where we want to use huge TLB entries to cover all of (low) memory.  Is
> > it really needed?
> 
> I'm thinking no-map would be part of having/making this reserved memory
> into a different coherency domain then the... everything else

OK, but it's not actually required to use a different coherency domain.
You're putting configuration into the device tree, and it's a
particularly burdensome bit of configuration on mpc85xx due to the way
the TLB works (it also doesn't currently work as advertised on PPC).
Have you benchmarked to see what the benefit is of using a separate
coherence domain?

> > What do we gain from specifying reusable here?
> 
> I guess the obvious of having this memory usable for something else when
> the B/QMan drivers don't use it

When would they not use it?

> > How is it actually supposed to work?
> 
> You mean how should one implement 'reusable'?

Yes.

-Scott

^ permalink raw reply

* Re: [PATCH v2 3/6] pseries: Create new device hotplug entry point
From: Gavin Shan @ 2014-11-17 22:53 UTC (permalink / raw)
  To: Nathan Fontenot; +Cc: linuxppc-dev@lists.ozlabs.org
In-Reply-To: <546A6DEE.8080708@linux.vnet.ibm.com>

On Mon, Nov 17, 2014 at 03:51:42PM -0600, Nathan Fontenot wrote:
>Create a new entry point for device hotplug on pseries that will
>work for both PowerVM and PowerKVM systems.
>
>The current process to hotplug (or dlpar) devices (generally the same
>process for memory, cpu, and pci devices) on PowerVM systems is initiated
>from the HMC, which communicates the request to the partitions through
>the RSCT framework. The RSCT framework then invokes the drmgr command.
>The drmgr command performs the hotplug operation by doing some pieces,
>such as most of the rtas calls and device tree parsing, in userspace
>and make requests to the kernel to online/offline the device, update the
>device tree and add/remove the device.
>
>For PowerKVM the approach for device hotplug is to follow what is currently
>being done for pci hotplug. A hotplug request is initiated from the host,
>QEMU then generates an EPOW interrupt to the guest which causes the guest
>to make the rtas,check-exception call. In QEMU, the rtas,check-exception call
>returns a rtas hotplug event to the guest.
>
>Please note that the current pci hotplug path for PowerKVM involves the
>kernel receiving the rtas hotplug event, passing it to rtas_errd in
>userspace, and having rtas_errd invoke drmgr. The drmgr command then
>handles the request as described above for PowerVM systems. This is to
>be updated to perform pci completely in the kernel in a later patch set.
>
>There is no need for this circuitous route, we should handle the entire
>hotplug of devices in the kernel. What I am planning is to enable this
>by moving the code to handle device hotplug from drmgr into the kernel to
>provide a single path for both PowerVM and PowerKVM systems. This patch
>provides the common entry point. For PowerKVM a future update to the kernel
>rtas code will recognize rtas hotplug events returned from
>rtas,check-exception calls and use the common entry point to handle device
>hotplug entirely in the kernel.
>
>For PowerVM systems, this patch creates the /sys/kernel/dlpar file that rtas
>hotplug events can be written to by drmgr and passed to the common entry point.
>There is no chance of updating how we receive hotplug requests on PowerVM
>systems.
>
>Signed-off-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
>---
> arch/powerpc/platforms/pseries/dlpar.c          |   72 ++++++++++++++++++++++-
> arch/powerpc/platforms/pseries/hotplug-memory.c |   19 ++++++
> arch/powerpc/platforms/pseries/pseries.h        |   10 +++
> 3 files changed, 99 insertions(+), 2 deletions(-)
>
>diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
>index c22bb1b..ec825d3 100644
>--- a/arch/powerpc/platforms/pseries/dlpar.c
>+++ b/arch/powerpc/platforms/pseries/dlpar.c
>@@ -10,6 +10,8 @@
>  * 2 as published by the Free Software Foundation.
>  */
> 
>+#define pr_fmt(fmt)	"dlpar: " fmt
>+
> #include <linux/kernel.h>
> #include <linux/notifier.h>
> #include <linux/spinlock.h>
>@@ -535,13 +537,79 @@ static ssize_t dlpar_cpu_release(const char *buf, size_t count)
> 	return count;
> }
> 
>+#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
>+
>+static int handle_dlpar_errorlog(struct rtas_error_log *error_log)
>+{
>+	struct pseries_errorlog *pseries_log;
>+	struct pseries_hp_errorlog *hp_elog;
>+	int rc;
>+
>+	pseries_log = get_pseries_errorlog(error_log,
>+					   PSERIES_ELOG_SECT_ID_HOTPLUG);
>+	if (!pseries_log || (pseries_log->length == 0))
>+		return -EINVAL;
>+
>+	hp_elog = (struct pseries_hp_errorlog *)pseries_log->data;
>+
>+	/* Go ahead and convert the hotplug type to the correct endianness
>+	 * to avoid converting it everywhere we use it.
>+	 */
>+	switch (hp_elog->id_type) {
>+	case PSERIES_HP_ELOG_ID_DRC_COUNT:
>+		hp_elog->_drc_u.drc_count =
>+					be32_to_cpu(hp_elog->_drc_u.drc_count);
>+	case PSERIES_HP_ELOG_ID_DRC_INDEX:
>+		hp_elog->_drc_u.drc_index =
>+					be32_to_cpu(hp_elog->_drc_u.drc_index);
>+	}
>+

It seems that "break" was missed for all cases.

>+	switch (hp_elog->resource) {
>+	case PSERIES_HP_ELOG_RESOURCE_MEM:
>+		rc = dlpar_memory(hp_elog);
>+		break;
>+	default:
>+		pr_warn_ratelimited("Invalid resource (%d) specified\n",
>+				    hp_elog->resource);
>+		rc = -EINVAL;
>+		break;

Unnecessary "break" here.

>+	}
>+
>+	return rc;
>+}
>+
>+static ssize_t dlpar_store(struct file *filp, struct kobject *kobj,
>+			   struct bin_attribute *bin_attr, char *buf,
>+			   loff_t pos, size_t count)
>+{
>+	struct rtas_error_log *error_log;
>+	int rc;
>+
>+	error_log = kmalloc(count, GFP_KERNEL);
>+	if (!error_log)
>+		return -ENOMEM;
>+
>+	memcpy(error_log, buf, count);
>+
>+	rc = handle_dlpar_errorlog(error_log);
>+	kfree(error_log);
>+	return rc ? rc : count;
>+}
>+
>+static BIN_ATTR(dlpar, S_IWUSR, NULL, dlpar_store, 0);
>+
> static int __init pseries_dlpar_init(void)
> {
>+	int rc;
>+
>+#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
> 	ppc_md.cpu_probe = dlpar_cpu_probe;
> 	ppc_md.cpu_release = dlpar_cpu_release;
>+#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
> 
>-	return 0;
>+	rc = sysfs_create_bin_file(kernel_kobj, &bin_attr_dlpar);
>+
>+	return rc;
> }
> machine_device_initcall(pseries, pseries_dlpar_init);
> 
>-#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
>diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
>index 3cb256c..69d178b 100644
>--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
>+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
>@@ -9,6 +9,8 @@
>  *      2 of the License, or (at your option) any later version.
>  */
> 
>+#define pr_fmt(fmt)	"pseries-hotplug-mem: " fmt
>+
> #include <linux/of.h>
> #include <linux/of_address.h>
> #include <linux/memblock.h>
>@@ -134,6 +136,23 @@ static inline int pseries_remove_mem_node(struct device_node *np)
> }
> #endif /* CONFIG_MEMORY_HOTREMOVE */
> 
>+int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
>+{
>+	int rc = 0;
>+
>+	lock_device_hotplug();
>+
>+	switch (hp_elog->action) {
>+	default:
>+		pr_err("Invalid action (%d) specified\n", hp_elog->action);
>+		rc = -EINVAL;
>+		break;
>+	}
>+
>+	unlock_device_hotplug();
>+	return rc;
>+}
>+
> static int pseries_add_mem_node(struct device_node *np)
> {
> 	const char *type;
>diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
>index 239bee5..40e0339 100644
>--- a/arch/powerpc/platforms/pseries/pseries.h
>+++ b/arch/powerpc/platforms/pseries/pseries.h
>@@ -11,6 +11,7 @@
> #define _PSERIES_PSERIES_H
> 
> #include <linux/interrupt.h>
>+#include <asm/rtas.h>
> 
> struct device_node;
> 
>@@ -63,6 +64,15 @@ extern int dlpar_detach_node(struct device_node *);
> int dlpar_acquire_drc(u32 drc_index);
> int dlpar_release_drc(u32 drc_index);
> 
>+#ifdef CONFIG_MEMORY_HOTPLUG
>+int dlpar_memory(struct pseries_hp_errorlog *hp_elog);
>+#else
>+static inline int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
>+{
>+	return -EOPNOTSUPP;
>+}
>+#endif
>+
> /* PCI root bridge prepare function override for pseries */
> struct pci_host_bridge;
> int pseries_root_bridge_prepare(struct pci_host_bridge *bridge);
>
>_______________________________________________
>Linuxppc-dev mailing list
>Linuxppc-dev@lists.ozlabs.org
>https://lists.ozlabs.org/listinfo/linuxppc-dev

^ permalink raw reply

* Re: [RFC PATCH 14/16] arm/PCI: Introduce pci_get_domain_nr()
From: Yijing Wang @ 2014-11-18  0:55 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Liviu Dudau, Tony Luck, Russell King, linux-pci@vger.kernel.org,
	x86@kernel.org, linux-kernel@vger.kernel.org, huxinwei@huawei.com,
	Thierry Reding, suravee.suthikulpanit@amd.com, Bjorn Helgaas,
	linux-ia64@vger.kernel.org, Thomas Gleixner, Wuyun,
	linuxppc-dev@lists.ozlabs.org,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <20141117120839.GA22241@e102568-lin.cambridge.arm.com>

>>  
>> -	bus->domain_nr = domain;
>> +void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
>> +{
>> +	bus->domain_nr = pci_get_domain_nr(parent);
>>  }
>>  #endif
> 
> This code is superseded by the last patches I sent to move the domain
> assignment to PCI core code.
> 
> http://lists.infradead.org/pipermail/linux-arm-kernel/2014-November/301220.html

OK, I will update it based the latest one.

> 
> Lorenzo
> 
> 
> .
> 


-- 
Thanks!
Yijing

^ permalink raw reply

* Re: [PATCH] i2c-qoriq: modified compatibility for correct prescaler
From: Scott Wood @ 2014-11-18  1:28 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: Valentin Longchamp, Linux device trees, Boschung, Rainer,
	Brunck, Holger, Linux I2C, Linux PowerPC Kernel
In-Reply-To: <20141114082832.GA2180@katana>

On Fri, 2014-11-14 at 09:28 +0100, Wolfram Sang wrote:
> > > 
> > > If we're going to change the device tree I'd rather just add a property
> > > to say what the prescaler is.
> > 
> >  We would however, leave the boards' device trees that use things like
> > "fsl,mpc8543-i2c" as is and introduce the prescaler for the others requiring it.
> > 
> > 
> > Now the drawback is that the driver would require a change, to parse this
> > prescaler new prescaler property. Would this be OK from your point of view
> > Wolfram ? If yes, I will send the patches for it.
> 
> I don't think it is OK.

Why?

>  I'd think it can be deduced from the compatible property.

For almost all existing device trees it cannot be.

If you want something that will work without changing device trees,
you'll need to use SVR to identify the SoC.

-Scott

^ permalink raw reply

* Re: [PATCH] powerpc: mitigate impact of decrementer reset
From: Michael Ellerman @ 2014-11-18  1:46 UTC (permalink / raw)
  To: paulmck; +Cc: linuxppc-dev, Paul Clarke
In-Reply-To: <20141117191842.GA5050@linux.vnet.ibm.com>

On Mon, 2014-11-17 at 11:18 -0800, Paul E. McKenney wrote:
> On Thu, Nov 13, 2014 at 01:42:12PM +1100, Michael Ellerman wrote:
> > On Mon, 2014-11-10 at 14:58 -0600, Paul Clarke wrote:
> > > On 11/10/2014 04:08 AM, Benjamin Herrenschmidt wrote:
> > > > On Tue, 2014-10-07 at 14:13 -0500, Paul Clarke wrote:
> > > >> This patch short-circuits the reset of the decrementer, exiting after
> > > >> the decrementer reset, but before the housekeeping tasks if the only
> > > >> need for the interrupt is simply to reset it.  After this patch,
> > > >> the latency spike was measured at about 150 nanoseconds.
> > > >
> > > > Doesn't this break the irq_work stuff ? We trigger it with a set_dec(1);
> > > > and your patch will probably cause it to be skipped...
> > > 
> > > You're right.
> > 
> > Yeah, thanks Ben, that would have been bad.
> > 
> > So we'll need to come up with a different approach.
> 
> If I am understanding this correctly, it underscores the need for more
> bits in the decrementer register.  :-/

Yes that is the root cause of the problem :)

cheers

^ permalink raw reply

* Re: [PATCH net-next] PPC: bpf_jit_comp: Unify BPF_MOD | BPF_X and BPF_DIV | BPF_X
From: Michael Ellerman @ 2014-11-18  1:50 UTC (permalink / raw)
  To: Denis Kirjanov
  Cc: Philippe Bergheaud, netdev, Daniel Borkmann, Alexei Starovoitov,
	linuxppc-dev
In-Reply-To: <1416254861-3879-1-git-send-email-kda@linux-powerpc.org>

On Mon, 2014-11-17 at 23:07 +0300, Denis Kirjanov wrote:
> Reduce duplicated code by unifying
> BPF_ALU | BPF_MOD | BPF_X and BPF_ALU | BPF_DIV | BPF_X
> 
> CC: Alexei Starovoitov<alexei.starovoitov@gmail.com>
> CC: Daniel Borkmann<dborkman@redhat.com>
> CC: Philippe Bergheaud<felix@linux.vnet.ibm.com>
> Signed-off-by: Denis Kirjanov <kda@linux-powerpc.org>

Please include the output of the test suite.

Assuming that's OK I'm happy for it to go in.

cheers

^ permalink raw reply

* Re: [PATCH v2 0/6] pseries: Move memory hotplug to the kernel
From: Cyril Bur @ 2014-11-18  2:00 UTC (permalink / raw)
  To: Nathan Fontenot; +Cc: linuxppc-dev@lists.ozlabs.org
In-Reply-To: <546A6C23.1080800@linux.vnet.ibm.com>

Hi Nathan,

I tried to apply these to Linus' tree and Mpes tree and to stable and
got several problems, I got stuck at the third hunk in patch 5.

Could you point out where I'm going wrong?

Thanks,

Cyril

On Mon, 2014-11-17 at 15:44 -0600, Nathan Fontenot wrote:
> In order to better support device hotplug (cpu, memory, and pci) in the
> PowerVM and PowerKVM environments, the handling of device hotplug
> could be updated so that the act of hotplugging a device occurs entirely
> in the kernel. This patch set begins to address this by moving
> memory hotplug to the kernel. Patches to follow will do the same
> for cpu and pci devices.
> 
> To provide background, the current handling of memory hotplug is
> handled by the drmgr command. This command is invoked when memory
> add/remove requests are made at the HMC and conveyed to a partition
> through the RSCT framework. The drmgr command then performs parts
> of the hotplug in user-space and makes requests to the kernel to perform
> other pieces. This is not really ideal, we can do everything in the
> kernel and do it faster.
> 
> In this patchset, hotplug events will now be communicated to the kernel
> in the form of rtas hotplug events. For PowerKVM systems this is done
> by qemu using the ras epow interrupt. For PowerVM systems the drmgr
> command will be updated to create a rtas hotplug event and send it to
> the kernel via a new /sys/kernel/dlpar interface. Both of these
> entry points for hotplug rtas events then call a common routine
> for handling rtas hotplug events.
> 
> -Nathan
> 
> Patch 1/6
> - Add definition of hotplug rtas event sections.
> 
> Patch 2/6
> - Update struct of_drconf_cell to use __be64/__be32
>  
> Patch 3/6
> - Export the dlpar_[acquire|release]drc() routines.
> 
> Patch 4/6
> - Create the new /sys/kernel/dlpar interface
> 
> Patch 5/6
> - Implement memory hotplug add in the kernel.
> 
> Patch 6/6
> - Implement memory hotplug remove in the kernel.
> 
>  include/asm/prom.h                 |   10 
>  include/asm/rtas.h                 |   26 ++
>  platforms/pseries/dlpar.c          |   72 +++++
>  platforms/pseries/hotplug-memory.c |  469 ++++++++++++++++++++++++++++++++++++-
>  platforms/pseries/pseries.h        |   12 
>  5 files changed, 576 insertions(+), 13 deletions(-)
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev

^ permalink raw reply

* Re: [PATCH] powerpc: mitigate impact of decrementer reset
From: Paul E. McKenney @ 2014-11-18  3:08 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev, Paul Clarke
In-Reply-To: <1416275216.1107.2.camel@concordia>

On Tue, Nov 18, 2014 at 12:46:56PM +1100, Michael Ellerman wrote:
> On Mon, 2014-11-17 at 11:18 -0800, Paul E. McKenney wrote:
> > On Thu, Nov 13, 2014 at 01:42:12PM +1100, Michael Ellerman wrote:
> > > On Mon, 2014-11-10 at 14:58 -0600, Paul Clarke wrote:
> > > > On 11/10/2014 04:08 AM, Benjamin Herrenschmidt wrote:
> > > > > On Tue, 2014-10-07 at 14:13 -0500, Paul Clarke wrote:
> > > > >> This patch short-circuits the reset of the decrementer, exiting after
> > > > >> the decrementer reset, but before the housekeeping tasks if the only
> > > > >> need for the interrupt is simply to reset it.  After this patch,
> > > > >> the latency spike was measured at about 150 nanoseconds.
> > > > >
> > > > > Doesn't this break the irq_work stuff ? We trigger it with a set_dec(1);
> > > > > and your patch will probably cause it to be skipped...
> > > > 
> > > > You're right.
> > > 
> > > Yeah, thanks Ben, that would have been bad.
> > > 
> > > So we'll need to come up with a different approach.
> > 
> > If I am understanding this correctly, it underscores the need for more
> > bits in the decrementer register.  :-/
> 
> Yes that is the root cause of the problem :)

Sigh!!!  I was hoping!  ;-)

							Thanx, Paul

^ permalink raw reply

* Re: [powerpc] init nvram_pstore_info's buf_lock
From: Michael Ellerman @ 2014-11-18  4:33 UTC (permalink / raw)
  To: Li Zhong, PowerPC email list; +Cc: Paul Mackerras
In-Reply-To: <1416192750.3375.7.camel@TP420>

On Mon, 2014-17-11 at 02:52:30 UTC, Li Zhong wrote:
> It seems nvram_pstore_info's buf_lock is not initialized before
> registering, which causes some strange behavior when trying to obtain
> the lock during kdump process.

What kind of strange behaviour? Does it still work and just print a warning?

It's static, so I'd expect it to be unlocked by default.

cheers

^ permalink raw reply

* Pull request: scottwood/linux.git master
From: Scott Wood @ 2014-11-18  4:39 UTC (permalink / raw)
  To: benh, Michael Ellerman; +Cc: Kevin Hao, linuxppc-dev

This patch fixes a crash (introduced in v3.18-rc1) in the FSL MSI driver
when threaded IRQs are enabled.

The following changes since commit 8a97577a5967c1234ccc3bc1b45e4b1a58b39ea8:

  Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mpe/linux (2014-11-04 11:18:29 -0800)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/scottwood/linux.git master

for you to fetch changes up to d7ce4377494adfaf8afb15ecf4f07d399bbf13d9:

  powerpc/fsl_msi: mark the msi cascade handler IRQF_NO_THREAD (2014-11-17 22:00:30 -0600)

----------------------------------------------------------------
Kevin Hao (1):
      powerpc/fsl_msi: mark the msi cascade handler IRQF_NO_THREAD

 arch/powerpc/sysdev/fsl_msi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

^ permalink raw reply

* Re: [RFC 01/11] sched: introduce sys_cpumask in tsk to adapt asymmetric system
From: Liu ping fan @ 2014-11-18  5:07 UTC (permalink / raw)
  To: Srikar Dronamraju; +Cc: Paul Mackerras, linuxppc-dev, Alexander Graf, kvm-ppc
In-Reply-To: <20141112092224.GA16566@linux.vnet.ibm.com>

On Wed, Nov 12, 2014 at 5:22 PM, Srikar Dronamraju
<srikar@linux.vnet.ibm.com> wrote:
> * kernelfans@gmail.com <kernelfans@gmail.com> [2014-10-16 15:29:50]:
>
>> Some system such as powerpc, some tsk (vcpu thread) can only run on
>> the dedicated cpu. Since we adapt some asymmetric method to monitor the
>> whole physical cpu. (powerKVM only allows the primary hwthread to
>> set up runtime env for the secondary when entering guest).
>>
>> Nowadays, powerKVM run with all the secondary hwthread offline to ensure
>> the vcpu threads only run on the primary thread. But we plan to keep all
>> cpus online when running powerKVM to give more power when switching back
>> to host, so introduce sys_allowed cpumask to reflect the cpuset which
>> the vcpu thread can run on.
>>
>> Signed-off-by: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
>> ---
>>  include/linux/init_task.h |  1 +
>>  include/linux/sched.h     |  6 ++++++
>>  kernel/sched/core.c       | 10 ++++++++--
>>  3 files changed, 15 insertions(+), 2 deletions(-)
>>
>> diff --git a/include/linux/init_task.h b/include/linux/init_task.h
>> index 2bb4c4f3..c56f69e 100644
>> --- a/include/linux/init_task.h
>> +++ b/include/linux/init_task.h
>> @@ -172,6 +172,7 @@ extern struct task_group root_task_group;
>>       .normal_prio    = MAX_PRIO-20,                                  \
>>       .policy         = SCHED_NORMAL,                                 \
>>       .cpus_allowed   = CPU_MASK_ALL,                                 \
>> +     .sys_allowed = CPU_MASK_ALL,                    \
>
> Do we really need another mask, cant we just use cpus_allowed itself.
>
I think it is not easy to cast two request: chip inherit and user's
configuration onto one mask.

>>       .nr_cpus_allowed= NR_CPUS,                                      \
>>       .mm             = NULL,                                         \
>>       .active_mm      = &init_mm,                                     \
>> diff --git a/include/linux/sched.h b/include/linux/sched.h
>> index 5c2c885..ce429f3 100644
>> --- a/include/linux/sched.h
>> +++ b/include/linux/sched.h
>> @@ -1260,7 +1260,10 @@ struct task_struct {
>>
>>       unsigned int policy;
>>       int nr_cpus_allowed;
>> +     /* Anded user and sys_allowed */
>>       cpumask_t cpus_allowed;
>> +     /* due to the feature of asymmetric, some tsk can only run on such cpu */
>> +     cpumask_t sys_allowed;
>>
>>  #ifdef CONFIG_PREEMPT_RCU
>>       int rcu_read_lock_nesting;
>> @@ -2030,6 +2033,9 @@ static inline void tsk_restore_flags(struct task_struct *task,
>>  }
>>
>>  #ifdef CONFIG_SMP
>> +extern void set_cpus_sys_allowed(struct task_struct *p,
>> +                     const struct cpumask *new_mask);
>> +
>>  extern void do_set_cpus_allowed(struct task_struct *p,
>>                              const struct cpumask *new_mask);
>>
>> diff --git a/kernel/sched/core.c b/kernel/sched/core.c
>> index ec1a286..2cd1ae3 100644
>> --- a/kernel/sched/core.c
>> +++ b/kernel/sched/core.c
>> @@ -4596,13 +4596,19 @@ void init_idle(struct task_struct *idle, int cpu)
>>  }
>>
>>  #ifdef CONFIG_SMP
>> +void set_cpus_sys_allowed(struct task_struct *p,
>> +     const struct cpumask *new_mask)
>> +{
>> +     cpumask_copy(&p->sys_allowed, new_mask);
>> +}
>> +
>
> This function doesnt seem to be used anywhere... Not sure why it is
> introduced
>
Not layered the patches well :(  It is used later in the series.

Thx,
Fan

>>  void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask)
>>  {
>>       if (p->sched_class && p->sched_class->set_cpus_allowed)
>>               p->sched_class->set_cpus_allowed(p, new_mask);
>>
>> -     cpumask_copy(&p->cpus_allowed, new_mask);
>> -     p->nr_cpus_allowed = cpumask_weight(new_mask);
>> +     cpumask_and(&p->cpus_allowed, &p->sys_allowed, new_mask);
>> +     p->nr_cpus_allowed = cpumask_weight(&p->cpus_allowed);
>>  }
>>
>>  /*
>> --
>> 1.8.3.1
>>
>>
>
> --
> Thanks and Regards
> Srikar Dronamraju
>

^ permalink raw reply

* Re: [RFC 03/11] powerpc: kvm: add interface to control kvm function on a core
From: Liu ping fan @ 2014-11-18  5:17 UTC (permalink / raw)
  To: Preeti U Murthy; +Cc: Paul Mackerras, linuxppc-dev, Alexander Graf, kvm-ppc
In-Reply-To: <544DC46A.4050906@linux.vnet.ibm.com>

On Mon, Oct 27, 2014 at 12:04 PM, Preeti U Murthy
<preeti@linux.vnet.ibm.com> wrote:
> Hi Liu,
>
> On 10/17/2014 12:59 AM, kernelfans@gmail.com wrote:
>> When kvm is enabled on a core, we migrate all external irq to primary
>> thread. Since currently, the kvmirq logic is handled by the primary
>> hwthread.
>>
>> Todo: this patch lacks re-enable of irqbalance when kvm is disable on
>> the core
>
> Why is a sysfs file introduced to trigger irq migration? Why is it not
> done during kvm module insert ? And similarly spread interrupts when the
> module is removed? Isn't this a saner way ?

Consider the scene: coreA and coreB, we want to enable KVM on coreA,
while keeping coreB unchanged.
In fact, I try to acheive something un-symmetric on the platform. Do
you think it is an justification?
>>
>> Signed-off-by: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
>> ---
>>  arch/powerpc/kernel/sysfs.c            | 39 ++++++++++++++++++++++++++++++++++
>>  arch/powerpc/sysdev/xics/xics-common.c | 12 +++++++++++
>>  2 files changed, 51 insertions(+)
>>
>> diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
>> index 67fd2fd..a2595dd 100644
>> --- a/arch/powerpc/kernel/sysfs.c
>> +++ b/arch/powerpc/kernel/sysfs.c
>> @@ -552,6 +552,45 @@ static void sysfs_create_dscr_default(void)
>>       if (cpu_has_feature(CPU_FTR_DSCR))
>>               err = device_create_file(cpu_subsys.dev_root, &dev_attr_dscr_default);
>>  }
>> +
>> +#ifdef CONFIG_KVMPPC_ENABLE_SECONDARY
>> +#define NR_CORES     (CONFIG_NR_CPUS/threads_per_core)
>> +static DECLARE_BITMAP(kvm_on_core, NR_CORES) __read_mostly
>> +
>> +static ssize_t show_kvm_enable(struct device *dev,
>> +             struct device_attribute *attr, char *buf)
>> +{
>> +}
>> +
>> +static ssize_t __used store_kvm_enable(struct device *dev,
>> +             struct device_attribute *attr, const char *buf,
>> +             size_t count)
>> +{
>> +     struct cpumask stop_cpus;
>> +     unsigned long core, thr;
>> +
>> +     sscanf(buf, "%lx", &core);
>> +     if (core > NR_CORES)
>> +             return -1;
>> +     if (!test_bit(core, &kvm_on_core))
>> +             for (thr = 1; thr< threads_per_core; thr++)
>> +                     if (cpu_online(thr * threads_per_core + thr))
>> +                             cpumask_set_cpu(thr * threads_per_core + thr, &stop_cpus);
>
> What is the above logic trying to do? Did you mean
> cpu_online(threads_per_core * core + thr) ?
>
Yeah. My mistake, should be cpumask_set_cpu(core * threads_per_core +
thr, &stop_cpus)

>> +
>> +     stop_machine(xics_migrate_irqs_away_secondary, NULL, &stop_cpus);
>> +     set_bit(core, &kvm_on_core);
>> +     return count;
>> +}
>> +
>> +static DEVICE_ATTR(kvm_enable, 0600,
>> +     show_kvm_enable, store_kvm_enable);
>> +
>> +static void sysfs_create_kvm_enable(void)
>> +{
>> +     device_create_file(cpu_subsys.dev_root, &dev_attr_kvm_enable);
>> +}
>> +#endif
>> +
>>  #endif /* CONFIG_PPC64 */
>>
>>  #ifdef HAS_PPC_PMC_PA6T
>> diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c
>> index fe0cca4..68b33d8 100644
>> --- a/arch/powerpc/sysdev/xics/xics-common.c
>> +++ b/arch/powerpc/sysdev/xics/xics-common.c
>> @@ -258,6 +258,18 @@ unlock:
>>               raw_spin_unlock_irqrestore(&desc->lock, flags);
>>       }
>>  }
>> +
>> +int xics_migrate_irqs_away_secondary(void *data)
>> +{
>> +     int cpu = smp_processor_id();
>> +     if(cpu%thread_per_core != 0) {
>> +             WARN(condition, format...);
>> +             return 0;
>> +     }
>> +     /* In fact, if we can migrate the primary, it will be more fine */
>> +     ();
>
> Isn't the aim of the patch to migrate irqs away from the secondary onto
> the primary? But from above it looks like we are returning when we find
> out that we are secondary threads, isn't it?
>
Yes, will fix in next version.

>> +     return 0;
>> +}
>>  #endif /* CONFIG_HOTPLUG_CPU */
>
> Note that xics_migrate_irqs_away() is defined under CONFIG_CPU_HOTPLUG.
> But we will need this option on PowerKVM even when hotplug is not
> configured in.
>
Yes, will fix the dependency in next version

Thx,
Fan

> Regards
> Preeti U Murthy
>>  #ifdef CONFIG_SMP
>>
>

^ permalink raw reply

* Pull request: scottwood/linux.git next
From: Scott Wood @ 2014-11-18  5:20 UTC (permalink / raw)
  To: benh, Michael Ellerman; +Cc: linuxppc-dev

Highlights include a bunch of 8xx optimizations, device tree bindings for
Freescale BMan, QMan, and FMan datapath components, misc device tree
updates, and inbound rio window support.

The following changes since commit 0df1f2487d2f0d04703f142813d53615d62a1da4:

  Linux 3.18-rc3 (2014-11-02 15:01:51 -0800)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/scottwood/linux.git next

for you to fetch changes up to 76f3e2929bb6b476fb02b519ad953e2e29ee7bd5:

  powerpc/config: Enable memory driver (2014-11-17 19:36:42 -0600)

----------------------------------------------------------------
Ashish Kumar (1):
      powerpc/mpc85xx: Remove SPI and NAND partition from bsc9131rdb.dtsi

Emil Medve (7):
      powerpc/dts: Factorize the clock control node
      dt/bindings: qoriq-clock: Add binding for the platform PLL
      powerpc/dts: Add node(s) for the platform PLL
      dt/bindings: Introduce the FSL QorIQ DPAA BMan
      dt/bindings: Introduce the FSL QorIQ DPAA BMan portal(s)
      dt/bindings: Introduce the FSL QorIQ DPAA QMan
      dt/bindings: Introduce the FSL QorIQ DPAA QMan portal(s)

Hongtao Jia (2):
      powerpc: Add ADT7461 to device tree for supported boards
      powerpc: Add INA220 to device tree for supported boards

Igal Liberman (2):
      powerpc/fsl: Added rcw registers to global utility registers
      powerpc/fsl: Frame Manager Device Tree binding document

LEROY Christophe (14):
      powerpc/8xx: exception InstructionAccess does not exist on MPC8xx
      powerpc/8xx: DataAccess exception not generated by MPC8xx
      powerpc/8xx: No need to restore registers and save them again.
      powerpc/8xx: Use M_TW instead of M_TWB
      powerpc/8xx: Don't use MD_TWC for walk
      powerpc/8xx: Use PAGE size related consts
      powerpc/8xx: Const for TLB RPN forced value
      powerpc/8xx: Implement 16k pages
      powerpc/8xx: Better readibility of ERRATA CPU6 handling
      powerpc/8xx: set PTE bit 22 off TLBmiss
      powerpc/8xx: _PMD_PRESENT already set in level 1 entries
      powerpc/8xx: Don't restore regs to save them again.
      powerpc/8xx: Use DAR to save r3 for CPU6 ERRATA
      powerpc/8xx: Invalidate non present TLB as early as possible

Martijn de Gouw (1):
      powerpc/fsl-rio: add support for mapping inbound windows

Paul Bolle (1):
      powerpc/8xx: Remove Kconfig symbol FADS

Prabhakar Kushwaha (1):
      powerpc/config: Enable memory driver

Scott Wood (1):
      powerpc/fsl: Update fman dt binding with clock name and qbman link

 .../devicetree/bindings/clock/qoriq-clock.txt      |  14 +-
 .../devicetree/bindings/powerpc/fsl/fman.txt       | 534 +++++++++++++++++++++
 .../devicetree/bindings/soc/fsl/bman-portals.txt   |  56 +++
 Documentation/devicetree/bindings/soc/fsl/bman.txt | 125 +++++
 .../devicetree/bindings/soc/fsl/qman-portals.txt   | 154 ++++++
 Documentation/devicetree/bindings/soc/fsl/qman.txt | 165 +++++++
 arch/powerpc/Kconfig                               |   2 +-
 arch/powerpc/boot/dts/b4860emu.dts                 |   4 +-
 arch/powerpc/boot/dts/b4qds.dtsi                   |  23 +
 arch/powerpc/boot/dts/bsc9131rdb.dtsi              |  50 --
 arch/powerpc/boot/dts/fsl/b4420si-post.dtsi        |  28 +-
 arch/powerpc/boot/dts/fsl/b4860si-post.dtsi        |  28 +-
 arch/powerpc/boot/dts/fsl/p2041si-post.dtsi        |  48 +-
 arch/powerpc/boot/dts/fsl/p3041si-post.dtsi        |  48 +-
 arch/powerpc/boot/dts/fsl/p4080si-post.dtsi        |  48 +-
 arch/powerpc/boot/dts/fsl/p5020si-post.dtsi        |  48 +-
 arch/powerpc/boot/dts/fsl/p5040si-post.dtsi        |  48 +-
 arch/powerpc/boot/dts/fsl/qoriq-clockgen1.dtsi     |  85 ++++
 arch/powerpc/boot/dts/fsl/qoriq-clockgen2.dtsi     |  68 +++
 arch/powerpc/boot/dts/fsl/t1040si-post.dtsi        |  30 +-
 arch/powerpc/boot/dts/fsl/t2081si-post.dtsi        |  29 +-
 arch/powerpc/boot/dts/fsl/t4240si-post.dtsi        |  29 +-
 arch/powerpc/boot/dts/p3041ds.dts                  |  20 +
 arch/powerpc/boot/dts/p5020ds.dts                  |  20 +
 arch/powerpc/boot/dts/p5040ds.dts                  |  20 +
 arch/powerpc/boot/dts/t104xrdb.dtsi                |   7 +
 arch/powerpc/boot/dts/t208xqds.dtsi                |  11 +
 arch/powerpc/boot/dts/t4240emu.dts                 |   4 +-
 arch/powerpc/configs/corenet32_smp_defconfig       |   1 +
 arch/powerpc/configs/corenet64_smp_defconfig       |   1 +
 arch/powerpc/configs/mpc85xx_defconfig             |   1 +
 arch/powerpc/configs/mpc85xx_smp_defconfig         |   1 +
 arch/powerpc/include/asm/fsl_guts.h                |   5 +-
 arch/powerpc/include/asm/mmu-8xx.h                 |   2 +
 arch/powerpc/include/asm/pgtable-ppc32.h           |  20 +
 arch/powerpc/include/asm/pte-8xx.h                 |   7 +-
 arch/powerpc/kernel/head_8xx.S                     | 230 ++++-----
 arch/powerpc/mm/fault.c                            |   7 -
 arch/powerpc/platforms/8xx/Kconfig                 |   4 -
 arch/powerpc/sysdev/fsl_rio.c                      | 104 ++++
 arch/powerpc/sysdev/fsl_rio.h                      |  13 +
 41 files changed, 1599 insertions(+), 543 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/powerpc/fsl/fman.txt
 create mode 100644 Documentation/devicetree/bindings/soc/fsl/bman-portals.txt
 create mode 100644 Documentation/devicetree/bindings/soc/fsl/bman.txt
 create mode 100644 Documentation/devicetree/bindings/soc/fsl/qman-portals.txt
 create mode 100644 Documentation/devicetree/bindings/soc/fsl/qman.txt
 create mode 100644 arch/powerpc/boot/dts/fsl/qoriq-clockgen1.dtsi
 create mode 100644 arch/powerpc/boot/dts/fsl/qoriq-clockgen2.dtsi

^ permalink raw reply


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