Unverified Commit cb2566ed authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

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

Merge Pull Request from: @ci-robot 
 
PR sync from: Yang Yingliang <yangyingliang@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/OIBVUYEE63LJQN5A4IZ6V6FO7K7PJ77U/ 
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'.

Kai Shen (1):
  arm64: errata: add option to disable cache readunique prefetch on
    HIP08

Xie XiuQi (1):
  arm64: errata: enable HISILICON_ERRATUM_HIP08_RU_PREFETCH


-- 
2.25.1
 
https://gitee.com/openeuler/kernel/issues/I8MKTT 
 
Link:https://gitee.com/openeuler/kernel/pulls/3285

 

Reviewed-by: default avatarZhang Jianhua <chris.zjh@huawei.com>
Reviewed-by: default avatarXie XiuQi <xiexiuqi@huawei.com>
Reviewed-by: default avatarLiu Chao <liuchao173@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parents 69f301dd 777e017f
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -1241,6 +1241,24 @@ config SOCIONEXT_SYNQUACER_PREITS

	  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 # "ARM errata workarounds via the alternatives framework"

choice
+2 −0
Original line number Diff line number Diff line
@@ -403,6 +403,8 @@ CONFIG_QCOM_FALKOR_ERRATUM_E1041=y
CONFIG_NVIDIA_CARMEL_CNP_ERRATUM=y
CONFIG_ROCKCHIP_ERRATUM_3588001=y
CONFIG_SOCIONEXT_SYNQUACER_PREITS=y
CONFIG_HISILICON_ERRATUM_HIP08_RU_PREFETCH=y
# CONFIG_HISILICON_HIP08_RU_PREFETCH_DEFAULT_OFF is not set
# end of ARM errata workarounds via the alternatives framework

CONFIG_ARM64_4K_PAGES=y
+56 −0
Original line number Diff line number Diff line
@@ -13,6 +13,11 @@
#include <asm/cpufeature.h>
#include <asm/kvm_asm.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
is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope)
@@ -121,6 +126,48 @@ cpu_enable_cache_maint_trap(const struct arm64_cpu_capabilities *__unused)
	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

static DEFINE_RAW_SPINLOCK(reg_user_mask_modification);
static void __maybe_unused
cpu_clear_bf16_from_user_emulation(const struct arm64_cpu_capabilities *__unused)
@@ -758,6 +805,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
		.capability = ARM64_WORKAROUND_AMPERE_AC03_CPU_38,
		ERRATA_MIDR_ALL_VERSIONS(MIDR_AMPERE1),
	},
#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
	{
	}
+1 −0
Original line number Diff line number Diff line
@@ -101,3 +101,4 @@ WORKAROUND_QCOM_FALKOR_E1003
WORKAROUND_REPEAT_TLBI
WORKAROUND_SPECULATIVE_AT
WORKAROUND_HISILICON_ERRATUM_162100125
WORKAROUND_HISI_HIP08_RU_PREFETCH