mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCHv2 0/4] ARM64: Improve copy_page and copy_template for ThunderX
@ 2016-01-13  7:08 Andrew Pinski
  2016-01-13  7:08 ` [PATCH 1/5] ARM64: Support midr detected cpufeature Andrew Pinski
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Andrew Pinski @ 2016-01-13  7:08 UTC (permalink / raw)
  To: pinskia, linux-kernel, linux-arm-kernel, Will Deacon; +Cc: Andrew Pinski

This is version 2.  I expanded it to include copy_template as it was a simple
extension to the new version of the patch.
Changes since v1:
1) Add infastructure for checking MIDR for features
2) Use the copy_page version from Will Deacon 
3) Add prefetching feature
4) Add prefetching to copy_page
5) Add prefetching to copy_template


Andrew Pinski (5):
  ARM64: Support midr detected cpufeature
  ARM64 Improve copy_page for 128 byte cache line
  ARM64: Add Needs software prefetching cap
  ARM64: Patch in prefetching for copy_page is requested
  ARM64: Patch in prefetching in copy_template

 arch/arm64/include/asm/cpufeature.h |   29 ++++++++++++++--
 arch/arm64/include/asm/cputype.h    |    7 ++++
 arch/arm64/kernel/cpu_errata.c      |   26 --------------
 arch/arm64/kernel/cpufeature.c      |   27 ++++++++++++++-
 arch/arm64/lib/copy_page.S          |   64 ++++++++++++++++++++++++++++++----
 arch/arm64/lib/copy_template.S      |   12 ++++++
 arch/arm64/lib/memcpy.S             |    2 +
 7 files changed, 129 insertions(+), 38 deletions(-)

-- 
1.7.2.5

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

* [PATCH 1/5] ARM64: Support midr detected cpufeature
  2016-01-13  7:08 [PATCHv2 0/4] ARM64: Improve copy_page and copy_template for ThunderX Andrew Pinski
@ 2016-01-13  7:08 ` Andrew Pinski
  2016-01-13  7:08 ` [PATCH 2/5] ARM64 Improve copy_page for 128 byte cache line Andrew Pinski
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Andrew Pinski @ 2016-01-13  7:08 UTC (permalink / raw)
  To: pinskia, linux-kernel, linux-arm-kernel, Will Deacon; +Cc: Andrew Pinski

A soon to be added feature is marking the need for
software prefetching of 128 byte cache line.
This feature is not detected via bits of a system register
but rather matching of the Machine ID register.
This adds support for detecting a cpufeature by the MIDR.

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/asm/cpufeature.h |   26 ++++++++++++++++++++++++--
 arch/arm64/include/asm/cputype.h    |    7 +++++++
 arch/arm64/kernel/cpu_errata.c      |   26 --------------------------
 arch/arm64/kernel/cpufeature.c      |   21 ++++++++++++++++++++-
 4 files changed, 51 insertions(+), 29 deletions(-)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 8136afc..92aaac6 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -11,6 +11,7 @@
 
 #include <asm/hwcap.h>
 #include <asm/sysreg.h>
+#include <asm/cputype.h>
 
 /*
  * In the arm64 world (as in the ARM world), elf_hwcap is used both internally
@@ -78,14 +79,14 @@ struct arm64_cpu_capabilities {
 	u16 capability;
 	bool (*matches)(const struct arm64_cpu_capabilities *);
 	void (*enable)(void *);		/* Called on all active CPUs */
+	u32 sys_reg;
 	union {
-		struct {	/* To be used for erratum handling only */
+		struct {	/* MIDR matching used if sys_reg is SYS_MIDR_EL1. */
 			u32 midr_model;
 			u32 midr_range_min, midr_range_max;
 		};
 
 		struct {	/* Feature register checking */
-			u32 sys_reg;
 			int field_pos;
 			int min_field_value;
 			int hwcap_type;
@@ -94,6 +95,27 @@ struct arm64_cpu_capabilities {
 	};
 };
 
+static bool __maybe_unused
+is_affected_midr_range(const struct arm64_cpu_capabilities *entry)
+{
+		u32 midr = read_cpuid_id();
+
+		if ((midr & CPU_MODEL_MASK) != entry->midr_model)
+				return false;
+
+		midr &= MIDR_REVISION_MASK | MIDR_VARIANT_MASK;
+
+		return (midr >= entry->midr_range_min && midr <= entry->midr_range_max);
+}
+
+#define MIDR_RANGE(model, min, max) \
+		.matches = is_affected_midr_range, \
+		.sys_reg = SYS_MIDR_EL1, \
+		.midr_model = model, \
+		.midr_range_min = min, \
+		.midr_range_max = max
+
+
 extern DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
 
 static inline bool cpu_have_feature(unsigned int num)
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 1a59493..cd99d28a 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -75,6 +75,13 @@
 
 #define CAVIUM_CPU_PART_THUNDERX	0x0A1
 
+#define MIDR_CORTEX_A53 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
+#define MIDR_CORTEX_A57 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
+#define MIDR_THUNDERX   MIDR_CPU_PART(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
+
+#define CPU_MODEL_MASK (MIDR_IMPLEMENTOR_MASK | MIDR_PARTNUM_MASK | \
+                                                MIDR_ARCHITECTURE_MASK)
+
 #ifndef __ASSEMBLY__
 
 /*
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 01248e8..cec63a9 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -21,32 +21,6 @@
 #include <asm/cputype.h>
 #include <asm/cpufeature.h>
 
-#define MIDR_CORTEX_A53 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
-#define MIDR_CORTEX_A57 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
-#define MIDR_THUNDERX	MIDR_CPU_PART(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
-
-#define CPU_MODEL_MASK (MIDR_IMPLEMENTOR_MASK | MIDR_PARTNUM_MASK | \
-			MIDR_ARCHITECTURE_MASK)
-
-static bool __maybe_unused
-is_affected_midr_range(const struct arm64_cpu_capabilities *entry)
-{
-	u32 midr = read_cpuid_id();
-
-	if ((midr & CPU_MODEL_MASK) != entry->midr_model)
-		return false;
-
-	midr &= MIDR_REVISION_MASK | MIDR_VARIANT_MASK;
-
-	return (midr >= entry->midr_range_min && midr <= entry->midr_range_max);
-}
-
-#define MIDR_RANGE(model, min, max) \
-	.matches = is_affected_midr_range, \
-	.midr_model = model, \
-	.midr_range_min = min, \
-	.midr_range_max = max
-
 const struct arm64_cpu_capabilities arm64_errata[] = {
 #if	defined(CONFIG_ARM64_ERRATUM_826319) || \
 	defined(CONFIG_ARM64_ERRATUM_827319) || \
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 0669c63..b0ee60e 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -869,8 +869,27 @@ void verify_local_cpu_capabilities(void)
 
 	caps = arm64_features;
 	for (i = 0; caps[i].desc; i++) {
-		if (!cpus_have_cap(caps[i].capability) || !caps[i].sys_reg)
+		/*
+		 * If the feature is not enable already, then don't try to
+		 * enable.
+		 */
+		if (!cpus_have_cap(caps[i].capability))
+			continue;
+		if (!caps[i].sys_reg)
+			continue;
+		/* Handle MIDR matching seperately. */
+		if (caps[i].sys_reg == SYS_MIDR_EL1) {
+			/*
+			 * If the new CPU is a different MIDR it means the
+			 * feature is missing, we cannot proceed further,
+			 * park the cpu.
+			 */
+			if (!is_affected_midr_range (&caps[i]))
+				fail_incapable_cpu("arm64_features", &caps[i]);
+			if (caps[i].enable)
+				caps[i].enable(NULL);
 			continue;
+		}
 		/*
 		 * If the new CPU misses an advertised feature, we cannot proceed
 		 * further, park the cpu.
-- 
1.7.2.5

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

* [PATCH 2/5] ARM64 Improve copy_page for 128 byte cache line
  2016-01-13  7:08 [PATCHv2 0/4] ARM64: Improve copy_page and copy_template for ThunderX Andrew Pinski
  2016-01-13  7:08 ` [PATCH 1/5] ARM64: Support midr detected cpufeature Andrew Pinski
@ 2016-01-13  7:08 ` Andrew Pinski
  2016-01-13  7:08 ` [PATCH 3/5] ARM64: Add Needs software prefetching cap Andrew Pinski
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Andrew Pinski @ 2016-01-13  7:08 UTC (permalink / raw)
  To: pinskia, linux-kernel, linux-arm-kernel, Will Deacon
  Cc: Andrew Pinski, Will Deacon

For 128 byte cache line, doing 128 bytes unrolled in
the loop is better.
This is adapted from:
https://lkml.org/lkml/2016/1/6/497

Note this removes prefetching as it is harmful for
processors that includes hardware prefetching.
Note the next patch includes patching in software
prefetching for one target.

Signed-off-by: Andrew Pinski <apinski@cavium.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/lib/copy_page.S |   47 ++++++++++++++++++++++++++++++++++++-------
 1 files changed, 39 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/lib/copy_page.S b/arch/arm64/lib/copy_page.S
index 512b9a7..dfb0316 100644
--- a/arch/arm64/lib/copy_page.S
+++ b/arch/arm64/lib/copy_page.S
@@ -19,6 +19,7 @@
 #include <asm/assembler.h>
 #include <asm/page.h>
 
+
 /*
  * Copy a page from src to dest (both are page aligned)
  *
@@ -27,20 +28,50 @@
  *	x1 - src
  */
 ENTRY(copy_page)
-	/* Assume cache line size is 64 bytes. */
-	prfm	pldl1strm, [x1, #64]
-1:	ldp	x2, x3, [x1]
+	ldp	x2, x3, [x1]
+	ldp	x4, x5, [x1, #16]
+	ldp	x6, x7, [x1, #32]
+	ldp	x8, x9, [x1, #48]
+	ldp	x10, x11, [x1, #64]
+	ldp	x12, x13, [x1, #80]
+	ldp	x14, x15, [x1, #96]
+	ldp	x16, x17, [x1, #112]
+
+	mov	x18, #(PAGE_SIZE - 128)
+	add	x1, x1, #128
+1:
+	subs	x18, x18, #128
+
+	stnp	x2, x3, [x0]
+	ldp	x2, x3, [x1]
+	stnp	x4, x5, [x0, #16]
 	ldp	x4, x5, [x1, #16]
+	stnp	x6, x7, [x0, #32]
 	ldp	x6, x7, [x1, #32]
+	stnp	x8, x9, [x0, #48]
 	ldp	x8, x9, [x1, #48]
-	add	x1, x1, #64
-	prfm	pldl1strm, [x1, #64]
+	stnp	x10, x11, [x0, #64]
+	ldp	x10, x11, [x1, #64]
+	stnp	x12, x13, [x0, #80]
+	ldp	x12, x13, [x1, #80]
+	stnp	x14, x15, [x0, #96]
+	ldp	x14, x15, [x1, #96]
+	stnp	x16, x17, [x0, #112]
+	ldp	x16, x17, [x1, #112]
+
+	add	x0, x0, #128
+	add	x1, x1, #128
+
+	b.gt	1b
+
 	stnp	x2, x3, [x0]
 	stnp	x4, x5, [x0, #16]
 	stnp	x6, x7, [x0, #32]
 	stnp	x8, x9, [x0, #48]
-	add	x0, x0, #64
-	tst	x1, #(PAGE_SIZE - 1)
-	b.ne	1b
+	stnp	x10, x11, [x0, #64]
+	stnp	x12, x13, [x0, #80]
+	stnp	x14, x15, [x0, #96]
+	stnp	x16, x17, [x0, #112]
+
 	ret
 ENDPROC(copy_page)
-- 
1.7.2.5

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

* [PATCH 3/5] ARM64: Add Needs software prefetching cap
  2016-01-13  7:08 [PATCHv2 0/4] ARM64: Improve copy_page and copy_template for ThunderX Andrew Pinski
  2016-01-13  7:08 ` [PATCH 1/5] ARM64: Support midr detected cpufeature Andrew Pinski
  2016-01-13  7:08 ` [PATCH 2/5] ARM64 Improve copy_page for 128 byte cache line Andrew Pinski
@ 2016-01-13  7:08 ` Andrew Pinski
  2016-01-13  7:08 ` [PATCH 4/5] ARM64: Patch in prefetching for copy_page is requested Andrew Pinski
  2016-01-13  7:08 ` [PATCH 5/5] ARM64: Patch in prefetching in copy_template Andrew Pinski
  4 siblings, 0 replies; 6+ messages in thread
From: Andrew Pinski @ 2016-01-13  7:08 UTC (permalink / raw)
  To: pinskia, linux-kernel, linux-arm-kernel, Will Deacon; +Cc: Andrew Pinski

On ThunderX T88 pass 1 and pass 2 does not include
a hardware prefetching so the memory copying
functions are slower than necessary.  This adds
a cpu feature for this.
The next patch will add the use in both copy_page
and copy_from_user/copy_to_user.

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/asm/cpufeature.h |    3 ++-
 arch/arm64/kernel/cpufeature.c      |    6 ++++++
 2 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 92aaac6..784bc63 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -32,8 +32,9 @@
 #define ARM64_WORKAROUND_CAVIUM_23154		6
 #define ARM64_WORKAROUND_834220			7
 #define ARM64_WORKAROUND_CAVIUM_27456		8
+#define ARM64_NEEDS_PREFETCH_128		9
 
-#define ARM64_NCAPS				9
+#define ARM64_NCAPS				10
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index b0ee60e..13cda09 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -651,6 +651,12 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.min_field_value = 2,
 	},
 #endif /* CONFIG_AS_LSE && CONFIG_ARM64_LSE_ATOMICS */
+	{
+		.desc = "Needs prefetching (128 byte cache line) for copying: ThunderX T88 pass 1.x and 2.x",
+		.capability = ARM64_NEEDS_PREFETCH_128,
+		MIDR_RANGE(MIDR_THUNDERX, 0,
+			   (1 << MIDR_VARIANT_SHIFT) | MIDR_REVISION_MASK),
+	},
 	{},
 };
 
-- 
1.7.2.5

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

* [PATCH 4/5] ARM64: Patch in prefetching for copy_page is requested
  2016-01-13  7:08 [PATCHv2 0/4] ARM64: Improve copy_page and copy_template for ThunderX Andrew Pinski
                   ` (2 preceding siblings ...)
  2016-01-13  7:08 ` [PATCH 3/5] ARM64: Add Needs software prefetching cap Andrew Pinski
@ 2016-01-13  7:08 ` Andrew Pinski
  2016-01-13  7:08 ` [PATCH 5/5] ARM64: Patch in prefetching in copy_template Andrew Pinski
  4 siblings, 0 replies; 6+ messages in thread
From: Andrew Pinski @ 2016-01-13  7:08 UTC (permalink / raw)
  To: pinskia, linux-kernel, linux-arm-kernel, Will Deacon; +Cc: Andrew Pinski

On ThunderX T88 pass 1 and pass 2, there is no
hardware prefetching so we need to patch in
software prefetching.  Prefetching improves this code
by 60% over the original code and 2x over the code
without prefetching.

Meaured by using the benchmark code at
https://github.com/apinski-cavium/copy_page_benchmark

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/lib/copy_page.S |   17 +++++++++++++++++
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/arch/arm64/lib/copy_page.S b/arch/arm64/lib/copy_page.S
index dfb0316..876e882 100644
--- a/arch/arm64/lib/copy_page.S
+++ b/arch/arm64/lib/copy_page.S
@@ -18,6 +18,8 @@
 #include <linux/const.h>
 #include <asm/assembler.h>
 #include <asm/page.h>
+#include <asm/cpufeature.h>
+#include <asm/alternative.h>
 
 
 /*
@@ -28,6 +30,15 @@
  *	x1 - src
  */
 ENTRY(copy_page)
+alternative_if_not ARM64_NEEDS_PREFETCH_128
+	nop
+	nop
+alternative_else
+	# Prefetch two cache lines ahead.
+	prfm    pldl1strm, [x1, #128]
+	prfm    pldl1strm, [x1, #256]
+alternative_endif
+
 	ldp	x2, x3, [x1]
 	ldp	x4, x5, [x1, #16]
 	ldp	x6, x7, [x1, #32]
@@ -42,6 +53,12 @@ ENTRY(copy_page)
 1:
 	subs	x18, x18, #128
 
+alternative_if_not ARM64_NEEDS_PREFETCH_128
+	nop
+alternative_else
+	prfm    pldl1strm, [x1, #384]
+alternative_endif
+
 	stnp	x2, x3, [x0]
 	ldp	x2, x3, [x1]
 	stnp	x4, x5, [x0, #16]
-- 
1.7.2.5

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

* [PATCH 5/5] ARM64: Patch in prefetching in copy_template
  2016-01-13  7:08 [PATCHv2 0/4] ARM64: Improve copy_page and copy_template for ThunderX Andrew Pinski
                   ` (3 preceding siblings ...)
  2016-01-13  7:08 ` [PATCH 4/5] ARM64: Patch in prefetching for copy_page is requested Andrew Pinski
@ 2016-01-13  7:08 ` Andrew Pinski
  4 siblings, 0 replies; 6+ messages in thread
From: Andrew Pinski @ 2016-01-13  7:08 UTC (permalink / raw)
  To: pinskia, linux-kernel, linux-arm-kernel, Will Deacon; +Cc: Andrew Pinski

For ThunderX T88 pass 1.x and 2.x where there is
no hardware prefetcher, we want to patch in
software prefetching instructions in the copy_template.
This speeds up copy_to_user and copy_from_user for large
size.  The main use of large sizes is I/O read/writes.

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/lib/copy_template.S |   12 ++++++++++++
 arch/arm64/lib/memcpy.S        |    2 ++
 2 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/arch/arm64/lib/copy_template.S b/arch/arm64/lib/copy_template.S
index 410fbdb..3f3f0a4 100644
--- a/arch/arm64/lib/copy_template.S
+++ b/arch/arm64/lib/copy_template.S
@@ -163,12 +163,24 @@ D_h	.req	x14
 	*/
 	.p2align	L1_CACHE_SHIFT
 .Lcpy_body_large:
+alternative_if_not ARM64_NEEDS_PREFETCH_128
+	nop
+	nop
+alternative_else
+	prfm	pldl1strm, [src, #128]
+	prfm	pldl1strm, [src, #256]
+alternative_endif
 	/* pre-get 64 bytes data. */
 	ldp1	A_l, A_h, src, #16
 	ldp1	B_l, B_h, src, #16
 	ldp1	C_l, C_h, src, #16
 	ldp1	D_l, D_h, src, #16
 1:
+alternative_if_not ARM64_NEEDS_PREFETCH_128
+	nop
+alternative_else
+	prfm	pldl1strm, [src, #384]
+alternative_endif
 	/*
 	* interlace the load of next 64 bytes data block with store of the last
 	* loaded 64 bytes data.
diff --git a/arch/arm64/lib/memcpy.S b/arch/arm64/lib/memcpy.S
index 6761393..3a50cf8b 100644
--- a/arch/arm64/lib/memcpy.S
+++ b/arch/arm64/lib/memcpy.S
@@ -25,6 +25,8 @@
 #include <linux/linkage.h>
 #include <asm/assembler.h>
 #include <asm/cache.h>
+#include <asm/alternative.h>
+#include <asm/cpufeature.h>
 
 /*
  * Copy a buffer from src to dest (alignment handled by the hardware)
-- 
1.7.2.5

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

end of thread, other threads:[~2016-01-13  7:09 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-13  7:08 [PATCHv2 0/4] ARM64: Improve copy_page and copy_template for ThunderX Andrew Pinski
2016-01-13  7:08 ` [PATCH 1/5] ARM64: Support midr detected cpufeature Andrew Pinski
2016-01-13  7:08 ` [PATCH 2/5] ARM64 Improve copy_page for 128 byte cache line Andrew Pinski
2016-01-13  7:08 ` [PATCH 3/5] ARM64: Add Needs software prefetching cap Andrew Pinski
2016-01-13  7:08 ` [PATCH 4/5] ARM64: Patch in prefetching for copy_page is requested Andrew Pinski
2016-01-13  7:08 ` [PATCH 5/5] ARM64: Patch in prefetching in copy_template Andrew Pinski

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

Powered by JetHome