提交 3b876a78 编写于 作者: K Kai Shen 提交者: Zheng Zengkai

arm64: errata: add option to disable cache readunique prefetch on HIP08

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I3ZFV2
CVE: NA

-----------------------------------------------------------

Random performance decreases appear on cases of Hackbench which test
pipe or socket communication among multi-threads on Hisi HIP08 SoC.
Cache sharing which caused by the change of the data layout and the
cache readunique prefetch mechanism both lead to this problem.

Readunique mechanism which may caused by store operation will invalid
cachelines on other cores during data fetching stage which can cause
cacheline invalidation happens frequently in a sharing data access
situation.

Disable cache readunique prefetch can trackle this problem.
Test cases are like:
    for i in 20;do
        echo "--------pipe thread num=$i----------"
        for j in $(seq 1 10);do
            ./hackbench -pipe $i thread 1000
        done
    done

We disable readunique prefetch only in el2 for in el1 disabling
readunique prefetch may cause panic due to lack of related priority
which often be set in BIOS.

Introduce CONFIG_HISILICON_ERRATUM_HIP08_RU_PREFETCH and disable RU
prefetch using boot cmdline 'readunique_prefetch=off'.
Signed-off-by: NKai Shen <shenkai8@huawei.com>
Signed-off-by: NHanjun Guo <guohanjun@huawei.com>
[XQ: adjusted context]
Signed-off-by: NXie XiuQi <xiexiuqi@huawei.com>
Reviewed-by: NHanjun Guo <guohanjun@huawei.com>
Signed-off-by: NCheng Jian <cj.chengjian@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 912d97dc
...@@ -820,6 +820,24 @@ config SOCIONEXT_SYNQUACER_PREITS ...@@ -820,6 +820,24 @@ config SOCIONEXT_SYNQUACER_PREITS
If unsure, say Y. If unsure, say Y.
config HISILICON_ERRATUM_HIP08_RU_PREFETCH
bool "HIP08 RU: HiSilicon HIP08 cache readunique might cause performance drop"
default y
help
The HiSilicon HIP08 cache readunique might compromise performance,
use cmdline "readunique_prefetch_disable" to disable RU prefetch.
If unsure, say Y.
config HISILICON_HIP08_RU_PREFETCH_DEFAULT_OFF
bool "HIP08 RU: disable HiSilicon HIP08 cache readunique by default"
depends on HISILICON_ERRATUM_HIP08_RU_PREFETCH
default n
help
Disable HiSilicon HIP08 cache readunique by default.
If unsure, say N.
endmenu endmenu
......
...@@ -67,7 +67,8 @@ ...@@ -67,7 +67,8 @@
#define ARM64_MTE 57 #define ARM64_MTE 57
#define ARM64_WORKAROUND_1508412 58 #define ARM64_WORKAROUND_1508412 58
#define ARM64_HAS_MPAM 59 #define ARM64_HAS_MPAM 59
#define ARM64_WORKAROUND_HISI_HIP08_RU_PREFETCH 60
#define ARM64_NCAPS 60 #define ARM64_NCAPS 61
#endif /* __ASM_CPUCAPS_H */ #endif /* __ASM_CPUCAPS_H */
...@@ -13,6 +13,11 @@ ...@@ -13,6 +13,11 @@
#include <asm/cpufeature.h> #include <asm/cpufeature.h>
#include <asm/kvm_asm.h> #include <asm/kvm_asm.h>
#include <asm/smp_plat.h> #include <asm/smp_plat.h>
#ifdef CONFIG_HISILICON_ERRATUM_HIP08_RU_PREFETCH
#include <asm/ptrace.h>
#include <asm/sysreg.h>
#include <linux/smp.h>
#endif
static bool __maybe_unused static bool __maybe_unused
is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope) is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope)
...@@ -123,6 +128,48 @@ cpu_enable_cache_maint_trap(const struct arm64_cpu_capabilities *__unused) ...@@ -123,6 +128,48 @@ cpu_enable_cache_maint_trap(const struct arm64_cpu_capabilities *__unused)
sysreg_clear_set(sctlr_el1, SCTLR_EL1_UCI, 0); sysreg_clear_set(sctlr_el1, SCTLR_EL1_UCI, 0);
} }
#ifdef CONFIG_HISILICON_ERRATUM_HIP08_RU_PREFETCH
# ifdef CONFIG_HISILICON_HIP08_RU_PREFETCH_DEFAULT_OFF
static bool readunique_prefetch_enabled;
# else
static bool readunique_prefetch_enabled = true;
# endif
static int __init readunique_prefetch_switch(char *data)
{
if (!data)
return -EINVAL;
if (strcmp(data, "off") == 0)
readunique_prefetch_enabled = false;
else if (strcmp(data, "on") == 0)
readunique_prefetch_enabled = true;
else
return -EINVAL;
return 0;
}
early_param("readunique_prefetch", readunique_prefetch_switch);
static bool
should_disable_hisi_hip08_ru_prefetch(const struct arm64_cpu_capabilities *entry, int unused)
{
u64 el;
if (readunique_prefetch_enabled)
return false;
el = read_sysreg(CurrentEL);
return el == CurrentEL_EL2;
}
#define CTLR_HISI_HIP08_RU_PREFETCH (1L << 40)
static void __maybe_unused
hisi_hip08_ru_prefetch_disable(const struct arm64_cpu_capabilities *__unused)
{
sysreg_clear_set(S3_1_c15_c6_4, 0, CTLR_HISI_HIP08_RU_PREFETCH);
}
#endif
#define CAP_MIDR_RANGE(model, v_min, r_min, v_max, r_max) \ #define CAP_MIDR_RANGE(model, v_min, r_min, v_max, r_max) \
.matches = is_affected_midr_range, \ .matches = is_affected_midr_range, \
.midr_range = MIDR_RANGE(model, v_min, r_min, v_max, r_max) .midr_range = MIDR_RANGE(model, v_min, r_min, v_max, r_max)
...@@ -534,6 +581,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = { ...@@ -534,6 +581,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
0, 0, 0, 0,
1, 0), 1, 0),
}, },
#endif
#ifdef CONFIG_HISILICON_ERRATUM_HIP08_RU_PREFETCH
{
.desc = "HiSilicon HIP08 Cache Readunique Prefetch Disable",
.capability = ARM64_WORKAROUND_HISI_HIP08_RU_PREFETCH,
ERRATA_MIDR_ALL_VERSIONS(MIDR_HISI_TSV110),
.matches = should_disable_hisi_hip08_ru_prefetch,
.cpu_enable = hisi_hip08_ru_prefetch_disable,
},
#endif #endif
{ {
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册