* Re: [PATCH] powerpc/topology: Update numa mask when cpu node mapping changes
From: Srikar Dronamraju @ 2018-10-10 5:37 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, Michael Bringmann
In-Reply-To: <1539145486-10250-1-git-send-email-srikar@linux.vnet.ibm.com>
* Srikar Dronamraju <srikar@linux.vnet.ibm.com> [2018-10-10 09:54:46]:
> Commit 2ea626306810 ("powerpc/topology: Get topology for shared
> processors at boot") will update the cpu node topology for shared lpars
> on PowerVM.
>
> However shared lpars on PowerVM also support VPHN and PRRN events.
> On receiving a VPHN, PRRN events, cpu to node mapping might change.
>
> Scheduler maintains sched_domains_numa_masks[], which is currently not
> updated on cpu to node mapping changes. This can lead to machine
> regressions and performance regressions.
s/regressions and performance regressions./hangs or performance hit./
>
> Fix numa_update_cpu_topology() to update sched_domains_numa_masks[].
>
--
Thanks and Regards
Srikar Dronamraju
^ permalink raw reply
* [PATCH] powerpc/rtasd: Improve unknown error logging
From: Oliver O'Halloran @ 2018-10-10 5:23 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Oliver O'Halloran
Currently when we get an unknown RTAS event it prints the type as
"Unknown" and no other useful information. Add the raw type code to the
log message so that we have something to work off.
Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
---
arch/powerpc/kernel/rtasd.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c
index 44d66c33d59d..6fafc82c04b0 100644
--- a/arch/powerpc/kernel/rtasd.c
+++ b/arch/powerpc/kernel/rtasd.c
@@ -150,8 +150,10 @@ static void printk_log_rtas(char *buf, int len)
} else {
struct rtas_error_log *errlog = (struct rtas_error_log *)buf;
- printk(RTAS_DEBUG "event: %d, Type: %s, Severity: %d\n",
- error_log_cnt, rtas_event_type(rtas_error_type(errlog)),
+ printk(RTAS_DEBUG "event: %d, Type: %s (%d), Severity: %d\n",
+ error_log_cnt,
+ rtas_event_type(rtas_error_type(errlog)),
+ rtas_error_type(errlog),
rtas_error_severity(errlog));
}
}
--
2.9.5
^ permalink raw reply related
* [PATCH 4/4] powerpc: Add -Wimplicit-fallthrough to arch CFLAGS
From: Michael Ellerman @ 2018-10-10 5:13 UTC (permalink / raw)
To: linuxppc-dev; +Cc: maddy, keescook
In-Reply-To: <20181010051308.25422-1-mpe@ellerman.id.au>
Warn whenever a switch statement has a fallthrough without a comment
annotating it.
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
arch/powerpc/Kbuild | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/powerpc/Kbuild b/arch/powerpc/Kbuild
index 86b261d6bde5..ef625f1db576 100644
--- a/arch/powerpc/Kbuild
+++ b/arch/powerpc/Kbuild
@@ -1,4 +1,5 @@
subdir-ccflags-y := $(call cc-option, -Wvla)
+subdir-ccflags-y += $(call cc-option, -Wimplicit-fallthrough)
subdir-ccflags-$(CONFIG_PPC_WERROR) += -Werror
obj-y += kernel/
--
2.17.1
^ permalink raw reply related
* [PATCH 3/4] powerpc: Add -Wvla to arch CFLAGS
From: Michael Ellerman @ 2018-10-10 5:13 UTC (permalink / raw)
To: linuxppc-dev; +Cc: maddy, keescook
In-Reply-To: <20181010051308.25422-1-mpe@ellerman.id.au>
Upstream has declared that Variable Length Array's (VLAs) are a bad
idea, and eventually -Wvla will be added to the top-level Makefile. We
can go one better and make sure we don't introduce any more by adding
it to the arch Makefile.
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
arch/powerpc/Kbuild | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/Kbuild b/arch/powerpc/Kbuild
index 1625a06802ca..86b261d6bde5 100644
--- a/arch/powerpc/Kbuild
+++ b/arch/powerpc/Kbuild
@@ -1,4 +1,5 @@
-subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
+subdir-ccflags-y := $(call cc-option, -Wvla)
+subdir-ccflags-$(CONFIG_PPC_WERROR) += -Werror
obj-y += kernel/
obj-y += mm/
--
2.17.1
^ permalink raw reply related
* [PATCH 2/4] powerpc: Add -Werror at arch/powerpc level
From: Michael Ellerman @ 2018-10-10 5:13 UTC (permalink / raw)
To: linuxppc-dev; +Cc: maddy, keescook
In-Reply-To: <20181010051308.25422-1-mpe@ellerman.id.au>
Back when I added -Werror in commit ba55bd74360e ("powerpc: Add
configurable -Werror for arch/powerpc") I did it by adding it to most
of the arch Makefiles.
At the time we excluded math-emu, because apparently it didn't build
cleanly. But that seems to have been fixed somewhere in the interim.
So move the -Werror addition to the top-level of the arch, this saves
us from repeating it in every Makefile and means we won't forget to
add it to any new sub-dirs.
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
arch/powerpc/Kbuild | 2 ++
arch/powerpc/kernel/Makefile | 2 --
arch/powerpc/kernel/trace/Makefile | 2 --
arch/powerpc/kvm/Makefile | 2 --
arch/powerpc/lib/Makefile | 2 --
arch/powerpc/mm/Makefile | 2 --
arch/powerpc/oprofile/Makefile | 1 -
arch/powerpc/perf/Makefile | 1 -
arch/powerpc/platforms/Makefile | 2 --
arch/powerpc/sysdev/Makefile | 3 ---
arch/powerpc/sysdev/xics/Makefile | 1 -
arch/powerpc/sysdev/xive/Makefile | 1 -
arch/powerpc/xmon/Makefile | 2 --
13 files changed, 2 insertions(+), 21 deletions(-)
diff --git a/arch/powerpc/Kbuild b/arch/powerpc/Kbuild
index 690a498da050..1625a06802ca 100644
--- a/arch/powerpc/Kbuild
+++ b/arch/powerpc/Kbuild
@@ -1,3 +1,5 @@
+subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
+
obj-y += kernel/
obj-y += mm/
obj-y += lib/
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 85ffa488dfb5..006e391814ed 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -5,8 +5,6 @@
CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"'
-subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
-
ifdef CONFIG_PPC64
CFLAGS_prom_init.o += $(NO_MINIMAL_TOC)
endif
diff --git a/arch/powerpc/kernel/trace/Makefile b/arch/powerpc/kernel/trace/Makefile
index d868ba42032f..b1725ad3e13d 100644
--- a/arch/powerpc/kernel/trace/Makefile
+++ b/arch/powerpc/kernel/trace/Makefile
@@ -3,8 +3,6 @@
# Makefile for the powerpc trace subsystem
#
-subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
-
ifdef CONFIG_FUNCTION_TRACER
# do not trace tracer code
CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE)
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile
index f872c04bb5b1..e9d579921a96 100644
--- a/arch/powerpc/kvm/Makefile
+++ b/arch/powerpc/kvm/Makefile
@@ -3,8 +3,6 @@
# Makefile for Kernel-based Virtual Machine module
#
-subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
-
ccflags-y := -Ivirt/kvm -Iarch/powerpc/kvm
KVM := ../../../virt/kvm
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index 670286808928..703afa1808ed 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -3,8 +3,6 @@
# Makefile for ppc-specific library files..
#
-subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
-
ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
CFLAGS_REMOVE_code-patching.o = $(CC_FLAGS_FTRACE)
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index cdf6a9960046..90e103ab44fb 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -3,8 +3,6 @@
# Makefile for the linux ppc-specific parts of the memory manager.
#
-subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
-
ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
obj-y := fault.o mem.o pgtable.o mmap.o \
diff --git a/arch/powerpc/oprofile/Makefile b/arch/powerpc/oprofile/Makefile
index 7a7834c39f64..8d26d7416481 100644
--- a/arch/powerpc/oprofile/Makefile
+++ b/arch/powerpc/oprofile/Makefile
@@ -1,5 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
-subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile
index 82986d2acd9b..ab26df5bacb9 100644
--- a/arch/powerpc/perf/Makefile
+++ b/arch/powerpc/perf/Makefile
@@ -1,5 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
-subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
obj-$(CONFIG_PERF_EVENTS) += callchain.o perf_regs.o
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile
index e46bb7ea710f..143d4417f6cc 100644
--- a/arch/powerpc/platforms/Makefile
+++ b/arch/powerpc/platforms/Makefile
@@ -1,7 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
-subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
-
obj-$(CONFIG_FSL_ULI1575) += fsl_uli1575.o
obj-$(CONFIG_PPC_PMAC) += powermac/
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index f730539074c4..2caa4defdfb6 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -1,5 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
-subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
@@ -56,8 +55,6 @@ obj-$(CONFIG_PPC_SCOM) += scom.o
obj-$(CONFIG_PPC_EARLY_DEBUG_MEMCONS) += udbg_memcons.o
-subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
-
obj-$(CONFIG_PPC_XICS) += xics/
obj-$(CONFIG_PPC_XIVE) += xive/
diff --git a/arch/powerpc/sysdev/xics/Makefile b/arch/powerpc/sysdev/xics/Makefile
index 5d438d92472b..ba1e3117b1c0 100644
--- a/arch/powerpc/sysdev/xics/Makefile
+++ b/arch/powerpc/sysdev/xics/Makefile
@@ -1,5 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
-subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
obj-y += xics-common.o
obj-$(CONFIG_PPC_ICP_NATIVE) += icp-native.o
diff --git a/arch/powerpc/sysdev/xive/Makefile b/arch/powerpc/sysdev/xive/Makefile
index 536d6e5706e3..dea2abc23f4d 100644
--- a/arch/powerpc/sysdev/xive/Makefile
+++ b/arch/powerpc/sysdev/xive/Makefile
@@ -1,4 +1,3 @@
-subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
obj-y += common.o
obj-$(CONFIG_PPC_XIVE_NATIVE) += native.o
diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile
index 93cc1f1b8b61..ab5f66affb06 100644
--- a/arch/powerpc/xmon/Makefile
+++ b/arch/powerpc/xmon/Makefile
@@ -1,8 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
# Makefile for xmon
-subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
-
GCOV_PROFILE := n
UBSAN_SANITIZE := n
--
2.17.1
^ permalink raw reply related
* [PATCH 1/4] powerpc: Move core kernel logic into arch/powerpc/Kbuild
From: Michael Ellerman @ 2018-10-10 5:13 UTC (permalink / raw)
To: linuxppc-dev; +Cc: maddy, keescook
This is a nice cleanup, arch/powerpc/Makefile is long and messy so
moving this out helps a little.
It also allows us to do:
$ make arch/powerpc
Which can be helpful if you just want to compile test some changes to
arch code and not link everything.
Finally it also gives us a single place to do subdir-cc-flags
assignments which affect the whole of arch/powerpc, which we will do
in a future patch.
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
arch/powerpc/Kbuild | 14 ++++++++++++++
arch/powerpc/Makefile | 14 ++------------
2 files changed, 16 insertions(+), 12 deletions(-)
create mode 100644 arch/powerpc/Kbuild
diff --git a/arch/powerpc/Kbuild b/arch/powerpc/Kbuild
new file mode 100644
index 000000000000..690a498da050
--- /dev/null
+++ b/arch/powerpc/Kbuild
@@ -0,0 +1,14 @@
+obj-y += kernel/
+obj-y += mm/
+obj-y += lib/
+obj-y += sysdev/
+obj-y += platforms/
+obj-y += math-emu/
+obj-y += crypto/
+obj-y += net/
+
+obj-$(CONFIG_XMON) += xmon/
+obj-$(CONFIG_KVM) += kvm/
+
+obj-$(CONFIG_PERF_EVENTS) += perf/
+obj-$(CONFIG_KEXEC_FILE) += purgatory/
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 974103254aed..e623abaa573e 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -269,18 +269,8 @@ head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o
head-$(CONFIG_ALTIVEC) += arch/powerpc/kernel/vector.o
head-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE) += arch/powerpc/kernel/prom_init.o
-core-y += arch/powerpc/kernel/ \
- arch/powerpc/mm/ \
- arch/powerpc/lib/ \
- arch/powerpc/sysdev/ \
- arch/powerpc/platforms/ \
- arch/powerpc/math-emu/ \
- arch/powerpc/crypto/ \
- arch/powerpc/net/
-core-$(CONFIG_XMON) += arch/powerpc/xmon/
-core-$(CONFIG_KVM) += arch/powerpc/kvm/
-core-$(CONFIG_PERF_EVENTS) += arch/powerpc/perf/
-core-$(CONFIG_KEXEC_FILE) += arch/powerpc/purgatory/
+# See arch/powerpc/Kbuild for content of core part of the kernel
+core-y += arch/powerpc/
drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/
--
2.17.1
^ permalink raw reply related
* Re: [PATCH 21/36] dt-bindings: arm: Convert TI davinci board/soc bindings to json-schema
From: Sekhar Nori @ 2018-10-09 11:59 UTC (permalink / raw)
To: Rob Herring, linux-kernel, devicetree, linux-arm-kernel,
linuxppc-dev
Cc: Mark Rutland, Tom Rini, Kumar Gala, Grant Likely, Arnd Bergmann,
Kevin Hilman, Linus Walleij, Pantelis Antoniou, Bjorn Andersson,
Mark Brown, Geert Uytterhoeven, Olof Johansson, Frank Rowand,
Jonathan Cameron
In-Reply-To: <20181005165848.3474-22-robh@kernel.org>
On Friday 05 October 2018 10:28 PM, Rob Herring wrote:
> Convert TI Davinci SoC bindings to DT schema format using json-schema.
>
> Cc: Sekhar Nori <nsekhar@ti.com>
> Cc: Kevin Hilman <khilman@kernel.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: devicetree@vger.kernel.org
> Signed-off-by: Rob Herring <robh@kernel.org>
> ---
> .../devicetree/bindings/arm/davinci.txt | 25 ------------------
> .../bindings/arm/ti/ti,davinci.yaml | 26 +++++++++++++++++++
> 2 files changed, 26 insertions(+), 25 deletions(-)
> delete mode 100644 Documentation/devicetree/bindings/arm/davinci.txt
> create mode 100644 Documentation/devicetree/bindings/arm/ti/ti,davinci.yaml
>
> diff --git a/Documentation/devicetree/bindings/arm/davinci.txt b/Documentation/devicetree/bindings/arm/davinci.txt
> deleted file mode 100644
> index 715622c36260..000000000000
> --- a/Documentation/devicetree/bindings/arm/davinci.txt
> +++ /dev/null
> @@ -1,25 +0,0 @@
> -Texas Instruments DaVinci Platforms Device Tree Bindings
> ---------------------------------------------------------
> -
> -DA850/OMAP-L138/AM18x Evaluation Module (EVM) board
> -Required root node properties:
> - - compatible = "ti,da850-evm", "ti,da850";
> -
> -DA850/OMAP-L138/AM18x L138/C6748 Development Kit (LCDK) board
> -Required root node properties:
> - - compatible = "ti,da850-lcdk", "ti,da850";
> -
> -EnBW AM1808 based CMC board
> -Required root node properties:
> - - compatible = "enbw,cmc", "ti,da850;
> -
> -LEGO MINDSTORMS EV3 (AM1808 based)
> -Required root node properties:
> - - compatible = "lego,ev3", "ti,da850";
> -
> -Generic DaVinci Boards
> -----------------------
> -
> -DA850/OMAP-L138/AM18x generic board
> -Required root node properties:
> - - compatible = "ti,da850";
> diff --git a/Documentation/devicetree/bindings/arm/ti/ti,davinci.yaml b/Documentation/devicetree/bindings/arm/ti/ti,davinci.yaml
> new file mode 100644
> index 000000000000..2675cae91a60
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/ti/ti,davinci.yaml
> @@ -0,0 +1,26 @@
> +# SPDX-License-Identifier: None
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/bindings/arm/davinci.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Texas Instruments DaVinci Platforms Device Tree Bindings
> +
> +maintainers:
> + - Sekhar Nori <nsekhar@ti.com>
> +description: |
> + DA850/OMAP-L138/AM18x based boards
> +
> +
> +properties:
> + $nodename:
> + const: '/'
> + compatible:
> + items:
> + - enum:
> + - ti,da850-evm
> + - ti,da850-lcdk
> + - enbw,cmc
> + - lego,ev3
The boards had some reasonable human readable description earlier, which
has been lost now. Is there a way to bring that back?
Apart from that, looks good to me.
Thanks,
Sekhar
> + - const: ti,da850
> +...
> --
> 2.17.1
>
^ permalink raw reply
* [PATCH] powerpc/topology: Update numa mask when cpu node mapping changes
From: Srikar Dronamraju @ 2018-10-10 4:24 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, Srikar Dronamraju, Michael Bringmann
Commit 2ea626306810 ("powerpc/topology: Get topology for shared
processors at boot") will update the cpu node topology for shared lpars
on PowerVM.
However shared lpars on PowerVM also support VPHN and PRRN events.
On receiving a VPHN, PRRN events, cpu to node mapping might change.
Scheduler maintains sched_domains_numa_masks[], which is currently not
updated on cpu to node mapping changes. This can lead to machine
regressions and performance regressions.
Fix numa_update_cpu_topology() to update sched_domains_numa_masks[].
Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
---
arch/powerpc/mm/numa.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 3ea5b05ee6be..bf34384aa314 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -29,6 +29,7 @@
#include <linux/seq_file.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
+#include <linux/sched/hotplug.h>
#include <asm/cputhreads.h>
#include <asm/sparsemem.h>
#include <asm/prom.h>
@@ -1424,6 +1425,19 @@ int numa_update_cpu_topology(bool cpus_locked)
changed = 1;
}
+ /*
+ * Scheduler maintains a sched_domain_numa_masks table that needs to
+ * be updated whenever cpu-node mapping changes. Cpu-node mapping
+ * change only with vphn and prrn.
+ */
+ if (!(topology_inited && (vphn_enabled || prrn_enabled)))
+ goto out;
+
+ for_each_cpu(cpu, &updated_cpus) {
+ sched_cpu_deactivate(cpu);
+ sched_cpu_activate(cpu);
+ }
+
out:
kfree(updates);
topology_update_needed = 0;
--
2.12.3
^ permalink raw reply related
* [PATCH 2/2] powerpc/boot: Build boot wrapper with optimisations
From: Joel Stanley @ 2018-10-10 2:45 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Oliver O'Halloran
In-Reply-To: <20181010024523.4921-1-joel@jms.id.au>
The boot wrapper is currently built with -Os. By building with O2 we
can meaningfully reduce the time decompressing the kernel.
I tested by comparing 10 runs of each option in Qemu and on hardware.
The kernel is compressed with KERNEL_XZ built with GCC 8.2.0-7ubuntu1.
The values are counts of the timebase.
Qemu TCG powernv Power8:
Os O2 O3
median 10221123889 6201518438 6568186825
stddev 1361267211 429090641 657930076
improvement 39.33% 35.74%
Palmetto Power8:
Os O2 O3
median 50279 50599 35790
stddev 992144533 627130655 623721078
improvement 36.79% 37.13%
Romulus Power9:
Os O2 O3
median 670312391 454733720 448881398
stddev 157569 107276 108760
improvement 32.16% 33.03%
TCG was quite noisy, with every few runs producing an outlier. Even so,
O2 is faster than O3. On hardware the numbers were less noisy and O3 is
slightly faster than O2.
The wrapper size increases when moving from Os. Comparing zImage.epapr
to the existing Os build using bloat-o-meter:
Before=43401, After=56837 (13KB), chg +30.96%
Before=43401, After=64305 (20KB), chg +48.16%
I chose O2 for a balance between Qemu and hardware speed up.
Signed-off-by: Joel Stanley <joel@jms.id.au>
---
arch/powerpc/boot/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 739ef8d43b91..c6c5a1a6627d 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -32,7 +32,7 @@ else
endif
BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
- -fno-strict-aliasing -Os -msoft-float -mno-altivec -mno-vsx \
+ -fno-strict-aliasing -O2 -msoft-float -mno-altivec -mno-vsx \
-pipe -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \
-D$(compress-y)
--
2.17.1
^ permalink raw reply related
* [PATCH 1/2] powerpc/boot: Disable vector instructions
From: Joel Stanley @ 2018-10-10 2:45 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Oliver O'Halloran
In-Reply-To: <20181010024523.4921-1-joel@jms.id.au>
This will avoid auto-vectorisation when building with higher
optimisation levels.
We don't know if the machine can support VSX and even if it's present
it's probably not going to be enabled at this point in boot.
Signed-off-by: Joel Stanley <joel@jms.id.au>
---
arch/powerpc/boot/Makefile | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 0fb96c26136f..739ef8d43b91 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -32,8 +32,8 @@ else
endif
BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
- -fno-strict-aliasing -Os -msoft-float -pipe \
- -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \
+ -fno-strict-aliasing -Os -msoft-float -mno-altivec -mno-vsx \
+ -pipe -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \
-D$(compress-y)
ifdef CONFIG_PPC64_BOOT_WRAPPER
--
2.17.1
^ permalink raw reply related
* [PATCH 0/2] powerpc/boot: Build wrapper with optimisations
From: Joel Stanley @ 2018-10-10 2:45 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Oliver O'Halloran
We currently build the wrapper with Os. This builds it with O2 instead,
reducing boot time when decompressing a compressed kernel. See patch
2 for details.
I've given this a spin with CONFIG_KERNEL_XZ on P9 and P8 as the
petitboot kernel.
Joel Stanley (2):
powerpc/boot: Disable vector instructions
powerpc/boot: Build boot wrapper with optimisations
arch/powerpc/boot/Makefile | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--
2.17.1
^ permalink raw reply
* Re: [PATCH 15/36] dt-bindings: arm: Convert Actions Semi bindings to jsonschema
From: Joe Perches @ 2018-10-10 1:41 UTC (permalink / raw)
To: Andreas Färber, Rob Herring
Cc: Mark Rutland, devicetree, Kumar Gala, Grant Likely, Arnd Bergmann,
Tom Rini, Frank Rowand, Linus Walleij, Pantelis Antoniou,
linux-kernel, Bjorn Andersson, Mark Brown, Geert Uytterhoeven,
Jonathan Cameron, Manivannan Sadhasivam, Olof Johansson,
linuxppc-dev, linux-arm-kernel
In-Reply-To: <c4909f78-bfa1-9253-e436-1159392b45a9@suse.de>
On Sat, 2018-10-06 at 12:40 +0200, Andreas Färber wrote:
> > +++ b/Documentation/devicetree/bindings/arm/actions.yaml
[]
> > +
> > +title: Actions Semi platforms device tree bindings
> > +
> > +maintainers:
> > + - Andreas Färber <afaerber@suse.de>
>
> Mani is now officially reviewer and the closest I have to a
> co-maintainer. I suggest we add him here in some form. I assume this is
> independent of MAINTAINERS patterns though, or will get_maintainers.pl
> parse this, too?
It _could_, if using the get_maintainers --file-emails option.
Ideally, it would be added to the MAINTAINERS somewhere.
^ permalink raw reply
* Re: [PATCH 05/16] of: overlay: use prop add changeset entry for property in new nodes
From: Frank Rowand @ 2018-10-09 23:44 UTC (permalink / raw)
To: Alan Tull
Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
linux-fpga, Pantelis Antoniou, linux-kernel, Rob Herring,
Moritz Fischer, Paul Mackerras, linuxppc-dev
In-Reply-To: <CANk1AXQScT_b1_UOiVuWNcB=LiA3gvvZrw53H1XVSCNqsGPqtA@mail.gmail.com>
On 10/09/18 13:28, Alan Tull wrote:
> On Thu, Oct 4, 2018 at 11:14 PM <frowand.list@gmail.com> wrote:
>>
>> From: Frank Rowand <frank.rowand@sony.com>
>>
>
> Hi Frank,
>
>> The changeset entry 'update property' was used for new properties in
>> an overlay instead of 'add property'.
>>
>> The decision of whether to use 'update property' was based on whether
>> the property already exists in the subtree where the node is being
>> spliced into. At the top level of creating a changeset describing the
>> overlay, the target node is in the live devicetree, so checking whether
>> the property exists in the target node returns the correct result.
>> As soon as the changeset creation algorithm recurses into a new node,
>> the target is no longer in the live devicetree, but is instead in the
>> detached overlay tree, thus all properties are incorrectly found to
>> already exist in the target.
>
> When I applied an overlay (that added a few gpio controllers, etc),
> the node names for nodes added from the overlay end up NULL. It
I'll look at this tonight.
-Frank
> seems related to this patch and the next one. I haven't completely
> root caused this but if I back out to before this patch, the situation
> is fixed.
>
> root@arria10:~/unit_tests# ls /sys/bus/platform/drivers/altera_gpio/
> bind ff200010.<NULL> ff200020.<NULL> ff200030.<NULL>
> uevent unbind
>
> root@arria10:~/unit_tests# ls /sys/bus/platform/drivers/altera_freeze_br/
> bind ff200450.<NULL> uevent unbind
>
> Alan
>
>>
>> This fix will expose another devicetree bug that will be fixed
>> in the following patch in the series.
>>
>> When this patch is applied the errors reported by the devictree
>> unittest will change, and the unittest results will change from:
>>
>> ### dt-test ### end of unittest - 210 passed, 0 failed
>>
>> to
>>
>> ### dt-test ### end of unittest - 203 passed, 7 failed
>>
>> Signed-off-by: Frank Rowand <frank.rowand@sony.com>
>> ---
>> drivers/of/overlay.c | 112 ++++++++++++++++++++++++++++++++++-----------------
>> 1 file changed, 74 insertions(+), 38 deletions(-)
>>
>> diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
>> index 32cfee68f2e3..0b0904f44bc7 100644
>> --- a/drivers/of/overlay.c
>> +++ b/drivers/of/overlay.c
>> @@ -24,6 +24,26 @@
>> #include "of_private.h"
>>
>> /**
>> + * struct target - info about current target node as recursing through overlay
>> + * @np: node where current level of overlay will be applied
>> + * @in_livetree: @np is a node in the live devicetree
>> + *
>> + * Used in the algorithm to create the portion of a changeset that describes
>> + * an overlay fragment, which is a devicetree subtree. Initially @np is a node
>> + * in the live devicetree where the overlay subtree is targeted to be grafted
>> + * into. When recursing to the next level of the overlay subtree, the target
>> + * also recurses to the next level of the live devicetree, as long as overlay
>> + * subtree node also exists in the live devicetree. When a node in the overlay
>> + * subtree does not exist at the same level in the live devicetree, target->np
>> + * points to a newly allocated node, and all subsequent targets in the subtree
>> + * will be newly allocated nodes.
>> + */
>> +struct target {
>> + struct device_node *np;
>> + bool in_livetree;
>> +};
>> +
>> +/**
>> * struct fragment - info about fragment nodes in overlay expanded device tree
>> * @target: target of the overlay operation
>> * @overlay: pointer to the __overlay__ node
>> @@ -72,8 +92,7 @@ static int devicetree_corrupt(void)
>> }
>>
>> static int build_changeset_next_level(struct overlay_changeset *ovcs,
>> - struct device_node *target_node,
>> - const struct device_node *overlay_node);
>> + struct target *target, const struct device_node *overlay_node);
>>
>> /*
>> * of_resolve_phandles() finds the largest phandle in the live tree.
>> @@ -257,14 +276,17 @@ static struct property *dup_and_fixup_symbol_prop(
>> /**
>> * add_changeset_property() - add @overlay_prop to overlay changeset
>> * @ovcs: overlay changeset
>> - * @target_node: where to place @overlay_prop in live tree
>> + * @target: where @overlay_prop will be placed
>> * @overlay_prop: property to add or update, from overlay tree
>> * @is_symbols_prop: 1 if @overlay_prop is from node "/__symbols__"
>> *
>> - * If @overlay_prop does not already exist in @target_node, add changeset entry
>> - * to add @overlay_prop in @target_node, else add changeset entry to update
>> + * If @overlay_prop does not already exist in live devicetree, add changeset
>> + * entry to add @overlay_prop in @target, else add changeset entry to update
>> * value of @overlay_prop.
>> *
>> + * @target may be either in the live devicetree or in a new subtree that
>> + * is contained in the changeset.
>> + *
>> * Some special properties are not updated (no error returned).
>> *
>> * Update of property in symbols node is not allowed.
>> @@ -273,20 +295,22 @@ static struct property *dup_and_fixup_symbol_prop(
>> * invalid @overlay.
>> */
>> static int add_changeset_property(struct overlay_changeset *ovcs,
>> - struct device_node *target_node,
>> - struct property *overlay_prop,
>> + struct target *target, struct property *overlay_prop,
>> bool is_symbols_prop)
>> {
>> struct property *new_prop = NULL, *prop;
>> int ret = 0;
>>
>> - prop = of_find_property(target_node, overlay_prop->name, NULL);
>> -
>> if (!of_prop_cmp(overlay_prop->name, "name") ||
>> !of_prop_cmp(overlay_prop->name, "phandle") ||
>> !of_prop_cmp(overlay_prop->name, "linux,phandle"))
>> return 0;
>>
>> + if (target->in_livetree)
>> + prop = of_find_property(target->np, overlay_prop->name, NULL);
>> + else
>> + prop = NULL;
>> +
>> if (is_symbols_prop) {
>> if (prop)
>> return -EINVAL;
>> @@ -299,10 +323,10 @@ static int add_changeset_property(struct overlay_changeset *ovcs,
>> return -ENOMEM;
>>
>> if (!prop)
>> - ret = of_changeset_add_property(&ovcs->cset, target_node,
>> + ret = of_changeset_add_property(&ovcs->cset, target->np,
>> new_prop);
>> else
>> - ret = of_changeset_update_property(&ovcs->cset, target_node,
>> + ret = of_changeset_update_property(&ovcs->cset, target->np,
>> new_prop);
>>
>> if (ret) {
>> @@ -315,14 +339,14 @@ static int add_changeset_property(struct overlay_changeset *ovcs,
>>
>> /**
>> * add_changeset_node() - add @node (and children) to overlay changeset
>> - * @ovcs: overlay changeset
>> - * @target_node: where to place @node in live tree
>> - * @node: node from within overlay device tree fragment
>> + * @ovcs: overlay changeset
>> + * @target: where @overlay_prop will be placed in live tree or changeset
>> + * @node: node from within overlay device tree fragment
>> *
>> - * If @node does not already exist in @target_node, add changeset entry
>> - * to add @node in @target_node.
>> + * If @node does not already exist in @target, add changeset entry
>> + * to add @node in @target.
>> *
>> - * If @node already exists in @target_node, and the existing node has
>> + * If @node already exists in @target, and the existing node has
>> * a phandle, the overlay node is not allowed to have a phandle.
>> *
>> * If @node has child nodes, add the children recursively via
>> @@ -355,15 +379,16 @@ static int add_changeset_property(struct overlay_changeset *ovcs,
>> * invalid @overlay.
>> */
>> static int add_changeset_node(struct overlay_changeset *ovcs,
>> - struct device_node *target_node, struct device_node *node)
>> + struct target *target, struct device_node *node)
>> {
>> const char *node_kbasename;
>> struct device_node *tchild;
>> + struct target target_child;
>> int ret = 0;
>>
>> node_kbasename = kbasename(node->full_name);
>>
>> - for_each_child_of_node(target_node, tchild)
>> + for_each_child_of_node(target->np, tchild)
>> if (!of_node_cmp(node_kbasename, kbasename(tchild->full_name)))
>> break;
>>
>> @@ -372,22 +397,28 @@ static int add_changeset_node(struct overlay_changeset *ovcs,
>> if (!tchild)
>> return -ENOMEM;
>>
>> - tchild->parent = target_node;
>> + tchild->parent = target->np;
>> of_node_set_flag(tchild, OF_OVERLAY);
>>
>> ret = of_changeset_attach_node(&ovcs->cset, tchild);
>> if (ret)
>> return ret;
>>
>> - ret = build_changeset_next_level(ovcs, tchild, node);
>> + target_child.np = tchild;
>> + target_child.in_livetree = false;
>> +
>> + ret = build_changeset_next_level(ovcs, &target_child, node);
>> of_node_put(tchild);
>> return ret;
>> }
>>
>> - if (node->phandle && tchild->phandle)
>> + if (node->phandle && tchild->phandle) {
>> ret = -EINVAL;
>> - else
>> - ret = build_changeset_next_level(ovcs, tchild, node);
>> + } else {
>> + target_child.np = tchild;
>> + target_child.in_livetree = target->in_livetree;
>> + ret = build_changeset_next_level(ovcs, &target_child, node);
>> + }
>> of_node_put(tchild);
>>
>> return ret;
>> @@ -396,7 +427,7 @@ static int add_changeset_node(struct overlay_changeset *ovcs,
>> /**
>> * build_changeset_next_level() - add level of overlay changeset
>> * @ovcs: overlay changeset
>> - * @target_node: where to place @overlay_node in live tree
>> + * @target: where to place @overlay_node in live tree
>> * @overlay_node: node from within an overlay device tree fragment
>> *
>> * Add the properties (if any) and nodes (if any) from @overlay_node to the
>> @@ -409,27 +440,26 @@ static int add_changeset_node(struct overlay_changeset *ovcs,
>> * invalid @overlay_node.
>> */
>> static int build_changeset_next_level(struct overlay_changeset *ovcs,
>> - struct device_node *target_node,
>> - const struct device_node *overlay_node)
>> + struct target *target, const struct device_node *overlay_node)
>> {
>> struct device_node *child;
>> struct property *prop;
>> int ret;
>>
>> for_each_property_of_node(overlay_node, prop) {
>> - ret = add_changeset_property(ovcs, target_node, prop, 0);
>> + ret = add_changeset_property(ovcs, target, prop, 0);
>> if (ret) {
>> pr_debug("Failed to apply prop @%pOF/%s, err=%d\n",
>> - target_node, prop->name, ret);
>> + target->np, prop->name, ret);
>> return ret;
>> }
>> }
>>
>> for_each_child_of_node(overlay_node, child) {
>> - ret = add_changeset_node(ovcs, target_node, child);
>> + ret = add_changeset_node(ovcs, target, child);
>> if (ret) {
>> pr_debug("Failed to apply node @%pOF/%s, err=%d\n",
>> - target_node, child->name, ret);
>> + target->np, child->name, ret);
>> of_node_put(child);
>> return ret;
>> }
>> @@ -442,17 +472,17 @@ static int build_changeset_next_level(struct overlay_changeset *ovcs,
>> * Add the properties from __overlay__ node to the @ovcs->cset changeset.
>> */
>> static int build_changeset_symbols_node(struct overlay_changeset *ovcs,
>> - struct device_node *target_node,
>> + struct target *target,
>> const struct device_node *overlay_symbols_node)
>> {
>> struct property *prop;
>> int ret;
>>
>> for_each_property_of_node(overlay_symbols_node, prop) {
>> - ret = add_changeset_property(ovcs, target_node, prop, 1);
>> + ret = add_changeset_property(ovcs, target, prop, 1);
>> if (ret) {
>> pr_debug("Failed to apply prop @%pOF/%s, err=%d\n",
>> - target_node, prop->name, ret);
>> + target->np, prop->name, ret);
>> return ret;
>> }
>> }
>> @@ -475,6 +505,7 @@ static int build_changeset_symbols_node(struct overlay_changeset *ovcs,
>> static int build_changeset(struct overlay_changeset *ovcs)
>> {
>> struct fragment *fragment;
>> + struct target target;
>> int fragments_count, i, ret;
>>
>> /*
>> @@ -489,7 +520,9 @@ static int build_changeset(struct overlay_changeset *ovcs)
>> for (i = 0; i < fragments_count; i++) {
>> fragment = &ovcs->fragments[i];
>>
>> - ret = build_changeset_next_level(ovcs, fragment->target,
>> + target.np = fragment->target;
>> + target.in_livetree = true;
>> + ret = build_changeset_next_level(ovcs, &target,
>> fragment->overlay);
>> if (ret) {
>> pr_debug("apply failed '%pOF'\n", fragment->target);
>> @@ -499,7 +532,10 @@ static int build_changeset(struct overlay_changeset *ovcs)
>>
>> if (ovcs->symbols_fragment) {
>> fragment = &ovcs->fragments[ovcs->count - 1];
>> - ret = build_changeset_symbols_node(ovcs, fragment->target,
>> +
>> + target.np = fragment->target;
>> + target.in_livetree = true;
>> + ret = build_changeset_symbols_node(ovcs, &target,
>> fragment->overlay);
>> if (ret) {
>> pr_debug("apply failed '%pOF'\n", fragment->target);
>> @@ -517,7 +553,7 @@ static int build_changeset(struct overlay_changeset *ovcs)
>> * 1) "target" property containing the phandle of the target
>> * 2) "target-path" property containing the path of the target
>> */
>> -static struct device_node *find_target_node(struct device_node *info_node)
>> +static struct device_node *find_target(struct device_node *info_node)
>> {
>> struct device_node *node;
>> const char *path;
>> @@ -623,7 +659,7 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs,
>>
>> fragment = &fragments[cnt];
>> fragment->overlay = overlay_node;
>> - fragment->target = find_target_node(node);
>> + fragment->target = find_target(node);
>> if (!fragment->target) {
>> of_node_put(fragment->overlay);
>> ret = -EINVAL;
>> --
>> Frank Rowand <frank.rowand@sony.com>
>>
>
^ permalink raw reply
* [PATCH 2/2] powerpc/boot: Fix opal console in boot wrapper
From: Joel Stanley @ 2018-10-09 23:28 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Oliver O'Halloran
In-Reply-To: <20181009232803.15072-1-joel@jms.id.au>
As of commit 10c77dba40ff ("powerpc/boot: Fix build failure in 32-bit
boot wrapper") the opal code is hidden behind CONFIG_PPC64_BOOT_WRAPPER,
but the boot wrapper avoids include/linux, so it does not get the normal
Kconfig flags.
We can drop the guard entirely as in commit f8e8e69cea49 ("powerpc/boot:
Only build OPAL code when necessary") the makefile only includes opal.c
in the build if CONFIG_PPC64_BOOT_WRAPPER is set.
Fixes: 10c77dba40ff ("powerpc/boot: Fix build failure in 32-bit boot wrapper")
Signed-off-by: Joel Stanley <joel@jms.id.au>
---
I wrote this patch before the kconfig one. We could use autoconf.h, or
fold this in, but I think the clean up of the redundant ifdef is cleaner.
arch/powerpc/boot/opal.c | 8 --------
1 file changed, 8 deletions(-)
diff --git a/arch/powerpc/boot/opal.c b/arch/powerpc/boot/opal.c
index 0272570d02de..dfb199ef5b94 100644
--- a/arch/powerpc/boot/opal.c
+++ b/arch/powerpc/boot/opal.c
@@ -13,8 +13,6 @@
#include <libfdt.h>
#include "../include/asm/opal-api.h"
-#ifdef CONFIG_PPC64_BOOT_WRAPPER
-
/* Global OPAL struct used by opal-call.S */
struct opal {
u64 base;
@@ -101,9 +99,3 @@ int opal_console_init(void *devp, struct serial_console_data *scdp)
return 0;
}
-#else
-int opal_console_init(void *devp, struct serial_console_data *scdp)
-{
- return -1;
-}
-#endif /* __powerpc64__ */
--
2.17.1
^ permalink raw reply related
* [PATCH 1/2] powerpc/boot: Expose Kconfig symbols to wrapper
From: Joel Stanley @ 2018-10-09 23:28 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Oliver O'Halloran
In-Reply-To: <20181009232803.15072-1-joel@jms.id.au>
Currently the wrapper is built without including anything in
$(src)/include/, which means there are no CONFIG_ symbols defined. This
means the platform specific serial drivers were never enabled.
We now copy the definitions into the boot directory, so any C file can
now include autoconf.h to depend on configuration options.
Fixes: 866bfc75f40e ("powerpc: conditionally compile platform-specific serial drivers")
Signed-off-by: Joel Stanley <joel@jms.id.au>
---
arch/powerpc/boot/.gitignore | 1 +
arch/powerpc/boot/Makefile | 7 ++++++-
arch/powerpc/boot/serial.c | 1 +
3 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/boot/.gitignore b/arch/powerpc/boot/.gitignore
index f92d0530ceb1..32034a0cc554 100644
--- a/arch/powerpc/boot/.gitignore
+++ b/arch/powerpc/boot/.gitignore
@@ -44,4 +44,5 @@ fdt_sw.c
fdt_wip.c
libfdt.h
libfdt_internal.h
+autoconf.h
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 0fb96c26136f..eeed74e0dfca 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -197,9 +197,14 @@ $(obj)/empty.c:
$(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds : $(obj)/%: $(srctree)/$(src)/%.S
$(Q)cp $< $@
+$(obj)/serial.c: $(obj)/autoconf.h
+
+$(obj)/autoconf.h: $(obj)/%: $(srctree)/include/generated/%
+ $(Q)cp $< $@
+
clean-files := $(zlib-) $(zlibheader-) $(zliblinuxheader-) \
$(zlib-decomp-) $(libfdt) $(libfdtheader) \
- empty.c zImage.coff.lds zImage.ps3.lds zImage.lds
+ autoconf.h empty.c zImage.coff.lds zImage.ps3.lds zImage.lds
quiet_cmd_bootcc = BOOTCC $@
cmd_bootcc = $(BOOTCC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $<
diff --git a/arch/powerpc/boot/serial.c b/arch/powerpc/boot/serial.c
index 48e3743faedf..f045f8494bf9 100644
--- a/arch/powerpc/boot/serial.c
+++ b/arch/powerpc/boot/serial.c
@@ -18,6 +18,7 @@
#include "stdio.h"
#include "io.h"
#include "ops.h"
+#include "autoconf.h"
static int serial_open(void)
{
--
2.17.1
^ permalink raw reply related
* [PATCH 0/2] powerpc/boot: Fix serial output in boot wrapper
From: Joel Stanley @ 2018-10-09 23:28 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Oliver O'Halloran
While doing some work on the wrapper I noticed we no longer get serial
output on a powernv system. This is because we compile out the opal
code.
As it turns out, none of the system-specific serial outputs will be
compiled in. This series fixes that. Tested on Qemu powernv, Romulus and
Palmetto.
Joel Stanley (2):
powerpc/boot: Expose Kconfig symbols to wrapper
powerpc/boot: Fix opal console in boot wrapper
arch/powerpc/boot/.gitignore | 1 +
arch/powerpc/boot/Makefile | 7 ++++++-
arch/powerpc/boot/opal.c | 8 --------
arch/powerpc/boot/serial.c | 1 +
4 files changed, 8 insertions(+), 9 deletions(-)
--
2.17.1
^ permalink raw reply
* Re: [PATCH] memblock: stop using implicit alignement to SMP_CACHE_BYTES
From: Paul Burton @ 2018-10-09 23:01 UTC (permalink / raw)
To: Mike Rapoport
Cc: linux-mips@linux-mips.org, Michal Hocko,
linux-ia64@vger.kernel.org, Catalin Marinas, linux-mm@kvack.org,
Richard Weinberger, Russell King, Ingo Molnar, Geert Uytterhoeven,
Matt Turner, linux-um@lists.infradead.org,
linux-m68k@lists.linux-m68k.org, Thomas Gleixner, Guan Xuetao,
linux-arm-kernel@lists.infradead.org, Chris Zankel, Michal Simek,
Tony Luck, linux-kernel@vger.kernel.org,
linux-alpha@vger.kernel.org, Andrew Morton,
linuxppc-dev@lists.ozlabs.org
In-Reply-To: <1538687224-17535-1-git-send-email-rppt@linux.vnet.ibm.com>
Hi Mike,
On Fri, Oct 05, 2018 at 12:07:04AM +0300, Mike Rapoport wrote:
> When a memblock allocation APIs are called with align = 0, the alignment is
> implicitly set to SMP_CACHE_BYTES.
>
> Replace all such uses of memblock APIs with the 'align' parameter explicitly
> set to SMP_CACHE_BYTES and stop implicit alignment assignment in the
> memblock internal allocation functions.
>
>%
>
> Suggested-by: Michal Hocko <mhocko@suse.com>
> Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com>
Acked-by: Paul Burton <paul.burton@mips.com> # MIPS part
Thanks,
Paul
^ permalink raw reply
* [PATCH v04 4/4] migration/memory: Support 'ibm,dynamic-memory-v2'
From: Michael Bringmann @ 2018-10-09 20:37 UTC (permalink / raw)
To: linuxppc-dev, mwb
Cc: Juliet Kim, Thomas Falcon, Tyrel Datwyler, Nathan Fontenot
In-Reply-To: <20181009203520.26091.86781.stgit@ltcalpine2-lp9.aus.stglabs.ibm.com>
migration/memory: This patch adds recognition for changes to the
associativity of memory blocks described by 'ibm,dynamic-memory-v2'.
If the associativity of an LMB has changed, it should be readded to
the system in order to update local and general kernel data structures.
This patch builds upon previous enhancements that scan the device-tree
"ibm,dynamic-memory" properties using the base LMB array, and a copy
derived from the updated properties.
Signed-off-by: Michael Bringmann <mwb@linux.vnet.ibm.com>
---
arch/powerpc/platforms/pseries/hotplug-memory.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index a7ca22e..233ef02 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -1180,7 +1180,8 @@ static int pseries_memory_notifier(struct notifier_block *nb,
err = pseries_remove_mem_node(rd->dn);
break;
case OF_RECONFIG_UPDATE_PROPERTY:
- if (!strcmp(rd->prop->name, "ibm,dynamic-memory")) {
+ if (!strcmp(rd->prop->name, "ibm,dynamic-memory") ||
+ !strcmp(rd->prop->name, "ibm,dynamic-memory-v2")) {
struct drmem_lmb_info *dinfo =
drmem_lmbs_init(rd->prop);
if (!dinfo)
^ permalink raw reply related
* [PATCH v04 3/4] migration/memory: Evaluate LMB assoc changes
From: Michael Bringmann @ 2018-10-09 20:37 UTC (permalink / raw)
To: linuxppc-dev, mwb
Cc: Juliet Kim, Thomas Falcon, Tyrel Datwyler, Nathan Fontenot
In-Reply-To: <20181009203520.26091.86781.stgit@ltcalpine2-lp9.aus.stglabs.ibm.com>
migration/memory: This patch adds code that recognizes changes to
the associativity of memory blocks described by the device-tree
properties in order to drive equivalent 'hotplug' operations to
update local and general kernel data structures to reflect those
changes. These differences may include:
* Evaluate 'ibm,dynamic-memory' properties when processing the
updated device-tree properties of the system during Post Migration
events (migration_store). The new functionality looks for changes
to the aa_index values for each drc_index/LMB to identify any memory
blocks that should be readded.
* In an LPAR migration scenario, the "ibm,associativity-lookup-arrays"
property may change. In the event that a row of the array differs,
locate all assigned memory blocks with that 'aa_index' and 're-add'
them to the system memory block data structures. In the process of
the 're-add', the system routines will update the corresponding entry
for the memory in the LMB structures and any other relevant kernel
data structures.
A number of previous extensions made to the DRMEM code for scanning
device-tree properties and creating LMB arrays are used here to
ensure that the resulting code is simpler and more usable:
* Use new paired list iterator for the DRMEM LMB info arrays to find
differences in old and new versions of properties.
* Use new iterator for copies of the DRMEM info arrays to evaluate
completely new structures.
* Combine common code for parsing and evaluating memory description
properties based on the DRMEM LMB array model to greatly simplify
extension from the older property 'ibm,dynamic-memory' to the new
property model of 'ibm,dynamic-memory-v2'.
For support, add a new pseries hotplug action for DLPAR operations,
PSERIES_HP_ELOG_ACTION_READD_MULTIPLE. It is a variant of the READD
operation which performs the action upon multiple instances of the
resource at one time. The operation is to be triggered by device-tree
analysis of updates by RTAS events analyzed by 'migation_store' during
post-migration processing. It will be used for memory updates,
initially.
Signed-off-by: Michael Bringmann <mwb@linux.vnet.ibm.com>
---
Changes in v04:
-- Move dlpar_memory_readd_multiple() function definition and use
into previous patch along with action constant definition.
-- Correct spacing in patch
Changes in v03:
-- Modify the code that parses the memory affinity attributes to
mark relevant DRMEM LMB array entries using the internal_flags
mechanism instead of generate unique hotplug actions for each
memory block to be readded. The change is intended to both
simplify the code, and to require fewer resources on systems
with huge amounts of memory.
-- Save up notice about any all LMB entries until the end of the
'migration_store' operation at which point a single action is
queued to scan the entire DRMEM array.
-- Add READD_MULTIPLE function for memory that scans the DRMEM
array to identify multiple entries that were marked previously.
The corresponding memory blocks are to be readded to the system
to update relevant data structures outside of the powerpc-
specific code.
-- Change dlpar_memory_pmt_changes_action to directly queue worker
to pseries work queue.
---
arch/powerpc/platforms/pseries/hotplug-memory.c | 189 +++++++++++++++++++----
arch/powerpc/platforms/pseries/mobility.c | 4
arch/powerpc/platforms/pseries/pseries.h | 4
3 files changed, 163 insertions(+), 34 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index bf2420a..a7ca22e 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -534,8 +534,11 @@ static int dlpar_memory_readd_by_index(u32 drc_index)
}
}
- if (!lmb_found)
- rc = -EINVAL;
+ if (!lmb_found) {
+ pr_info("Failed to update memory for drc index %lx\n",
+ (unsigned long) drc_index);
+ return -EINVAL;
+ }
if (rc)
pr_info("Failed to update memory at %llx\n",
@@ -1002,13 +1005,43 @@ static int pseries_add_mem_node(struct device_node *np)
return (ret < 0) ? -EINVAL : 0;
}
-static int pseries_update_drconf_memory(struct of_reconfig_data *pr)
+static int pmt_changes = 0;
+
+void dlpar_memory_pmt_changes_set(void)
+{
+ pmt_changes = 1;
+}
+
+void dlpar_memory_pmt_changes_clear(void)
+{
+ pmt_changes = 0;
+}
+
+int dlpar_memory_pmt_changes(void)
+{
+ return pmt_changes;
+}
+
+void dlpar_memory_pmt_changes_action(void)
+{
+ if (dlpar_memory_pmt_changes()) {
+ struct pseries_hp_errorlog hp_errlog;
+
+ hp_errlog.resource = PSERIES_HP_ELOG_RESOURCE_MEM;
+ hp_errlog.action = PSERIES_HP_ELOG_ACTION_READD_MULTIPLE;
+ hp_errlog.id_type = 0;
+
+ queue_hotplug_event(&hp_errlog, NULL, NULL);
+
+ dlpar_memory_pmt_changes_clear();
+ }
+}
+
+static int pseries_update_drconf_memory(struct drmem_lmb_info *new_dinfo)
{
- struct of_drconf_cell_v1 *new_drmem, *old_drmem;
+ struct drmem_lmb *old_lmb, *new_lmb;
unsigned long memblock_size;
- u32 entries;
- __be32 *p;
- int i, rc = -EINVAL;
+ int rc = 0;
if (rtas_hp_event)
return 0;
@@ -1017,42 +1050,122 @@ static int pseries_update_drconf_memory(struct of_reconfig_data *pr)
if (!memblock_size)
return -EINVAL;
- p = (__be32 *) pr->old_prop->value;
- if (!p)
- return -EINVAL;
-
- /* The first int of the property is the number of lmb's described
- * by the property. This is followed by an array of of_drconf_cell
- * entries. Get the number of entries and skip to the array of
- * of_drconf_cell's.
- */
- entries = be32_to_cpu(*p++);
- old_drmem = (struct of_drconf_cell_v1 *)p;
+ /* Arrays should have the same size and DRC indexes */
+ for_each_pair_dinfo_lmb(drmem_info, old_lmb, new_dinfo, new_lmb) {
- p = (__be32 *)pr->prop->value;
- p++;
- new_drmem = (struct of_drconf_cell_v1 *)p;
+ if (new_lmb->drc_index != old_lmb->drc_index)
+ continue;
- for (i = 0; i < entries; i++) {
- if ((be32_to_cpu(old_drmem[i].flags) & DRCONF_MEM_ASSIGNED) &&
- (!(be32_to_cpu(new_drmem[i].flags) & DRCONF_MEM_ASSIGNED))) {
+ if ((old_lmb->flags & DRCONF_MEM_ASSIGNED) &&
+ (!(new_lmb->flags & DRCONF_MEM_ASSIGNED))) {
rc = pseries_remove_memblock(
- be64_to_cpu(old_drmem[i].base_addr),
- memblock_size);
+ old_lmb->base_addr, memblock_size);
break;
- } else if ((!(be32_to_cpu(old_drmem[i].flags) &
- DRCONF_MEM_ASSIGNED)) &&
- (be32_to_cpu(new_drmem[i].flags) &
- DRCONF_MEM_ASSIGNED)) {
- rc = memblock_add(be64_to_cpu(old_drmem[i].base_addr),
- memblock_size);
+ } else if ((!(old_lmb->flags & DRCONF_MEM_ASSIGNED)) &&
+ (new_lmb->flags & DRCONF_MEM_ASSIGNED)) {
+ rc = memblock_add(old_lmb->base_addr,
+ memblock_size);
rc = (rc < 0) ? -EINVAL : 0;
break;
+ } else if ((old_lmb->aa_index != new_lmb->aa_index) &&
+ (new_lmb->flags & DRCONF_MEM_ASSIGNED)) {
+ drmem_mark_lmb_update(old_lmb);
+ dlpar_memory_pmt_changes_set();
}
}
return rc;
}
+static void pseries_update_ala_memory_aai(int aa_index)
+{
+ struct drmem_lmb *lmb;
+
+ /* Readd all LMBs which were previously using the
+ * specified aa_index value.
+ */
+ for_each_drmem_lmb(lmb) {
+ if ((lmb->aa_index == aa_index) &&
+ (lmb->flags & DRCONF_MEM_ASSIGNED)) {
+ drmem_mark_lmb_update(lmb);
+ dlpar_memory_pmt_changes_set();
+ }
+ }
+}
+
+struct assoc_arrays {
+ u32 n_arrays;
+ u32 array_sz;
+ const __be32 *arrays;
+};
+
+static int pseries_update_ala_memory(struct of_reconfig_data *pr)
+{
+ struct assoc_arrays new_ala, old_ala;
+ __be32 *p;
+ int i, lim;
+
+ if (rtas_hp_event)
+ return 0;
+
+ /*
+ * The layout of the ibm,associativity-lookup-arrays
+ * property is a number N indicating the number of
+ * associativity arrays, followed by a number M
+ * indicating the size of each associativity array,
+ * followed by a list of N associativity arrays.
+ */
+
+ p = (__be32 *) pr->old_prop->value;
+ if (!p)
+ return -EINVAL;
+ old_ala.n_arrays = of_read_number(p++, 1);
+ old_ala.array_sz = of_read_number(p++, 1);
+ old_ala.arrays = p;
+
+ p = (__be32 *) pr->prop->value;
+ if (!p)
+ return -EINVAL;
+ new_ala.n_arrays = of_read_number(p++, 1);
+ new_ala.array_sz = of_read_number(p++, 1);
+ new_ala.arrays = p;
+
+ lim = (new_ala.n_arrays > old_ala.n_arrays) ? old_ala.n_arrays :
+ new_ala.n_arrays;
+
+ if (old_ala.array_sz == new_ala.array_sz) {
+
+ /* Reset any entries where the old and new rows
+ * the array have changed.
+ */
+ for (i = 0; i < lim; i++) {
+ int index = (i * new_ala.array_sz);
+
+ if (!memcmp(&old_ala.arrays[index],
+ &new_ala.arrays[index],
+ new_ala.array_sz))
+ continue;
+
+ pseries_update_ala_memory_aai(i);
+ }
+
+ /* Reset any entries representing the extra rows.
+ * There shouldn't be any, but just in case ...
+ */
+ for (i = lim; i < new_ala.n_arrays; i++)
+ pseries_update_ala_memory_aai(i);
+
+ } else {
+ /* Update all entries representing these rows;
+ * as all rows have different sizes, none can
+ * have equivalent values.
+ */
+ for (i = 0; i < lim; i++)
+ pseries_update_ala_memory_aai(i);
+ }
+
+ return 0;
+}
+
static int pseries_memory_notifier(struct notifier_block *nb,
unsigned long action, void *data)
{
@@ -1067,8 +1180,16 @@ static int pseries_memory_notifier(struct notifier_block *nb,
err = pseries_remove_mem_node(rd->dn);
break;
case OF_RECONFIG_UPDATE_PROPERTY:
- if (!strcmp(rd->prop->name, "ibm,dynamic-memory"))
- err = pseries_update_drconf_memory(rd);
+ if (!strcmp(rd->prop->name, "ibm,dynamic-memory")) {
+ struct drmem_lmb_info *dinfo =
+ drmem_lmbs_init(rd->prop);
+ if (!dinfo)
+ return -EINVAL;
+ err = pseries_update_drconf_memory(dinfo);
+ drmem_lmbs_free(dinfo);
+ } else if (!strcmp(rd->prop->name,
+ "ibm,associativity-lookup-arrays"))
+ err = pseries_update_ala_memory(rd);
break;
}
return notifier_from_errno(err);
diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
index eba7ef7..c9d3d80 100644
--- a/arch/powerpc/platforms/pseries/mobility.c
+++ b/arch/powerpc/platforms/pseries/mobility.c
@@ -373,6 +373,10 @@ static ssize_t migration_store(struct class *class,
return rc;
post_mobility_fixup();
+
+ /* Apply any necessary changes identified during fixup */
+ dlpar_memory_pmt_changes_action();
+
return count;
}
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
index 72c0b89..3352f90 100644
--- a/arch/powerpc/platforms/pseries/pseries.h
+++ b/arch/powerpc/platforms/pseries/pseries.h
@@ -71,6 +71,10 @@ static inline int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
return -EOPNOTSUPP;
}
#endif
+void dlpar_memory_pmt_changes_set(void);
+void dlpar_memory_pmt_changes_clear(void);
+int dlpar_memory_pmt_changes(void);
+void dlpar_memory_pmt_changes_action(void);
#ifdef CONFIG_HOTPLUG_CPU
int dlpar_cpu(struct pseries_hp_errorlog *hp_elog);
^ permalink raw reply related
* [PATCH v04 3/5] migration/memory: Add hotplug READD_MULTIPLE
From: Michael Bringmann @ 2018-10-09 20:36 UTC (permalink / raw)
To: linuxppc-dev, mwb
Cc: Juliet Kim, Thomas Falcon, Tyrel Datwyler, Nathan Fontenot
In-Reply-To: <20181009203520.26091.86781.stgit@ltcalpine2-lp9.aus.stglabs.ibm.com>
migration/memory: This patch adds a new pseries hotplug action
for CPU and memory operations, PSERIES_HP_ELOG_ACTION_READD_MULTIPLE.
This is a variant of the READD operation which performs the action
upon multiple instances of the resource at one time. The operation
is to be triggered by device-tree analysis of updates by RTAS events
analyzed by 'migation_store' during post-migration processing. It
will be used for memory updates, initially.
Signed-off-by: Michael Bringmann <mwb@linux.vnet.ibm.com>
---
Changes in v04:
-- Move init of 'lmb->internal_flags' in init_drmem_v2_lmbs to
previous patch.
-- Pull in implementation of dlpar_memory_readd_multiple() to go
with operation flag.
---
arch/powerpc/include/asm/rtas.h | 1 +
arch/powerpc/platforms/pseries/hotplug-memory.c | 31 +++++++++++++++++++++++
2 files changed, 32 insertions(+)
diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index 0183e95..cc00451 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -333,6 +333,7 @@ struct pseries_hp_errorlog {
#define PSERIES_HP_ELOG_ACTION_ADD 1
#define PSERIES_HP_ELOG_ACTION_REMOVE 2
#define PSERIES_HP_ELOG_ACTION_READD 3
+#define PSERIES_HP_ELOG_ACTION_READD_MULTIPLE 4
#define PSERIES_HP_ELOG_ID_DRC_NAME 1
#define PSERIES_HP_ELOG_ID_DRC_INDEX 2
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index 9a15d39..bf2420a 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -546,6 +546,30 @@ static int dlpar_memory_readd_by_index(u32 drc_index)
return rc;
}
+static int dlpar_memory_readd_multiple(void)
+{
+ struct drmem_lmb *lmb;
+ int rc;
+
+ pr_info("Attempting to update multiple LMBs\n");
+
+ for_each_drmem_lmb(lmb) {
+ if (drmem_lmb_update(lmb)) {
+ rc = dlpar_remove_lmb(lmb);
+
+ if (!rc) {
+ rc = dlpar_add_lmb(lmb);
+ if (rc)
+ dlpar_release_drc(lmb->drc_index);
+ }
+
+ drmem_remove_lmb_update(lmb);
+ }
+ }
+
+ return rc;
+}
+
static int dlpar_memory_remove_by_ic(u32 lmbs_to_remove, u32 drc_index)
{
struct drmem_lmb *lmb, *start_lmb, *end_lmb;
@@ -646,6 +670,10 @@ static int dlpar_memory_readd_by_index(u32 drc_index)
{
return -EOPNOTSUPP;
}
+static int dlpar_memory_readd_multiple(void)
+{
+ return -EOPNOTSUPP;
+}
static int dlpar_memory_remove_by_ic(u32 lmbs_to_remove, u32 drc_index)
{
@@ -923,6 +951,9 @@ int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
drc_index = hp_elog->_drc_u.drc_index;
rc = dlpar_memory_readd_by_index(drc_index);
break;
+ case PSERIES_HP_ELOG_ACTION_READD_MULTIPLE:
+ rc = dlpar_memory_readd_multiple();
+ break;
default:
pr_err("Invalid action (%d) specified\n", hp_elog->action);
rc = -EINVAL;
^ permalink raw reply related
* [PATCH v04 2/5] powerpc/drmem: Add internal_flags feature
From: Michael Bringmann @ 2018-10-09 20:36 UTC (permalink / raw)
To: linuxppc-dev, mwb
Cc: Juliet Kim, Thomas Falcon, Tyrel Datwyler, Nathan Fontenot
In-Reply-To: <20181009203520.26091.86781.stgit@ltcalpine2-lp9.aus.stglabs.ibm.com>
powerpc/drmem: Add internal_flags field to each LMB to allow
marking of kernel software-specific operations that need not
be exported to other users. For instance, if information about
selected LMBs needs to be maintained for subsequent passes
through the system, it can be encoded into the LMB array itself
without requiring the allocation and maintainance of additional
data structures.
Signed-off-by: Michael Bringmann <mwb@linux.vnet.ibm.com>
---
Changes in v04:
-- Add another initialization of 'lmb->internal_flags' to
init_drmem_v2_lmbs.
---
arch/powerpc/include/asm/drmem.h | 18 ++++++++++++++++++
arch/powerpc/mm/drmem.c | 3 +++
2 files changed, 21 insertions(+)
diff --git a/arch/powerpc/include/asm/drmem.h b/arch/powerpc/include/asm/drmem.h
index 1fbb684..6c5df92 100644
--- a/arch/powerpc/include/asm/drmem.h
+++ b/arch/powerpc/include/asm/drmem.h
@@ -17,6 +17,7 @@ struct drmem_lmb {
u32 drc_index;
u32 aa_index;
u32 flags;
+ u32 internal_flags;
};
struct drmem_lmb_info {
@@ -101,6 +102,23 @@ static inline bool drmem_lmb_reserved(struct drmem_lmb *lmb)
return lmb->flags & DRMEM_LMB_RESERVED;
}
+#define DRMEM_LMBINT_UPDATE 0x00000001
+
+static inline void drmem_mark_lmb_update(struct drmem_lmb *lmb)
+{
+ lmb->internal_flags |= DRMEM_LMBINT_UPDATE;
+}
+
+static inline void drmem_remove_lmb_update(struct drmem_lmb *lmb)
+{
+ lmb->internal_flags &= ~DRMEM_LMBINT_UPDATE;
+}
+
+static inline bool drmem_lmb_update(struct drmem_lmb *lmb)
+{
+ return lmb->internal_flags & DRMEM_LMBINT_UPDATE;
+}
+
u64 drmem_lmb_memory_max(void);
void __init walk_drmem_lmbs(struct device_node *dn,
void (*func)(struct drmem_lmb *, const __be32 **));
diff --git a/arch/powerpc/mm/drmem.c b/arch/powerpc/mm/drmem.c
index 13d2abb..2228586 100644
--- a/arch/powerpc/mm/drmem.c
+++ b/arch/powerpc/mm/drmem.c
@@ -207,6 +207,7 @@ static void read_drconf_v1_cell(struct drmem_lmb *lmb,
lmb->aa_index = of_read_number(p++, 1);
lmb->flags = of_read_number(p++, 1);
+ lmb->internal_flags = 0;
*prop = p;
}
@@ -265,6 +266,7 @@ static void __walk_drmem_v2_lmbs(const __be32 *prop, const __be32 *usm,
lmb.aa_index = dr_cell.aa_index;
lmb.flags = dr_cell.flags;
+ lmb.internal_flags = 0;
func(&lmb, &usm);
}
@@ -420,6 +422,7 @@ static void init_drmem_v2_lmbs(const __be32 *prop,
lmb->aa_index = dr_cell.aa_index;
lmb->flags = dr_cell.flags;
+ lmb->internal_flags = 0;
}
}
}
^ permalink raw reply related
* [PATCH v04 1/5] powerpc/drmem: Export 'dynamic-memory' loader
From: Michael Bringmann @ 2018-10-09 20:36 UTC (permalink / raw)
To: linuxppc-dev, mwb
Cc: Juliet Kim, Thomas Falcon, Tyrel Datwyler, Nathan Fontenot
In-Reply-To: <20181009203520.26091.86781.stgit@ltcalpine2-lp9.aus.stglabs.ibm.com>
powerpc/drmem: Export many of the functions of DRMEM to parse
"ibm,dynamic-memory" and "ibm,dynamic-memory-v2" during hotplug
operations and for Post Migration events.
Also modify the DRMEM initialization code to allow it to,
* Be called after system initialization
* Provide a separate user copy of the LMB array that is produces
* Free the user copy upon request
In addition, a couple of changes were made to make the creation
of additional copies of the LMB array more useful including,
* Add new iterator to work through a pair of drmem_info arrays.
* Modify DRMEM code to replace usages of dt_root_addr_cells, and
dt_mem_next_cell, as these are only available at first boot.
Signed-off-by: Michael Bringmann <mwb@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/drmem.h | 15 ++++++++
arch/powerpc/mm/drmem.c | 75 ++++++++++++++++++++++++++++----------
2 files changed, 70 insertions(+), 20 deletions(-)
diff --git a/arch/powerpc/include/asm/drmem.h b/arch/powerpc/include/asm/drmem.h
index 7c1d8e7..1fbb684 100644
--- a/arch/powerpc/include/asm/drmem.h
+++ b/arch/powerpc/include/asm/drmem.h
@@ -35,6 +35,18 @@ struct drmem_lmb_info {
&drmem_info->lmbs[0], \
&drmem_info->lmbs[drmem_info->n_lmbs - 1])
+#define for_each_dinfo_lmb(dinfo, lmb) \
+ for_each_drmem_lmb_in_range((lmb), \
+ &dinfo->lmbs[0], \
+ &dinfo->lmbs[dinfo->n_lmbs - 1])
+
+#define for_each_pair_dinfo_lmb(dinfo1, lmb1, dinfo2, lmb2) \
+ for ((lmb1) = (&dinfo1->lmbs[0]), \
+ (lmb2) = (&dinfo2->lmbs[0]); \
+ ((lmb1) <= (&dinfo1->lmbs[dinfo1->n_lmbs - 1])) && \
+ ((lmb2) <= (&dinfo2->lmbs[dinfo2->n_lmbs - 1])); \
+ (lmb1)++, (lmb2)++)
+
/*
* The of_drconf_cell_v1 struct defines the layout of the LMB data
* specified in the ibm,dynamic-memory device tree property.
@@ -94,6 +106,9 @@ void __init walk_drmem_lmbs(struct device_node *dn,
void (*func)(struct drmem_lmb *, const __be32 **));
int drmem_update_dt(void);
+struct drmem_lmb_info *drmem_lmbs_init(struct property *prop);
+void drmem_lmbs_free(struct drmem_lmb_info *dinfo);
+
#ifdef CONFIG_PPC_PSERIES
void __init walk_drmem_lmbs_early(unsigned long node,
void (*func)(struct drmem_lmb *, const __be32 **));
diff --git a/arch/powerpc/mm/drmem.c b/arch/powerpc/mm/drmem.c
index 3f18036..13d2abb 100644
--- a/arch/powerpc/mm/drmem.c
+++ b/arch/powerpc/mm/drmem.c
@@ -20,6 +20,7 @@
static struct drmem_lmb_info __drmem_info;
struct drmem_lmb_info *drmem_info = &__drmem_info;
+static int n_root_addr_cells;
u64 drmem_lmb_memory_max(void)
{
@@ -193,12 +194,13 @@ int drmem_update_dt(void)
return rc;
}
-static void __init read_drconf_v1_cell(struct drmem_lmb *lmb,
+static void read_drconf_v1_cell(struct drmem_lmb *lmb,
const __be32 **prop)
{
const __be32 *p = *prop;
- lmb->base_addr = dt_mem_next_cell(dt_root_addr_cells, &p);
+ lmb->base_addr = of_read_number(p, n_root_addr_cells);
+ p += n_root_addr_cells;
lmb->drc_index = of_read_number(p++, 1);
p++; /* skip reserved field */
@@ -209,7 +211,7 @@ static void __init read_drconf_v1_cell(struct drmem_lmb *lmb,
*prop = p;
}
-static void __init __walk_drmem_v1_lmbs(const __be32 *prop, const __be32 *usm,
+static void __walk_drmem_v1_lmbs(const __be32 *prop, const __be32 *usm,
void (*func)(struct drmem_lmb *, const __be32 **))
{
struct drmem_lmb lmb;
@@ -225,13 +227,14 @@ static void __init __walk_drmem_v1_lmbs(const __be32 *prop, const __be32 *usm,
}
}
-static void __init read_drconf_v2_cell(struct of_drconf_cell_v2 *dr_cell,
+static void read_drconf_v2_cell(struct of_drconf_cell_v2 *dr_cell,
const __be32 **prop)
{
const __be32 *p = *prop;
dr_cell->seq_lmbs = of_read_number(p++, 1);
- dr_cell->base_addr = dt_mem_next_cell(dt_root_addr_cells, &p);
+ dr_cell->base_addr = of_read_number(p, n_root_addr_cells);
+ p += n_root_addr_cells;
dr_cell->drc_index = of_read_number(p++, 1);
dr_cell->aa_index = of_read_number(p++, 1);
dr_cell->flags = of_read_number(p++, 1);
@@ -239,7 +242,7 @@ static void __init read_drconf_v2_cell(struct of_drconf_cell_v2 *dr_cell,
*prop = p;
}
-static void __init __walk_drmem_v2_lmbs(const __be32 *prop, const __be32 *usm,
+static void __walk_drmem_v2_lmbs(const __be32 *prop, const __be32 *usm,
void (*func)(struct drmem_lmb *, const __be32 **))
{
struct of_drconf_cell_v2 dr_cell;
@@ -275,6 +278,9 @@ void __init walk_drmem_lmbs_early(unsigned long node,
const __be32 *prop, *usm;
int len;
+ if (n_root_addr_cells == 0)
+ n_root_addr_cells = dt_root_addr_cells;
+
prop = of_get_flat_dt_prop(node, "ibm,lmb-size", &len);
if (!prop || len < dt_root_size_cells * sizeof(__be32))
return;
@@ -353,24 +359,26 @@ void __init walk_drmem_lmbs(struct device_node *dn,
}
}
-static void __init init_drmem_v1_lmbs(const __be32 *prop)
+static void init_drmem_v1_lmbs(const __be32 *prop,
+ struct drmem_lmb_info *dinfo)
{
struct drmem_lmb *lmb;
- drmem_info->n_lmbs = of_read_number(prop++, 1);
- if (drmem_info->n_lmbs == 0)
+ dinfo->n_lmbs = of_read_number(prop++, 1);
+ if (dinfo->n_lmbs == 0)
return;
- drmem_info->lmbs = kcalloc(drmem_info->n_lmbs, sizeof(*lmb),
+ dinfo->lmbs = kcalloc(dinfo->n_lmbs, sizeof(*lmb),
GFP_KERNEL);
- if (!drmem_info->lmbs)
+ if (!dinfo->lmbs)
return;
- for_each_drmem_lmb(lmb)
+ for_each_dinfo_lmb(dinfo, lmb)
read_drconf_v1_cell(lmb, &prop);
}
-static void __init init_drmem_v2_lmbs(const __be32 *prop)
+static void init_drmem_v2_lmbs(const __be32 *prop,
+ struct drmem_lmb_info *dinfo)
{
struct drmem_lmb *lmb;
struct of_drconf_cell_v2 dr_cell;
@@ -386,12 +394,12 @@ static void __init init_drmem_v2_lmbs(const __be32 *prop)
p = prop;
for (i = 0; i < lmb_sets; i++) {
read_drconf_v2_cell(&dr_cell, &p);
- drmem_info->n_lmbs += dr_cell.seq_lmbs;
+ dinfo->n_lmbs += dr_cell.seq_lmbs;
}
- drmem_info->lmbs = kcalloc(drmem_info->n_lmbs, sizeof(*lmb),
+ dinfo->lmbs = kcalloc(dinfo->n_lmbs, sizeof(*lmb),
GFP_KERNEL);
- if (!drmem_info->lmbs)
+ if (!dinfo->lmbs)
return;
/* second pass, read in the LMB information */
@@ -402,10 +410,10 @@ static void __init init_drmem_v2_lmbs(const __be32 *prop)
read_drconf_v2_cell(&dr_cell, &p);
for (j = 0; j < dr_cell.seq_lmbs; j++) {
- lmb = &drmem_info->lmbs[lmb_index++];
+ lmb = &dinfo->lmbs[lmb_index++];
lmb->base_addr = dr_cell.base_addr;
- dr_cell.base_addr += drmem_info->lmb_size;
+ dr_cell.base_addr += dinfo->lmb_size;
lmb->drc_index = dr_cell.drc_index;
dr_cell.drc_index++;
@@ -416,11 +424,38 @@ static void __init init_drmem_v2_lmbs(const __be32 *prop)
}
}
+void drmem_lmbs_free(struct drmem_lmb_info *dinfo)
+{
+ if (dinfo) {
+ kfree(dinfo->lmbs);
+ kfree(dinfo);
+ }
+}
+
+struct drmem_lmb_info *drmem_lmbs_init(struct property *prop)
+{
+ struct drmem_lmb_info *dinfo;
+
+ dinfo = kzalloc(sizeof(*dinfo), GFP_KERNEL);
+ if (!dinfo)
+ return NULL;
+
+ if (!strcmp("ibm,dynamic-memory", prop->name))
+ init_drmem_v1_lmbs(prop->value, dinfo);
+ else if (!strcmp("ibm,dynamic-memory-v2", prop->name))
+ init_drmem_v2_lmbs(prop->value, dinfo);
+
+ return dinfo;
+}
+
static int __init drmem_init(void)
{
struct device_node *dn;
const __be32 *prop;
+ if (n_root_addr_cells == 0)
+ n_root_addr_cells = dt_root_addr_cells;
+
dn = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
if (!dn) {
pr_info("No dynamic reconfiguration memory found\n");
@@ -434,11 +469,11 @@ static int __init drmem_init(void)
prop = of_get_property(dn, "ibm,dynamic-memory", NULL);
if (prop) {
- init_drmem_v1_lmbs(prop);
+ init_drmem_v1_lmbs(prop, drmem_info);
} else {
prop = of_get_property(dn, "ibm,dynamic-memory-v2", NULL);
if (prop)
- init_drmem_v2_lmbs(prop);
+ init_drmem_v2_lmbs(prop, drmem_info);
}
of_node_put(dn);
^ permalink raw reply related
* [PATCH v04 0/5] powerpc/migration: Affinity fix for memory
From: Michael Bringmann @ 2018-10-09 20:35 UTC (permalink / raw)
To: linuxppc-dev, mwb
Cc: Juliet Kim, Thomas Falcon, Tyrel Datwyler, Nathan Fontenot
The migration of LPARs across Power systems affects many attributes
including that of the associativity of memory blocks. The patches
in this set execute when a system is coming up fresh upon a migration
target. They are intended to,
* Recognize changes to the associativity of memory recorded in
internal data structures when compared to the latest copies in
the device tree (e.g. ibm,dynamic-memory, ibm,dynamic-memory-v2).
* Recognize changes to the associativity mapping (e.g. ibm,
associativity-lookup-arrays), locate all assigned memory blocks
corresponding to each changed row, and readd all such blocks.
* Generate calls to other code layers to reset the data structures
related to associativity of memory.
* Re-register the 'changed' entities into the target system.
Re-registration of memory blocks mostly entails acting as if they
have been newly hot-added into the target system.
This code builds upon features introduced in a previous patch set
that updates CPUs for affinity changes that may occur during LPM.
Signed-off-by: Michael Bringmann <mwb@linux.vnet.ibm.com>
Michael Bringmann (5):
powerpc/drmem: Export 'dynamic-memory' loader
powerpc/drmem: Add internal_flags feature
migration/memory: Add hotplug flags READD_MULTIPLE
migration/memory: Evaluate LMB assoc changes
migration/memory: Support 'ibm,dynamic-memory-v2'
---
Changes in v04:
-- Move dlpar_memory_readd_multiple() to patch with new ACTION
constant.
-- Move init of 'lmb->internal_flags' in init_drmem_v2_lmbs to
patch with other references to flag.
-- Correct spacing in one of the patches
Changes in v03:
-- Change operation to tag changed LMBs in DRMEM array instead of
queuing a potentially huge number of structures.
-- Added another hotplug queue event for CPU/memory operations
-- Added internal_flags feature to DRMEM
-- Improve the patch description language for the patch set.
-- Revise patch set to queue worker for memory association
updates directly to pseries worker queue.
^ permalink raw reply
* Re: [PATCH 05/16] of: overlay: use prop add changeset entry for property in new nodes
From: Alan Tull @ 2018-10-09 20:28 UTC (permalink / raw)
To: Frank Rowand
Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
linux-fpga, Pantelis Antoniou, linux-kernel, Rob Herring,
Moritz Fischer, Paul Mackerras, linuxppc-dev
In-Reply-To: <1538712767-30394-6-git-send-email-frowand.list@gmail.com>
On Thu, Oct 4, 2018 at 11:14 PM <frowand.list@gmail.com> wrote:
>
> From: Frank Rowand <frank.rowand@sony.com>
>
Hi Frank,
> The changeset entry 'update property' was used for new properties in
> an overlay instead of 'add property'.
>
> The decision of whether to use 'update property' was based on whether
> the property already exists in the subtree where the node is being
> spliced into. At the top level of creating a changeset describing the
> overlay, the target node is in the live devicetree, so checking whether
> the property exists in the target node returns the correct result.
> As soon as the changeset creation algorithm recurses into a new node,
> the target is no longer in the live devicetree, but is instead in the
> detached overlay tree, thus all properties are incorrectly found to
> already exist in the target.
When I applied an overlay (that added a few gpio controllers, etc),
the node names for nodes added from the overlay end up NULL. It
seems related to this patch and the next one. I haven't completely
root caused this but if I back out to before this patch, the situation
is fixed.
root@arria10:~/unit_tests# ls /sys/bus/platform/drivers/altera_gpio/
bind ff200010.<NULL> ff200020.<NULL> ff200030.<NULL>
uevent unbind
root@arria10:~/unit_tests# ls /sys/bus/platform/drivers/altera_freeze_br/
bind ff200450.<NULL> uevent unbind
Alan
>
> This fix will expose another devicetree bug that will be fixed
> in the following patch in the series.
>
> When this patch is applied the errors reported by the devictree
> unittest will change, and the unittest results will change from:
>
> ### dt-test ### end of unittest - 210 passed, 0 failed
>
> to
>
> ### dt-test ### end of unittest - 203 passed, 7 failed
>
> Signed-off-by: Frank Rowand <frank.rowand@sony.com>
> ---
> drivers/of/overlay.c | 112 ++++++++++++++++++++++++++++++++++-----------------
> 1 file changed, 74 insertions(+), 38 deletions(-)
>
> diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
> index 32cfee68f2e3..0b0904f44bc7 100644
> --- a/drivers/of/overlay.c
> +++ b/drivers/of/overlay.c
> @@ -24,6 +24,26 @@
> #include "of_private.h"
>
> /**
> + * struct target - info about current target node as recursing through overlay
> + * @np: node where current level of overlay will be applied
> + * @in_livetree: @np is a node in the live devicetree
> + *
> + * Used in the algorithm to create the portion of a changeset that describes
> + * an overlay fragment, which is a devicetree subtree. Initially @np is a node
> + * in the live devicetree where the overlay subtree is targeted to be grafted
> + * into. When recursing to the next level of the overlay subtree, the target
> + * also recurses to the next level of the live devicetree, as long as overlay
> + * subtree node also exists in the live devicetree. When a node in the overlay
> + * subtree does not exist at the same level in the live devicetree, target->np
> + * points to a newly allocated node, and all subsequent targets in the subtree
> + * will be newly allocated nodes.
> + */
> +struct target {
> + struct device_node *np;
> + bool in_livetree;
> +};
> +
> +/**
> * struct fragment - info about fragment nodes in overlay expanded device tree
> * @target: target of the overlay operation
> * @overlay: pointer to the __overlay__ node
> @@ -72,8 +92,7 @@ static int devicetree_corrupt(void)
> }
>
> static int build_changeset_next_level(struct overlay_changeset *ovcs,
> - struct device_node *target_node,
> - const struct device_node *overlay_node);
> + struct target *target, const struct device_node *overlay_node);
>
> /*
> * of_resolve_phandles() finds the largest phandle in the live tree.
> @@ -257,14 +276,17 @@ static struct property *dup_and_fixup_symbol_prop(
> /**
> * add_changeset_property() - add @overlay_prop to overlay changeset
> * @ovcs: overlay changeset
> - * @target_node: where to place @overlay_prop in live tree
> + * @target: where @overlay_prop will be placed
> * @overlay_prop: property to add or update, from overlay tree
> * @is_symbols_prop: 1 if @overlay_prop is from node "/__symbols__"
> *
> - * If @overlay_prop does not already exist in @target_node, add changeset entry
> - * to add @overlay_prop in @target_node, else add changeset entry to update
> + * If @overlay_prop does not already exist in live devicetree, add changeset
> + * entry to add @overlay_prop in @target, else add changeset entry to update
> * value of @overlay_prop.
> *
> + * @target may be either in the live devicetree or in a new subtree that
> + * is contained in the changeset.
> + *
> * Some special properties are not updated (no error returned).
> *
> * Update of property in symbols node is not allowed.
> @@ -273,20 +295,22 @@ static struct property *dup_and_fixup_symbol_prop(
> * invalid @overlay.
> */
> static int add_changeset_property(struct overlay_changeset *ovcs,
> - struct device_node *target_node,
> - struct property *overlay_prop,
> + struct target *target, struct property *overlay_prop,
> bool is_symbols_prop)
> {
> struct property *new_prop = NULL, *prop;
> int ret = 0;
>
> - prop = of_find_property(target_node, overlay_prop->name, NULL);
> -
> if (!of_prop_cmp(overlay_prop->name, "name") ||
> !of_prop_cmp(overlay_prop->name, "phandle") ||
> !of_prop_cmp(overlay_prop->name, "linux,phandle"))
> return 0;
>
> + if (target->in_livetree)
> + prop = of_find_property(target->np, overlay_prop->name, NULL);
> + else
> + prop = NULL;
> +
> if (is_symbols_prop) {
> if (prop)
> return -EINVAL;
> @@ -299,10 +323,10 @@ static int add_changeset_property(struct overlay_changeset *ovcs,
> return -ENOMEM;
>
> if (!prop)
> - ret = of_changeset_add_property(&ovcs->cset, target_node,
> + ret = of_changeset_add_property(&ovcs->cset, target->np,
> new_prop);
> else
> - ret = of_changeset_update_property(&ovcs->cset, target_node,
> + ret = of_changeset_update_property(&ovcs->cset, target->np,
> new_prop);
>
> if (ret) {
> @@ -315,14 +339,14 @@ static int add_changeset_property(struct overlay_changeset *ovcs,
>
> /**
> * add_changeset_node() - add @node (and children) to overlay changeset
> - * @ovcs: overlay changeset
> - * @target_node: where to place @node in live tree
> - * @node: node from within overlay device tree fragment
> + * @ovcs: overlay changeset
> + * @target: where @overlay_prop will be placed in live tree or changeset
> + * @node: node from within overlay device tree fragment
> *
> - * If @node does not already exist in @target_node, add changeset entry
> - * to add @node in @target_node.
> + * If @node does not already exist in @target, add changeset entry
> + * to add @node in @target.
> *
> - * If @node already exists in @target_node, and the existing node has
> + * If @node already exists in @target, and the existing node has
> * a phandle, the overlay node is not allowed to have a phandle.
> *
> * If @node has child nodes, add the children recursively via
> @@ -355,15 +379,16 @@ static int add_changeset_property(struct overlay_changeset *ovcs,
> * invalid @overlay.
> */
> static int add_changeset_node(struct overlay_changeset *ovcs,
> - struct device_node *target_node, struct device_node *node)
> + struct target *target, struct device_node *node)
> {
> const char *node_kbasename;
> struct device_node *tchild;
> + struct target target_child;
> int ret = 0;
>
> node_kbasename = kbasename(node->full_name);
>
> - for_each_child_of_node(target_node, tchild)
> + for_each_child_of_node(target->np, tchild)
> if (!of_node_cmp(node_kbasename, kbasename(tchild->full_name)))
> break;
>
> @@ -372,22 +397,28 @@ static int add_changeset_node(struct overlay_changeset *ovcs,
> if (!tchild)
> return -ENOMEM;
>
> - tchild->parent = target_node;
> + tchild->parent = target->np;
> of_node_set_flag(tchild, OF_OVERLAY);
>
> ret = of_changeset_attach_node(&ovcs->cset, tchild);
> if (ret)
> return ret;
>
> - ret = build_changeset_next_level(ovcs, tchild, node);
> + target_child.np = tchild;
> + target_child.in_livetree = false;
> +
> + ret = build_changeset_next_level(ovcs, &target_child, node);
> of_node_put(tchild);
> return ret;
> }
>
> - if (node->phandle && tchild->phandle)
> + if (node->phandle && tchild->phandle) {
> ret = -EINVAL;
> - else
> - ret = build_changeset_next_level(ovcs, tchild, node);
> + } else {
> + target_child.np = tchild;
> + target_child.in_livetree = target->in_livetree;
> + ret = build_changeset_next_level(ovcs, &target_child, node);
> + }
> of_node_put(tchild);
>
> return ret;
> @@ -396,7 +427,7 @@ static int add_changeset_node(struct overlay_changeset *ovcs,
> /**
> * build_changeset_next_level() - add level of overlay changeset
> * @ovcs: overlay changeset
> - * @target_node: where to place @overlay_node in live tree
> + * @target: where to place @overlay_node in live tree
> * @overlay_node: node from within an overlay device tree fragment
> *
> * Add the properties (if any) and nodes (if any) from @overlay_node to the
> @@ -409,27 +440,26 @@ static int add_changeset_node(struct overlay_changeset *ovcs,
> * invalid @overlay_node.
> */
> static int build_changeset_next_level(struct overlay_changeset *ovcs,
> - struct device_node *target_node,
> - const struct device_node *overlay_node)
> + struct target *target, const struct device_node *overlay_node)
> {
> struct device_node *child;
> struct property *prop;
> int ret;
>
> for_each_property_of_node(overlay_node, prop) {
> - ret = add_changeset_property(ovcs, target_node, prop, 0);
> + ret = add_changeset_property(ovcs, target, prop, 0);
> if (ret) {
> pr_debug("Failed to apply prop @%pOF/%s, err=%d\n",
> - target_node, prop->name, ret);
> + target->np, prop->name, ret);
> return ret;
> }
> }
>
> for_each_child_of_node(overlay_node, child) {
> - ret = add_changeset_node(ovcs, target_node, child);
> + ret = add_changeset_node(ovcs, target, child);
> if (ret) {
> pr_debug("Failed to apply node @%pOF/%s, err=%d\n",
> - target_node, child->name, ret);
> + target->np, child->name, ret);
> of_node_put(child);
> return ret;
> }
> @@ -442,17 +472,17 @@ static int build_changeset_next_level(struct overlay_changeset *ovcs,
> * Add the properties from __overlay__ node to the @ovcs->cset changeset.
> */
> static int build_changeset_symbols_node(struct overlay_changeset *ovcs,
> - struct device_node *target_node,
> + struct target *target,
> const struct device_node *overlay_symbols_node)
> {
> struct property *prop;
> int ret;
>
> for_each_property_of_node(overlay_symbols_node, prop) {
> - ret = add_changeset_property(ovcs, target_node, prop, 1);
> + ret = add_changeset_property(ovcs, target, prop, 1);
> if (ret) {
> pr_debug("Failed to apply prop @%pOF/%s, err=%d\n",
> - target_node, prop->name, ret);
> + target->np, prop->name, ret);
> return ret;
> }
> }
> @@ -475,6 +505,7 @@ static int build_changeset_symbols_node(struct overlay_changeset *ovcs,
> static int build_changeset(struct overlay_changeset *ovcs)
> {
> struct fragment *fragment;
> + struct target target;
> int fragments_count, i, ret;
>
> /*
> @@ -489,7 +520,9 @@ static int build_changeset(struct overlay_changeset *ovcs)
> for (i = 0; i < fragments_count; i++) {
> fragment = &ovcs->fragments[i];
>
> - ret = build_changeset_next_level(ovcs, fragment->target,
> + target.np = fragment->target;
> + target.in_livetree = true;
> + ret = build_changeset_next_level(ovcs, &target,
> fragment->overlay);
> if (ret) {
> pr_debug("apply failed '%pOF'\n", fragment->target);
> @@ -499,7 +532,10 @@ static int build_changeset(struct overlay_changeset *ovcs)
>
> if (ovcs->symbols_fragment) {
> fragment = &ovcs->fragments[ovcs->count - 1];
> - ret = build_changeset_symbols_node(ovcs, fragment->target,
> +
> + target.np = fragment->target;
> + target.in_livetree = true;
> + ret = build_changeset_symbols_node(ovcs, &target,
> fragment->overlay);
> if (ret) {
> pr_debug("apply failed '%pOF'\n", fragment->target);
> @@ -517,7 +553,7 @@ static int build_changeset(struct overlay_changeset *ovcs)
> * 1) "target" property containing the phandle of the target
> * 2) "target-path" property containing the path of the target
> */
> -static struct device_node *find_target_node(struct device_node *info_node)
> +static struct device_node *find_target(struct device_node *info_node)
> {
> struct device_node *node;
> const char *path;
> @@ -623,7 +659,7 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs,
>
> fragment = &fragments[cnt];
> fragment->overlay = overlay_node;
> - fragment->target = find_target_node(node);
> + fragment->target = find_target(node);
> if (!fragment->target) {
> of_node_put(fragment->overlay);
> ret = -EINVAL;
> --
> Frank Rowand <frank.rowand@sony.com>
>
^ permalink raw reply
* [PATCH v02] powerpc/mobility: Extend start/stop topology update scope
From: Michael Bringmann @ 2018-10-09 20:12 UTC (permalink / raw)
To: linuxppc-dev, mwb
Cc: Nathan Fontenot, Juliet Kim, Thomas Falcon, Tyrel Datwyler
The PPC mobility code may receive RTAS requests to perform PRRN
topology changes at any time, including during LPAR migration
operations. In some configurations where the affinity of CPUs
or memory is being changed on that platform, the PRRN requests
may apply or refer to outdated information prior to the complete
update of the device-tree. This patch changes the duration for
which topology updates are suppressed during LPAR migrations from
just the rtas_ibm_suspend_me / 'ibm,suspend-me' call(s) to cover
the entire 'migration_store' operation to allow all changes to
the device-tree to be applied prior to accepting and applying any
PRRN requests.
For tracking purposes, pr_info notices are added to the functions
start_topology_update() and stop_topology_update() of 'numa.c'.
Signed-off-by: Michael Bringmann <mwb@linux.vnet.ibm.com>
---
Changes in v02:
-- Rebase to latest powerpc next tree.
---
arch/powerpc/kernel/rtas.c | 2 --
arch/powerpc/mm/numa.c | 6 ++++++
arch/powerpc/platforms/pseries/mobility.c | 5 +++++
3 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 2c7ed31..e02ac37 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -982,7 +982,6 @@ int rtas_ibm_suspend_me(u64 handle)
}
cpu_hotplug_disable();
- stop_topology_update();
/* Call function on all CPUs. One of us will make the
* rtas call
@@ -995,7 +994,6 @@ int rtas_ibm_suspend_me(u64 handle)
if (atomic_read(&data.error) != 0)
printk(KERN_ERR "Error doing global join\n");
- start_topology_update();
cpu_hotplug_enable();
/* Take down CPUs not online prior to suspend */
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index b5a71ba..0ade0a1 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -1518,6 +1518,10 @@ int start_topology_update(void)
}
}
+ pr_info("Starting topology update%s%s\n",
+ (prrn_enabled ? " prrn_enabled" : ""),
+ (vphn_enabled ? " vphn_enabled" : ""));
+
return rc;
}
@@ -1539,6 +1543,8 @@ int stop_topology_update(void)
rc = del_timer_sync(&topology_timer);
}
+ pr_info("Stopping topology update\n");
+
return rc;
}
diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
index 2f0f512..7da222d 100644
--- a/arch/powerpc/platforms/pseries/mobility.c
+++ b/arch/powerpc/platforms/pseries/mobility.c
@@ -367,6 +367,8 @@ static ssize_t migration_store(struct class *class,
if (rc)
return rc;
+ stop_topology_update();
+
do {
rc = rtas_ibm_suspend_me(streamid);
if (rc == -EAGAIN)
@@ -377,6 +379,9 @@ static ssize_t migration_store(struct class *class,
return rc;
post_mobility_fixup();
+
+ start_topology_update();
+
return count;
}
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox