Arm64: Query L3 cache info via DT
Subsystems (4)
Hi.
I saw you discussed how to achieve querying cache information and tend to implement the external ones(like L3 cache) via DT a few months ago.
http://lists.infradead.org/pipermail/linux-arm-kernel/2016-February/405399.html
Are these implementations progressing? Forgive me to take the liberty to ask, we care about this thing.
If you've already implemented some codes, we can help with testing (in Hisilicon D02, D03, D05) after you send it to the mail-list.
We can try our best to help if there is any difficulty.
Thanks.
Xiaojun.
Hi Tan,
Quoted 11 lines · Tan Xiaojun
Hi.
I saw you discussed how to achieve querying cache information and tend to implement the external ones(like L3 cache) via DT a few months ago.
http://lists.infradead.org/pipermail/linux-arm-kernel/2016-February/405399.html
Are these implementations progressing? Forgive me to take the
liberty to ask, we care about this thing.
Yes the support to override the cache properties for DT was added in v4.10
However, it still depends on the the sysreg to get the total levels of caches supported in the system. You may need to tweak a bit around that to support what you need.
Quoted 3 lines
If you've already implemented some codes, we can help with testing (in Hisilicon D02, D03, D05) after you send it to the mail-list.
Sure, that would help.
Quoted 1 line
We can try our best to help if there is any difficulty.
OK, you can start trying the patch below :). It's not even compile tested, so you make have to make some changes necessary. I just wanted to put my thoughts here. Make sure all the L3 cacheinfo is present in DT.
Regards,
Sudeep
--
arch/arm64/kernel/cacheinfo.c +12 -1
@@ -84,7 +84,7 @@ static void ci_leaf_init(struct cacheinfo *this_leaf,static int __init_cache_level (unsigned int cpu) { -unsigned int ctype, level, leaves; +unsigned int ctype, level, leaves, of_level;struct cpu_cacheinfo *this_cpu_ci =get_cpu_cacheinfo (cpu);for (level =1 , leaves =0 ; level <=MAX_CACHE_LEVEL ; level++) {
@@ -97,6 +97,17 @@ static int __init_cache_level(unsigned int cpu) leaves += (ctype ==CACHE_TYPE_SEPARATE ) ?2 :1 ; } + of_level =of_count_cache_levels (cpu); +if (level < of_level) { +/* +* some external caches not specified in CLIDR_EL1 +* the information may be available in the device tree +* only unified external caches are considered here +*/ + level = of_level; + leaves += (of_level - level); + } + this_cpu_ci->num_levels = level; this_cpu_ci->num_leaves = leaves;return 0 ;
drivers/of/base.c +0 -0
@@ -2267,6 +2267,20 @@ struct device_node *of_find_next_cache_node(const
struct device_node *np)
return NULL;
}
+int of_count_cache_levels(unsigned int cpu)
+{
+ int level = 0;
+ struct device *cpu_dev = get_cpu_device(cpu);
+ struct device_node *np = cpu_dev->of_node;
+
+ while (np) {
+ level++;
+ np = of_find_next_cache_node(np);
+ }
+
+ return level;
+}
+
/**
* of_graph_parse_endpoint() - parse common endpoint node properties
* @node: pointer to endpoint device_node
include/linux/of.h +0 -0
@@ -280,6 +280,7 @@ extern struct device_node
*of_get_child_by_name(const struct device_node *node,
/* cache lookup */
extern struct device_node *of_find_next_cache_node(const structdevice_node *);
+extern int of_count_cache_levels(unsigned int cpu);
extern struct device_node *of_find_node_with_property(
struct device_node *from, const char *prop_name);
OK. Thank you very much. I will try it in my arm64 board.
Xiaojun.
Quoted 114 lines · Sudeep Holla
Hi Tan,
Quoted 11 lines · Tan Xiaojun
Hi.
I saw you discussed how to achieve querying cache information and tend to implement the external ones(like L3 cache) via DT a few months ago.
http://lists.infradead.org/pipermail/linux-arm-kernel/2016-February/405399.html
Are these implementations progressing? Forgive me to take the
liberty to ask, we care about this thing.Yes the support to override the cache properties for DT was added in v4.10
However, it still depends on the the sysreg to get the total levels of caches supported in the system. You may need to tweak a bit around that to support what you need.
Quoted 3 lines
If you've already implemented some codes, we can help with testing (in Hisilicon D02, D03, D05) after you send it to the mail-list.
Sure, that would help.
Quoted 1 line
We can try our best to help if there is any difficulty.
OK, you can start trying the patch below :). It's not even compile tested, so you make have to make some changes necessary. I just wanted to put my thoughts here. Make sure all the L3 cacheinfo is present in DT.
Regards,
Sudeep--
arch/arm64/kernel/cacheinfo.c +12
-1@@ -84,7 +84,7 @@ static void ci_leaf_init(struct cacheinfo *this_leaf,static int __init_cache_level (unsigned int cpu) { -unsigned int ctype, level, leaves; +unsigned int ctype, level, leaves, of_level;struct cpu_cacheinfo *this_cpu_ci =get_cpu_cacheinfo (cpu);for (level =1 , leaves =0 ; level <=MAX_CACHE_LEVEL ; level++) {@@ -97,6 +97,17 @@ static int __init_cache_level(unsigned int cpu) leaves += (ctype ==CACHE_TYPE_SEPARATE ) ?2 :1 ; } + of_level =of_count_cache_levels (cpu); +if (level < of_level) { +/* +* some external caches not specified in CLIDR_EL1 +* the information may be available in the device tree +* only unified external caches are considered here +*/ + level = of_level; + leaves += (of_level - level); + } + this_cpu_ci->num_levels = level; this_cpu_ci->num_leaves = leaves;return 0 ;drivers/of/base.c +14
-0@@ -2267,6 +2267,20 @@ struct device_node *of_find_next_cache_node(const struct device_node *np)return NULL ; } +int of_count_cache_levels (unsigned int cpu) +{ +int level =0 ; +struct device *cpu_dev =get_cpu_device (cpu); +struct device_node *np = cpu_dev->of_node; + +while (np) { + level++; + np =of_find_next_cache_node (np); + } + +return level; +} +/** * of_graph_parse_endpoint() - parse common endpoint node properties * @node: pointer to endpoint
device_nodeinclude/linux/of.h +1
-0@@ -280,6 +280,7 @@ extern struct device_node *of_get_child_by_name(const struct device_node *node,/* cache lookup */ extern struct device_node *of_find_next_cache_node(const struct device_node *); +extern int of_count_cache_levels(unsigned int cpu); extern struct device_node *of_find_node_with_property(struct
device_node*from, const char*prop_name);.
I add this patch, and test in Hisilicon D02/D03. It can work well.
I'm sorry to reply so late. I took some time to debug, because I am not familiar with the code.
Review
Quoted 8 lines
(quoted diff) +8
-0+ if (level < of_level) { + /* + * some external caches not specified in CLIDR_EL1 + * the information may be available in the device tree + * only unified external caches are considered here + */ + level = of_level; + leaves += (of_level - level);
The above two lines need to exchange the location.
Review
Quoted 1 line
(quoted diff) +1
-0+ }
PS: I will test the other scenes, the next step.
Thanks.
Xiaojun.
----------------------------------------------------------------------------
D02:
root at genericarmv8:~# cat /sys/devices/system/cpu/cpu0/cache/index3/size 16384K
root at genericarmv8:~# cat /sys/devices/system/cpu/cpu0/cache/index3/number_of_sets 4096
root at genericarmv8:~# cat /sys/devices/system/cpu/cpu0/cache/index3/coherency_line_size 64
root at genericarmv8:~# cat /sys/devices/system/cpu/cpu0/cache/index3/level 3
root at genericarmv8:~# cat /sys/devices/system/cpu/cpu0/cache/index3/shared_cpu_list 0-15
root at genericarmv8:~# cat /sys/devices/system/cpu/cpu0/cache/index3/shared_cpu_map ffff
----------------------------------------------------------------------------
D02 (some data may be not accurate):
arch/arm64/boot/dts/hisilicon/hip05.dtsi +12 -0
@@ -215,18 +215,30 @@ cluster0_l2: l2-cache0 { compatible = "cache"; + next-level-cache = <&die0_l3c>; }; cluster1_l2: l2-cache1 { compatible = "cache"; + next-level-cache = <&die0_l3c>; }; cluster2_l2: l2-cache2 { compatible = "cache"; + next-level-cache = <&die0_l3c>; }; cluster3_l2: l2-cache3 { compatible = "cache"; + next-level-cache = <&die0_l3c>; + }; + + die0_l3c: l3-cache { + compatible = "cache"; + cache-size = <16777216>; + cache-line-size = <64>; + cache-block-size = <16>; + cache-sets = <4096>; }; };
Quoted 114 lines · Sudeep Holla
Hi Tan,
Quoted 11 lines · Tan Xiaojun
Hi.
I saw you discussed how to achieve querying cache information and tend to implement the external ones(like L3 cache) via DT a few months ago.
http://lists.infradead.org/pipermail/linux-arm-kernel/2016-February/405399.html
Are these implementations progressing? Forgive me to take the
liberty to ask, we care about this thing.Yes the support to override the cache properties for DT was added in v4.10
However, it still depends on the the sysreg to get the total levels of caches supported in the system. You may need to tweak a bit around that to support what you need.
Quoted 3 lines
If you've already implemented some codes, we can help with testing (in Hisilicon D02, D03, D05) after you send it to the mail-list.
Sure, that would help.
Quoted 1 line
We can try our best to help if there is any difficulty.
OK, you can start trying the patch below :). It's not even compile tested, so you make have to make some changes necessary. I just wanted to put my thoughts here. Make sure all the L3 cacheinfo is present in DT.
Regards,
Sudeep--
arch/arm64/kernel/cacheinfo.c +12
-1@@ -84,7 +84,7 @@ static void ci_leaf_init(struct cacheinfo *this_leaf,static int __init_cache_level (unsigned int cpu) { -unsigned int ctype, level, leaves; +unsigned int ctype, level, leaves, of_level;struct cpu_cacheinfo *this_cpu_ci =get_cpu_cacheinfo (cpu);for (level =1 , leaves =0 ; level <=MAX_CACHE_LEVEL ; level++) {@@ -97,6 +97,17 @@ static int __init_cache_level(unsigned int cpu) leaves += (ctype ==CACHE_TYPE_SEPARATE ) ?2 :1 ; } + of_level =of_count_cache_levels (cpu); +if (level < of_level) { +/* +* some external caches not specified in CLIDR_EL1 +* the information may be available in the device tree +* only unified external caches are considered here +*/ + level = of_level; + leaves += (of_level - level); + } + this_cpu_ci->num_levels = level; this_cpu_ci->num_leaves = leaves;return 0 ;drivers/of/base.c +14
-0@@ -2267,6 +2267,20 @@ struct device_node *of_find_next_cache_node(const struct device_node *np)return NULL ; } +int of_count_cache_levels (unsigned int cpu) +{ +int level =0 ; +struct device *cpu_dev =get_cpu_device (cpu); +struct device_node *np = cpu_dev->of_node; + +while (np) { + level++; + np =of_find_next_cache_node (np); + } + +return level; +} +/** * of_graph_parse_endpoint() - parse common endpoint node properties * @node: pointer to endpoint
device_nodeinclude/linux/of.h +1
-0@@ -280,6 +280,7 @@ extern struct device_node *of_get_child_by_name(const struct device_node *node,/* cache lookup */ extern struct device_node *of_find_next_cache_node(const struct device_node *); +extern int of_count_cache_levels(unsigned int cpu); extern struct device_node *of_find_node_with_property(struct
device_node*from, const char*prop_name);.
Quoted 4 lines · Tan Xiaojun
I add this patch, and test in Hisilicon D02/D03. It can work well.
I'm sorry to reply so late. I took some time to debug, because I am not familiar with the code.
Quoted 11 lines
Review
Quoted 8 lines
(quoted diff) +8
-0+ if (level < of_level) { + /* + * some external caches not specified in CLIDR_EL1 + * the information may be available in the device tree + * only unified external caches are considered here + */ + level = of_level; + leaves += (of_level - level);The above two lines need to exchange the location.
Ah crap, sorry for such a silly mistake.
I will post proper patch(es) soon.
Signature · 2 lines
Regards, Sudeep
Quoted 19 lines · Sudeep Holla
Quoted 4 lines · Tan Xiaojun
I add this patch, and test in Hisilicon D02/D03. It can work well.
I'm sorry to reply so late. I took some time to debug, because I am not familiar with the code.
Quoted 11 lines
Review
Quoted 8 lines
(quoted diff) +8
-0+ if (level < of_level) { + /* + * some external caches not specified in CLIDR_EL1 + * the information may be available in the device tree + * only unified external caches are considered here + */ + level = of_level; + leaves += (of_level - level);The above two lines need to exchange the location.
Quoted 3 lines
Ah crap, sorry for such a silly mistake.
I will post proper patch(es) soon.
OK. Wait for your new patch. ^_^
Thanks.
Xiaojun.
Quoted 20 lines · Tan Xiaojun
Quoted 19 lines · Sudeep Holla
Quoted 15 lines · Tan Xiaojun
I add this patch, and test in Hisilicon D02/D03. It can work well.
I'm sorry to reply so late. I took some time to debug, because I am not familiar with the code.
Review
Quoted 8 lines
(quoted diff) +8
-0+ if (level < of_level) { + /* + * some external caches not specified in CLIDR_EL1 + * the information may be available in the device tree + * only unified external caches are considered here + */ + level = of_level; + leaves += (of_level - level);The above two lines need to exchange the location.
Quoted 6 lines
Quoted 3 lines
Ah crap, sorry for such a silly mistake.
I will post proper patch(es) soon.OK. Wait for your new patch. ^_^
Thanks, I have posted the patches[1] and Cc-ed you on them. It would be good to get Tested-by once you check.
Signature · 5 lines
Regards, Sudeep [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2017-January/478261.html
Quoted 27 lines · Sudeep Holla
Quoted 24 lines · Tan Xiaojun
Quoted 22 lines · Sudeep Holla
Quoted 4 lines · Tan Xiaojun
I add this patch, and test in Hisilicon D02/D03. It can work well.
I'm sorry to reply so late. I took some time to debug, because I am not familiar with the code.
Quoted 11 lines
Review
Quoted 8 lines
(quoted diff) +8
-0+ if (level < of_level) { + /* + * some external caches not specified in CLIDR_EL1 + * the information may be available in the device tree + * only unified external caches are considered here + */ + level = of_level; + leaves += (of_level - level);The above two lines need to exchange the location.
Ah crap, sorry for such a silly mistake.
I will post proper patch(es) soon.
Quoted 6 lines
Quoted 2 lines
OK. Wait for your new patch. ^_^
Thanks, I have posted the patches[1] and Cc-ed you on them. It would be good to get Tested-by once you check.
OK. I'm glad to do this.
Thanks.
Xiaojun.
On 10/01/17 08:50, Tan Xiaojun wrote:
[...]
Quoted 21 lines
arch/arm64/boot/dts/hisilicon/hip05.dtsi +3
-0@@ -215,18 +215,30 @@ cluster0_l2: l2-cache0 { compatible = "cache"; + next-level-cache = <&die0_l3c>; }; cluster1_l2: l2-cache1 { compatible = "cache"; + next-level-cache = <&die0_l3c>; }; cluster2_l2: l2-cache2 { compatible = "cache"; + next-level-cache = <&die0_l3c>; };
arch/arm64/boot/dts/hisilicon/hip05.dtsi line 240
Quoted 10 lines
arch/arm64/boot/dts/hisilicon/hip05.dtsi +8
-0cluster3_l2: l2-cache3 { compatible = "cache"; + next-level-cache = <&die0_l3c>; + }; + + die0_l3c: l3-cache { + compatible = "cache"; + cache-size = <16777216>; + cache-line-size = <64>; + cache-block-size = <16>;
You need to add cache-level = <3> with v2 patch set to work.
Signature · 2 lines
Regards, Sudeep