linux-riscv.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] Get cache information from userland
@ 2020-07-03  8:57 Zong Li
  2020-07-03  8:57 ` [PATCH 1/3] riscv: Set more data to cacheinfo Zong Li
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Zong Li @ 2020-07-03  8:57 UTC (permalink / raw)
  To: palmer, paul.walmsley, linux-riscv, linux-kernel; +Cc: Zong Li

There are no standard CSR registers to provide cache information, the
way for RISC-V is to get this information from DT. Currently, AT_L1I_X,
AT_L1D_X and AT_L2_X are present in glibc header, and sysconf syscall
could use them to get information of cache through AUX vector. We
exploit 'struct cacheinfo' to obtain the information of cache, then we
don't need additional variable or data structure to record it.

We also need some works in glibc, but we have to support the function in
kernel first by rule of glibc, then post the patch to glibc site.

The result of 'getconf -a' as follows:

LEVEL1_ICACHE_SIZE                 32768
LEVEL1_ICACHE_ASSOC                8
LEVEL1_ICACHE_LINESIZE             64
LEVEL1_DCACHE_SIZE                 32768
LEVEL1_DCACHE_ASSOC                8
LEVEL1_DCACHE_LINESIZE             64
LEVEL2_CACHE_SIZE                  2097152
LEVEL2_CACHE_ASSOC                 32
LEVEL2_CACHE_LINESIZE              64

Zong Li (3):
  riscv: Set more data to cacheinfo
  riscv: Define AT_VECTOR_SIZE_ARCH for ARCH_DLINFO
  riscv: Add cache information in AUX vector

 arch/riscv/include/asm/cacheinfo.h   | 14 +++++
 arch/riscv/include/asm/elf.h         | 13 ++++
 arch/riscv/include/uapi/asm/auxvec.h | 24 ++++++++
 arch/riscv/kernel/cacheinfo.c        | 92 +++++++++++++++++++++++-----
 4 files changed, 127 insertions(+), 16 deletions(-)
 create mode 100644 arch/riscv/include/asm/cacheinfo.h

-- 
2.27.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

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

* [PATCH 1/3] riscv: Set more data to cacheinfo
  2020-07-03  8:57 [PATCH 0/3] Get cache information from userland Zong Li
@ 2020-07-03  8:57 ` Zong Li
  2020-08-20 20:44   ` Palmer Dabbelt
  2020-07-03  8:57 ` [PATCH 2/3] riscv: Define AT_VECTOR_SIZE_ARCH for ARCH_DLINFO Zong Li
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Zong Li @ 2020-07-03  8:57 UTC (permalink / raw)
  To: palmer, paul.walmsley, linux-riscv, linux-kernel; +Cc: Zong Li

Set cacheinfo.{size,sets,line_size} for each cache node, then we can
get these information from userland through auxiliary vector.

Signed-off-by: Zong Li <zong.li@sifive.com>
---
 arch/riscv/kernel/cacheinfo.c | 59 ++++++++++++++++++++++++++---------
 1 file changed, 44 insertions(+), 15 deletions(-)

diff --git a/arch/riscv/kernel/cacheinfo.c b/arch/riscv/kernel/cacheinfo.c
index 4c90c07d8c39..cdd35e53fd98 100644
--- a/arch/riscv/kernel/cacheinfo.c
+++ b/arch/riscv/kernel/cacheinfo.c
@@ -8,12 +8,46 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 
-static void ci_leaf_init(struct cacheinfo *this_leaf,
-			 struct device_node *node,
-			 enum cache_type type, unsigned int level)
+static void ci_leaf_init(struct cacheinfo *this_leaf, enum cache_type type,
+			 unsigned int level, unsigned int size,
+			 unsigned int sets, unsigned int line_size)
 {
 	this_leaf->level = level;
 	this_leaf->type = type;
+	this_leaf->size = size;
+	this_leaf->number_of_sets = sets;
+	this_leaf->coherency_line_size = line_size;
+
+	/*
+	 * If the cache is fully associative, there is no need to
+	 * check the other properties.
+	 */
+	if (!(sets == 1) && (sets > 0 && size > 0 && line_size > 0))
+		this_leaf->ways_of_associativity = (size / sets) / line_size;
+}
+
+static void fill_cacheinfo(struct cacheinfo **this_leaf,
+			   struct device_node *node, unsigned int level)
+{
+	unsigned int size, sets, line_size;
+
+	if (!of_property_read_u32(node, "cache-size", &size)) {
+		of_property_read_u32(node, "cache-block-size", &line_size);
+		of_property_read_u32(node, "cache-sets", &sets);
+		ci_leaf_init((*this_leaf)++, CACHE_TYPE_UNIFIED, level, size, sets, line_size);
+	}
+
+	if (!of_property_read_u32(node, "i-cache-size", &size)) {
+		of_property_read_u32(node, "i-cache-sets", &sets);
+		of_property_read_u32(node, "i-cache-block-size", &line_size);
+		ci_leaf_init((*this_leaf)++, CACHE_TYPE_INST, level, size, sets, line_size);
+	}
+
+	if (!of_property_read_u32(node, "d-cache-size", &size)) {
+		of_property_read_u32(node, "d-cache-sets", &sets);
+		of_property_read_u32(node, "d-cache-block-size", &line_size);
+		ci_leaf_init((*this_leaf)++, CACHE_TYPE_DATA, level, size, sets, line_size);
+	}
 }
 
 static int __init_cache_level(unsigned int cpu)
@@ -66,29 +100,24 @@ static int __populate_cache_leaves(unsigned int cpu)
 	struct device_node *prev = NULL;
 	int levels = 1, level = 1;
 
-	if (of_property_read_bool(np, "cache-size"))
-		ci_leaf_init(this_leaf++, np, CACHE_TYPE_UNIFIED, level);
-	if (of_property_read_bool(np, "i-cache-size"))
-		ci_leaf_init(this_leaf++, np, CACHE_TYPE_INST, level);
-	if (of_property_read_bool(np, "d-cache-size"))
-		ci_leaf_init(this_leaf++, np, CACHE_TYPE_DATA, level);
+	/* Level 1 caches in cpu node */
+	fill_cacheinfo(&this_leaf, np, level);
 
+	/* Next level caches in cache nodes */
 	prev = np;
 	while ((np = of_find_next_cache_node(np))) {
 		of_node_put(prev);
 		prev = np;
+
 		if (!of_device_is_compatible(np, "cache"))
 			break;
 		if (of_property_read_u32(np, "cache-level", &level))
 			break;
 		if (level <= levels)
 			break;
-		if (of_property_read_bool(np, "cache-size"))
-			ci_leaf_init(this_leaf++, np, CACHE_TYPE_UNIFIED, level);
-		if (of_property_read_bool(np, "i-cache-size"))
-			ci_leaf_init(this_leaf++, np, CACHE_TYPE_INST, level);
-		if (of_property_read_bool(np, "d-cache-size"))
-			ci_leaf_init(this_leaf++, np, CACHE_TYPE_DATA, level);
+
+		fill_cacheinfo(&this_leaf, np, level);
+
 		levels = level;
 	}
 	of_node_put(np);
-- 
2.27.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

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

* [PATCH 2/3] riscv: Define AT_VECTOR_SIZE_ARCH for ARCH_DLINFO
  2020-07-03  8:57 [PATCH 0/3] Get cache information from userland Zong Li
  2020-07-03  8:57 ` [PATCH 1/3] riscv: Set more data to cacheinfo Zong Li
@ 2020-07-03  8:57 ` Zong Li
  2020-08-20 20:44   ` Palmer Dabbelt
  2020-07-03  8:57 ` [PATCH 3/3] riscv: Add cache information in AUX vector Zong Li
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Zong Li @ 2020-07-03  8:57 UTC (permalink / raw)
  To: palmer, paul.walmsley, linux-riscv, linux-kernel; +Cc: Zong Li

AT_VECTOR_SIZE_ARCH should be defined with the maximum number of
NEW_AUX_ENT entries that ARCH_DLINFO can contain, but it wasn't defined
for RISC-V at all even though ARCH_DLINFO will contain one NEW_AUX_ENT
for the VDSO address.

Signed-off-by: Zong Li <zong.li@sifive.com>
---
 arch/riscv/include/uapi/asm/auxvec.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/riscv/include/uapi/asm/auxvec.h b/arch/riscv/include/uapi/asm/auxvec.h
index d86cb17bbabe..22e0ae888406 100644
--- a/arch/riscv/include/uapi/asm/auxvec.h
+++ b/arch/riscv/include/uapi/asm/auxvec.h
@@ -10,4 +10,7 @@
 /* vDSO location */
 #define AT_SYSINFO_EHDR 33
 
+/* entries in ARCH_DLINFO */
+#define AT_VECTOR_SIZE_ARCH	1
+
 #endif /* _UAPI_ASM_RISCV_AUXVEC_H */
-- 
2.27.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

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

* [PATCH 3/3] riscv: Add cache information in AUX vector
  2020-07-03  8:57 [PATCH 0/3] Get cache information from userland Zong Li
  2020-07-03  8:57 ` [PATCH 1/3] riscv: Set more data to cacheinfo Zong Li
  2020-07-03  8:57 ` [PATCH 2/3] riscv: Define AT_VECTOR_SIZE_ARCH for ARCH_DLINFO Zong Li
@ 2020-07-03  8:57 ` Zong Li
  2020-08-20 20:44   ` Palmer Dabbelt
  2020-07-27  3:03 ` [PATCH 0/3] Get cache information from userland Zong Li
  2020-08-20 20:45 ` Palmer Dabbelt
  4 siblings, 1 reply; 10+ messages in thread
From: Zong Li @ 2020-07-03  8:57 UTC (permalink / raw)
  To: palmer, paul.walmsley, linux-riscv, linux-kernel; +Cc: Zong Li

There are no standard CSR registers to provide cache information, the
way for RISC-V is to get this information from DT. Currently, AT_L1I_X,
AT_L1D_X and AT_L2_X are present in glibc header, and sysconf syscall
could use them to get information of cache through AUX vector.

The result of 'getconf -a' as follows:
LEVEL1_ICACHE_SIZE                 32768
LEVEL1_ICACHE_ASSOC                8
LEVEL1_ICACHE_LINESIZE             64
LEVEL1_DCACHE_SIZE                 32768
LEVEL1_DCACHE_ASSOC                8
LEVEL1_DCACHE_LINESIZE             64
LEVEL2_CACHE_SIZE                  2097152
LEVEL2_CACHE_ASSOC                 32
LEVEL2_CACHE_LINESIZE              64

Signed-off-by: Zong Li <zong.li@sifive.com>
---
 arch/riscv/include/asm/cacheinfo.h   | 14 ++++++++++++
 arch/riscv/include/asm/elf.h         | 13 +++++++++++
 arch/riscv/include/uapi/asm/auxvec.h | 23 ++++++++++++++++++-
 arch/riscv/kernel/cacheinfo.c        | 33 +++++++++++++++++++++++++++-
 4 files changed, 81 insertions(+), 2 deletions(-)
 create mode 100644 arch/riscv/include/asm/cacheinfo.h

diff --git a/arch/riscv/include/asm/cacheinfo.h b/arch/riscv/include/asm/cacheinfo.h
new file mode 100644
index 000000000000..ba179cd198b9
--- /dev/null
+++ b/arch/riscv/include/asm/cacheinfo.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2020 SiFive
+ */
+
+#ifndef _ASM_RISCV_CACHEINFO_H
+#define _ASM_RISCV_CACHEINFO_H
+
+#include <linux/cacheinfo.h>
+
+uintptr_t get_cache_size(u32 level, enum cache_type type);
+uintptr_t get_cache_geometry(u32 level, enum cache_type type);
+
+#endif /* _ASM_RISCV_CACHEINFO_H */
diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
index d83a4efd052b..5c725e1df58b 100644
--- a/arch/riscv/include/asm/elf.h
+++ b/arch/riscv/include/asm/elf.h
@@ -11,6 +11,7 @@
 #include <uapi/asm/elf.h>
 #include <asm/auxvec.h>
 #include <asm/byteorder.h>
+#include <asm/cacheinfo.h>
 
 /*
  * These are used to set parameters in the core dumps.
@@ -61,6 +62,18 @@ extern unsigned long elf_hwcap;
 do {								\
 	NEW_AUX_ENT(AT_SYSINFO_EHDR,				\
 		(elf_addr_t)current->mm->context.vdso);		\
+	NEW_AUX_ENT(AT_L1I_CACHESIZE,				\
+		get_cache_size(1, CACHE_TYPE_INST));		\
+	NEW_AUX_ENT(AT_L1I_CACHEGEOMETRY,			\
+		get_cache_geometry(1, CACHE_TYPE_INST));	\
+	NEW_AUX_ENT(AT_L1D_CACHESIZE,				\
+		get_cache_size(1, CACHE_TYPE_DATA));		\
+	NEW_AUX_ENT(AT_L1D_CACHEGEOMETRY,			\
+		get_cache_geometry(1, CACHE_TYPE_DATA));	\
+	NEW_AUX_ENT(AT_L2_CACHESIZE,				\
+		get_cache_size(2, CACHE_TYPE_UNIFIED));		\
+	NEW_AUX_ENT(AT_L2_CACHEGEOMETRY,			\
+		get_cache_geometry(2, CACHE_TYPE_UNIFIED));	\
 } while (0)
 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES
 struct linux_binprm;
diff --git a/arch/riscv/include/uapi/asm/auxvec.h b/arch/riscv/include/uapi/asm/auxvec.h
index 22e0ae888406..32c73ba1d531 100644
--- a/arch/riscv/include/uapi/asm/auxvec.h
+++ b/arch/riscv/include/uapi/asm/auxvec.h
@@ -10,7 +10,28 @@
 /* vDSO location */
 #define AT_SYSINFO_EHDR 33
 
+/*
+ * The set of entries below represent more extensive information
+ * about the caches, in the form of two entry per cache type,
+ * one entry containing the cache size in bytes, and the other
+ * containing the cache line size in bytes in the bottom 16 bits
+ * and the cache associativity in the next 16 bits.
+ *
+ * The associativity is such that if N is the 16-bit value, the
+ * cache is N way set associative. A value if 0xffff means fully
+ * associative, a value of 1 means directly mapped.
+ *
+ * For all these fields, a value of 0 means that the information
+ * is not known.
+ */
+#define AT_L1I_CACHESIZE	40
+#define AT_L1I_CACHEGEOMETRY	41
+#define AT_L1D_CACHESIZE	42
+#define AT_L1D_CACHEGEOMETRY	43
+#define AT_L2_CACHESIZE		44
+#define AT_L2_CACHEGEOMETRY	45
+
 /* entries in ARCH_DLINFO */
-#define AT_VECTOR_SIZE_ARCH	1
+#define AT_VECTOR_SIZE_ARCH	7
 
 #endif /* _UAPI_ASM_RISCV_AUXVEC_H */
diff --git a/arch/riscv/kernel/cacheinfo.c b/arch/riscv/kernel/cacheinfo.c
index cdd35e53fd98..263335def44b 100644
--- a/arch/riscv/kernel/cacheinfo.c
+++ b/arch/riscv/kernel/cacheinfo.c
@@ -3,10 +3,41 @@
  * Copyright (C) 2017 SiFive
  */
 
-#include <linux/cacheinfo.h>
 #include <linux/cpu.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <asm/cacheinfo.h>
+
+static struct cacheinfo *get_cacheinfo(u32 level, enum cache_type type)
+{
+	struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(smp_processor_id());
+	struct cacheinfo *this_leaf;
+	int index;
+
+	for (index = 0; index < this_cpu_ci->num_leaves; index++) {
+		this_leaf = this_cpu_ci->info_list + index;
+		if (this_leaf->level == level && this_leaf->type == type)
+			return this_leaf;
+	}
+
+	return 0;
+}
+
+uintptr_t get_cache_size(u32 level, enum cache_type type)
+{
+	struct cacheinfo *this_leaf = get_cacheinfo(level, type);
+
+	return this_leaf ? this_leaf->size : 0;
+}
+
+uintptr_t get_cache_geometry(u32 level, enum cache_type type)
+{
+	struct cacheinfo *this_leaf = get_cacheinfo(level, type);
+	uintptr_t ret = (this_leaf->ways_of_associativity << 16 |
+			 this_leaf->coherency_line_size);
+
+	return this_leaf ? ret : 0;
+}
 
 static void ci_leaf_init(struct cacheinfo *this_leaf, enum cache_type type,
 			 unsigned int level, unsigned int size,
-- 
2.27.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

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

* Re: [PATCH 0/3] Get cache information from userland
  2020-07-03  8:57 [PATCH 0/3] Get cache information from userland Zong Li
                   ` (2 preceding siblings ...)
  2020-07-03  8:57 ` [PATCH 3/3] riscv: Add cache information in AUX vector Zong Li
@ 2020-07-27  3:03 ` Zong Li
  2020-08-20 20:45 ` Palmer Dabbelt
  4 siblings, 0 replies; 10+ messages in thread
From: Zong Li @ 2020-07-27  3:03 UTC (permalink / raw)
  To: Palmer Dabbelt, Paul Walmsley, linux-riscv,
	linux-kernel@vger.kernel.org List

On Fri, Jul 3, 2020 at 4:57 PM Zong Li <zong.li@sifive.com> wrote:
>
> There are no standard CSR registers to provide cache information, the
> way for RISC-V is to get this information from DT. Currently, AT_L1I_X,
> AT_L1D_X and AT_L2_X are present in glibc header, and sysconf syscall
> could use them to get information of cache through AUX vector. We
> exploit 'struct cacheinfo' to obtain the information of cache, then we
> don't need additional variable or data structure to record it.
>
> We also need some works in glibc, but we have to support the function in
> kernel first by rule of glibc, then post the patch to glibc site.
>
> The result of 'getconf -a' as follows:
>
> LEVEL1_ICACHE_SIZE                 32768
> LEVEL1_ICACHE_ASSOC                8
> LEVEL1_ICACHE_LINESIZE             64
> LEVEL1_DCACHE_SIZE                 32768
> LEVEL1_DCACHE_ASSOC                8
> LEVEL1_DCACHE_LINESIZE             64
> LEVEL2_CACHE_SIZE                  2097152
> LEVEL2_CACHE_ASSOC                 32
> LEVEL2_CACHE_LINESIZE              64
>
> Zong Li (3):
>   riscv: Set more data to cacheinfo
>   riscv: Define AT_VECTOR_SIZE_ARCH for ARCH_DLINFO
>   riscv: Add cache information in AUX vector
>
>  arch/riscv/include/asm/cacheinfo.h   | 14 +++++
>  arch/riscv/include/asm/elf.h         | 13 ++++
>  arch/riscv/include/uapi/asm/auxvec.h | 24 ++++++++
>  arch/riscv/kernel/cacheinfo.c        | 92 +++++++++++++++++++++++-----
>  4 files changed, 127 insertions(+), 16 deletions(-)
>  create mode 100644 arch/riscv/include/asm/cacheinfo.h
>
> --
> 2.27.0
>

ping

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

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

* Re: [PATCH 1/3] riscv: Set more data to cacheinfo
  2020-07-03  8:57 ` [PATCH 1/3] riscv: Set more data to cacheinfo Zong Li
@ 2020-08-20 20:44   ` Palmer Dabbelt
  0 siblings, 0 replies; 10+ messages in thread
From: Palmer Dabbelt @ 2020-08-20 20:44 UTC (permalink / raw)
  To: zong.li; +Cc: linux-riscv, linux-kernel, zong.li, Paul Walmsley

On Fri, 03 Jul 2020 01:57:53 PDT (-0700), zong.li@sifive.com wrote:
> Set cacheinfo.{size,sets,line_size} for each cache node, then we can
> get these information from userland through auxiliary vector.
>
> Signed-off-by: Zong Li <zong.li@sifive.com>
> ---
>  arch/riscv/kernel/cacheinfo.c | 59 ++++++++++++++++++++++++++---------
>  1 file changed, 44 insertions(+), 15 deletions(-)
>
> diff --git a/arch/riscv/kernel/cacheinfo.c b/arch/riscv/kernel/cacheinfo.c
> index 4c90c07d8c39..cdd35e53fd98 100644
> --- a/arch/riscv/kernel/cacheinfo.c
> +++ b/arch/riscv/kernel/cacheinfo.c
> @@ -8,12 +8,46 @@
>  #include <linux/of.h>
>  #include <linux/of_device.h>
>
> -static void ci_leaf_init(struct cacheinfo *this_leaf,
> -			 struct device_node *node,
> -			 enum cache_type type, unsigned int level)
> +static void ci_leaf_init(struct cacheinfo *this_leaf, enum cache_type type,
> +			 unsigned int level, unsigned int size,
> +			 unsigned int sets, unsigned int line_size)
>  {
>  	this_leaf->level = level;
>  	this_leaf->type = type;
> +	this_leaf->size = size;
> +	this_leaf->number_of_sets = sets;
> +	this_leaf->coherency_line_size = line_size;
> +
> +	/*
> +	 * If the cache is fully associative, there is no need to
> +	 * check the other properties.
> +	 */
> +	if (!(sets == 1) && (sets > 0 && size > 0 && line_size > 0))
> +		this_leaf->ways_of_associativity = (size / sets) / line_size;
> +}
> +
> +static void fill_cacheinfo(struct cacheinfo **this_leaf,
> +			   struct device_node *node, unsigned int level)
> +{
> +	unsigned int size, sets, line_size;
> +
> +	if (!of_property_read_u32(node, "cache-size", &size)) {
> +		of_property_read_u32(node, "cache-block-size", &line_size);
> +		of_property_read_u32(node, "cache-sets", &sets);

Presumably we should be checking for errors here as well, rather than just
passing arbitrary values to userspace?

> +		ci_leaf_init((*this_leaf)++, CACHE_TYPE_UNIFIED, level, size, sets, line_size);
> +	}
> +
> +	if (!of_property_read_u32(node, "i-cache-size", &size)) {
> +		of_property_read_u32(node, "i-cache-sets", &sets);
> +		of_property_read_u32(node, "i-cache-block-size", &line_size);
> +		ci_leaf_init((*this_leaf)++, CACHE_TYPE_INST, level, size, sets, line_size);
> +	}
> +
> +	if (!of_property_read_u32(node, "d-cache-size", &size)) {
> +		of_property_read_u32(node, "d-cache-sets", &sets);
> +		of_property_read_u32(node, "d-cache-block-size", &line_size);
> +		ci_leaf_init((*this_leaf)++, CACHE_TYPE_DATA, level, size, sets, line_size);
> +	}
>  }
>
>  static int __init_cache_level(unsigned int cpu)
> @@ -66,29 +100,24 @@ static int __populate_cache_leaves(unsigned int cpu)
>  	struct device_node *prev = NULL;
>  	int levels = 1, level = 1;
>
> -	if (of_property_read_bool(np, "cache-size"))
> -		ci_leaf_init(this_leaf++, np, CACHE_TYPE_UNIFIED, level);
> -	if (of_property_read_bool(np, "i-cache-size"))
> -		ci_leaf_init(this_leaf++, np, CACHE_TYPE_INST, level);
> -	if (of_property_read_bool(np, "d-cache-size"))
> -		ci_leaf_init(this_leaf++, np, CACHE_TYPE_DATA, level);
> +	/* Level 1 caches in cpu node */
> +	fill_cacheinfo(&this_leaf, np, level);
>
> +	/* Next level caches in cache nodes */
>  	prev = np;
>  	while ((np = of_find_next_cache_node(np))) {
>  		of_node_put(prev);
>  		prev = np;
> +
>  		if (!of_device_is_compatible(np, "cache"))
>  			break;
>  		if (of_property_read_u32(np, "cache-level", &level))
>  			break;
>  		if (level <= levels)
>  			break;
> -		if (of_property_read_bool(np, "cache-size"))
> -			ci_leaf_init(this_leaf++, np, CACHE_TYPE_UNIFIED, level);
> -		if (of_property_read_bool(np, "i-cache-size"))
> -			ci_leaf_init(this_leaf++, np, CACHE_TYPE_INST, level);
> -		if (of_property_read_bool(np, "d-cache-size"))
> -			ci_leaf_init(this_leaf++, np, CACHE_TYPE_DATA, level);
> +
> +		fill_cacheinfo(&this_leaf, np, level);
> +
>  		levels = level;
>  	}
>  	of_node_put(np);

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

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

* Re: [PATCH 2/3] riscv: Define AT_VECTOR_SIZE_ARCH for ARCH_DLINFO
  2020-07-03  8:57 ` [PATCH 2/3] riscv: Define AT_VECTOR_SIZE_ARCH for ARCH_DLINFO Zong Li
@ 2020-08-20 20:44   ` Palmer Dabbelt
  0 siblings, 0 replies; 10+ messages in thread
From: Palmer Dabbelt @ 2020-08-20 20:44 UTC (permalink / raw)
  To: zong.li; +Cc: linux-riscv, linux-kernel, zong.li, Paul Walmsley

On Fri, 03 Jul 2020 01:57:54 PDT (-0700), zong.li@sifive.com wrote:
> AT_VECTOR_SIZE_ARCH should be defined with the maximum number of
> NEW_AUX_ENT entries that ARCH_DLINFO can contain, but it wasn't defined
> for RISC-V at all even though ARCH_DLINFO will contain one NEW_AUX_ENT
> for the VDSO address.
>
> Signed-off-by: Zong Li <zong.li@sifive.com>
> ---
>  arch/riscv/include/uapi/asm/auxvec.h | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/arch/riscv/include/uapi/asm/auxvec.h b/arch/riscv/include/uapi/asm/auxvec.h
> index d86cb17bbabe..22e0ae888406 100644
> --- a/arch/riscv/include/uapi/asm/auxvec.h
> +++ b/arch/riscv/include/uapi/asm/auxvec.h
> @@ -10,4 +10,7 @@
>  /* vDSO location */
>  #define AT_SYSINFO_EHDR 33
>
> +/* entries in ARCH_DLINFO */
> +#define AT_VECTOR_SIZE_ARCH	1
> +
>  #endif /* _UAPI_ASM_RISCV_AUXVEC_H */

Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

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

* Re: [PATCH 3/3] riscv: Add cache information in AUX vector
  2020-07-03  8:57 ` [PATCH 3/3] riscv: Add cache information in AUX vector Zong Li
@ 2020-08-20 20:44   ` Palmer Dabbelt
  0 siblings, 0 replies; 10+ messages in thread
From: Palmer Dabbelt @ 2020-08-20 20:44 UTC (permalink / raw)
  To: zong.li; +Cc: linux-riscv, linux-kernel, zong.li, Paul Walmsley

On Fri, 03 Jul 2020 01:57:55 PDT (-0700), zong.li@sifive.com wrote:
> There are no standard CSR registers to provide cache information, the
> way for RISC-V is to get this information from DT. Currently, AT_L1I_X,
> AT_L1D_X and AT_L2_X are present in glibc header, and sysconf syscall
> could use them to get information of cache through AUX vector.
>
> The result of 'getconf -a' as follows:
> LEVEL1_ICACHE_SIZE                 32768
> LEVEL1_ICACHE_ASSOC                8
> LEVEL1_ICACHE_LINESIZE             64
> LEVEL1_DCACHE_SIZE                 32768
> LEVEL1_DCACHE_ASSOC                8
> LEVEL1_DCACHE_LINESIZE             64
> LEVEL2_CACHE_SIZE                  2097152
> LEVEL2_CACHE_ASSOC                 32
> LEVEL2_CACHE_LINESIZE              64
>
> Signed-off-by: Zong Li <zong.li@sifive.com>
> ---
>  arch/riscv/include/asm/cacheinfo.h   | 14 ++++++++++++
>  arch/riscv/include/asm/elf.h         | 13 +++++++++++
>  arch/riscv/include/uapi/asm/auxvec.h | 23 ++++++++++++++++++-
>  arch/riscv/kernel/cacheinfo.c        | 33 +++++++++++++++++++++++++++-
>  4 files changed, 81 insertions(+), 2 deletions(-)
>  create mode 100644 arch/riscv/include/asm/cacheinfo.h
>
> diff --git a/arch/riscv/include/asm/cacheinfo.h b/arch/riscv/include/asm/cacheinfo.h
> new file mode 100644
> index 000000000000..ba179cd198b9
> --- /dev/null
> +++ b/arch/riscv/include/asm/cacheinfo.h
> @@ -0,0 +1,14 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (C) 2020 SiFive
> + */
> +
> +#ifndef _ASM_RISCV_CACHEINFO_H
> +#define _ASM_RISCV_CACHEINFO_H
> +
> +#include <linux/cacheinfo.h>
> +
> +uintptr_t get_cache_size(u32 level, enum cache_type type);
> +uintptr_t get_cache_geometry(u32 level, enum cache_type type);
> +
> +#endif /* _ASM_RISCV_CACHEINFO_H */
> diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
> index d83a4efd052b..5c725e1df58b 100644
> --- a/arch/riscv/include/asm/elf.h
> +++ b/arch/riscv/include/asm/elf.h
> @@ -11,6 +11,7 @@
>  #include <uapi/asm/elf.h>
>  #include <asm/auxvec.h>
>  #include <asm/byteorder.h>
> +#include <asm/cacheinfo.h>
>
>  /*
>   * These are used to set parameters in the core dumps.
> @@ -61,6 +62,18 @@ extern unsigned long elf_hwcap;
>  do {								\
>  	NEW_AUX_ENT(AT_SYSINFO_EHDR,				\
>  		(elf_addr_t)current->mm->context.vdso);		\
> +	NEW_AUX_ENT(AT_L1I_CACHESIZE,				\
> +		get_cache_size(1, CACHE_TYPE_INST));		\
> +	NEW_AUX_ENT(AT_L1I_CACHEGEOMETRY,			\
> +		get_cache_geometry(1, CACHE_TYPE_INST));	\
> +	NEW_AUX_ENT(AT_L1D_CACHESIZE,				\
> +		get_cache_size(1, CACHE_TYPE_DATA));		\
> +	NEW_AUX_ENT(AT_L1D_CACHEGEOMETRY,			\
> +		get_cache_geometry(1, CACHE_TYPE_DATA));	\
> +	NEW_AUX_ENT(AT_L2_CACHESIZE,				\
> +		get_cache_size(2, CACHE_TYPE_UNIFIED));		\
> +	NEW_AUX_ENT(AT_L2_CACHEGEOMETRY,			\
> +		get_cache_geometry(2, CACHE_TYPE_UNIFIED));	\
>  } while (0)
>  #define ARCH_HAS_SETUP_ADDITIONAL_PAGES
>  struct linux_binprm;
> diff --git a/arch/riscv/include/uapi/asm/auxvec.h b/arch/riscv/include/uapi/asm/auxvec.h
> index 22e0ae888406..32c73ba1d531 100644
> --- a/arch/riscv/include/uapi/asm/auxvec.h
> +++ b/arch/riscv/include/uapi/asm/auxvec.h
> @@ -10,7 +10,28 @@
>  /* vDSO location */
>  #define AT_SYSINFO_EHDR 33
>
> +/*
> + * The set of entries below represent more extensive information
> + * about the caches, in the form of two entry per cache type,
> + * one entry containing the cache size in bytes, and the other
> + * containing the cache line size in bytes in the bottom 16 bits
> + * and the cache associativity in the next 16 bits.
> + *
> + * The associativity is such that if N is the 16-bit value, the
> + * cache is N way set associative. A value if 0xffff means fully
> + * associative, a value of 1 means directly mapped.
> + *
> + * For all these fields, a value of 0 means that the information
> + * is not known.
> + */
> +#define AT_L1I_CACHESIZE	40
> +#define AT_L1I_CACHEGEOMETRY	41
> +#define AT_L1D_CACHESIZE	42
> +#define AT_L1D_CACHEGEOMETRY	43
> +#define AT_L2_CACHESIZE		44
> +#define AT_L2_CACHEGEOMETRY	45
> +
>  /* entries in ARCH_DLINFO */
> -#define AT_VECTOR_SIZE_ARCH	1
> +#define AT_VECTOR_SIZE_ARCH	7
>
>  #endif /* _UAPI_ASM_RISCV_AUXVEC_H */
> diff --git a/arch/riscv/kernel/cacheinfo.c b/arch/riscv/kernel/cacheinfo.c
> index cdd35e53fd98..263335def44b 100644
> --- a/arch/riscv/kernel/cacheinfo.c
> +++ b/arch/riscv/kernel/cacheinfo.c
> @@ -3,10 +3,41 @@
>   * Copyright (C) 2017 SiFive
>   */
>
> -#include <linux/cacheinfo.h>
>  #include <linux/cpu.h>
>  #include <linux/of.h>
>  #include <linux/of_device.h>
> +#include <asm/cacheinfo.h>
> +
> +static struct cacheinfo *get_cacheinfo(u32 level, enum cache_type type)
> +{
> +	struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(smp_processor_id());
> +	struct cacheinfo *this_leaf;
> +	int index;
> +
> +	for (index = 0; index < this_cpu_ci->num_leaves; index++) {
> +		this_leaf = this_cpu_ci->info_list + index;
> +		if (this_leaf->level == level && this_leaf->type == type)
> +			return this_leaf;
> +	}
> +
> +	return 0;
> +}
> +
> +uintptr_t get_cache_size(u32 level, enum cache_type type)
> +{
> +	struct cacheinfo *this_leaf = get_cacheinfo(level, type);
> +
> +	return this_leaf ? this_leaf->size : 0;
> +}
> +
> +uintptr_t get_cache_geometry(u32 level, enum cache_type type)
> +{
> +	struct cacheinfo *this_leaf = get_cacheinfo(level, type);
> +	uintptr_t ret = (this_leaf->ways_of_associativity << 16 |
> +			 this_leaf->coherency_line_size);
> +
> +	return this_leaf ? ret : 0;
> +}
>
>  static void ci_leaf_init(struct cacheinfo *this_leaf, enum cache_type type,
>  			 unsigned int level, unsigned int size,

Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

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

* Re: [PATCH 0/3] Get cache information from userland
  2020-07-03  8:57 [PATCH 0/3] Get cache information from userland Zong Li
                   ` (3 preceding siblings ...)
  2020-07-27  3:03 ` [PATCH 0/3] Get cache information from userland Zong Li
@ 2020-08-20 20:45 ` Palmer Dabbelt
  2020-08-27  8:22   ` Zong Li
  4 siblings, 1 reply; 10+ messages in thread
From: Palmer Dabbelt @ 2020-08-20 20:45 UTC (permalink / raw)
  To: zong.li; +Cc: linux-riscv, linux-kernel, zong.li, Paul Walmsley

On Fri, 03 Jul 2020 01:57:52 PDT (-0700), zong.li@sifive.com wrote:
> There are no standard CSR registers to provide cache information, the
> way for RISC-V is to get this information from DT. Currently, AT_L1I_X,
> AT_L1D_X and AT_L2_X are present in glibc header, and sysconf syscall
> could use them to get information of cache through AUX vector. We
> exploit 'struct cacheinfo' to obtain the information of cache, then we
> don't need additional variable or data structure to record it.
>
> We also need some works in glibc, but we have to support the function in
> kernel first by rule of glibc, then post the patch to glibc site.
>
> The result of 'getconf -a' as follows:
>
> LEVEL1_ICACHE_SIZE                 32768
> LEVEL1_ICACHE_ASSOC                8
> LEVEL1_ICACHE_LINESIZE             64
> LEVEL1_DCACHE_SIZE                 32768
> LEVEL1_DCACHE_ASSOC                8
> LEVEL1_DCACHE_LINESIZE             64
> LEVEL2_CACHE_SIZE                  2097152
> LEVEL2_CACHE_ASSOC                 32
> LEVEL2_CACHE_LINESIZE              64
>
> Zong Li (3):
>   riscv: Set more data to cacheinfo
>   riscv: Define AT_VECTOR_SIZE_ARCH for ARCH_DLINFO
>   riscv: Add cache information in AUX vector
>
>  arch/riscv/include/asm/cacheinfo.h   | 14 +++++
>  arch/riscv/include/asm/elf.h         | 13 ++++
>  arch/riscv/include/uapi/asm/auxvec.h | 24 ++++++++
>  arch/riscv/kernel/cacheinfo.c        | 92 +++++++++++++++++++++++-----
>  4 files changed, 127 insertions(+), 16 deletions(-)
>  create mode 100644 arch/riscv/include/asm/cacheinfo.h

Sorry, I lost track of these.  There's a little issue in #1, LMK if you want to
send another version or if you want me to just fix it.

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

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

* Re: [PATCH 0/3] Get cache information from userland
  2020-08-20 20:45 ` Palmer Dabbelt
@ 2020-08-27  8:22   ` Zong Li
  0 siblings, 0 replies; 10+ messages in thread
From: Zong Li @ 2020-08-27  8:22 UTC (permalink / raw)
  To: Palmer Dabbelt
  Cc: linux-riscv, linux-kernel@vger.kernel.org List, Paul Walmsley

On Fri, Aug 21, 2020 at 4:45 AM Palmer Dabbelt <palmer@dabbelt.com> wrote:
>
> On Fri, 03 Jul 2020 01:57:52 PDT (-0700), zong.li@sifive.com wrote:
> > There are no standard CSR registers to provide cache information, the
> > way for RISC-V is to get this information from DT. Currently, AT_L1I_X,
> > AT_L1D_X and AT_L2_X are present in glibc header, and sysconf syscall
> > could use them to get information of cache through AUX vector. We
> > exploit 'struct cacheinfo' to obtain the information of cache, then we
> > don't need additional variable or data structure to record it.
> >
> > We also need some works in glibc, but we have to support the function in
> > kernel first by rule of glibc, then post the patch to glibc site.
> >
> > The result of 'getconf -a' as follows:
> >
> > LEVEL1_ICACHE_SIZE                 32768
> > LEVEL1_ICACHE_ASSOC                8
> > LEVEL1_ICACHE_LINESIZE             64
> > LEVEL1_DCACHE_SIZE                 32768
> > LEVEL1_DCACHE_ASSOC                8
> > LEVEL1_DCACHE_LINESIZE             64
> > LEVEL2_CACHE_SIZE                  2097152
> > LEVEL2_CACHE_ASSOC                 32
> > LEVEL2_CACHE_LINESIZE              64
> >
> > Zong Li (3):
> >   riscv: Set more data to cacheinfo
> >   riscv: Define AT_VECTOR_SIZE_ARCH for ARCH_DLINFO
> >   riscv: Add cache information in AUX vector
> >
> >  arch/riscv/include/asm/cacheinfo.h   | 14 +++++
> >  arch/riscv/include/asm/elf.h         | 13 ++++
> >  arch/riscv/include/uapi/asm/auxvec.h | 24 ++++++++
> >  arch/riscv/kernel/cacheinfo.c        | 92 +++++++++++++++++++++++-----
> >  4 files changed, 127 insertions(+), 16 deletions(-)
> >  create mode 100644 arch/riscv/include/asm/cacheinfo.h
>
> Sorry, I lost track of these.  There's a little issue in #1, LMK if you want to
> send another version or if you want me to just fix it.

Sorry for being late here, I have sent the second version patches to
fix it, thanks for your reviewing.

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

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

end of thread, other threads:[~2020-08-27  8:23 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-03  8:57 [PATCH 0/3] Get cache information from userland Zong Li
2020-07-03  8:57 ` [PATCH 1/3] riscv: Set more data to cacheinfo Zong Li
2020-08-20 20:44   ` Palmer Dabbelt
2020-07-03  8:57 ` [PATCH 2/3] riscv: Define AT_VECTOR_SIZE_ARCH for ARCH_DLINFO Zong Li
2020-08-20 20:44   ` Palmer Dabbelt
2020-07-03  8:57 ` [PATCH 3/3] riscv: Add cache information in AUX vector Zong Li
2020-08-20 20:44   ` Palmer Dabbelt
2020-07-27  3:03 ` [PATCH 0/3] Get cache information from userland Zong Li
2020-08-20 20:45 ` Palmer Dabbelt
2020-08-27  8:22   ` Zong Li

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