* [PATCH V2 0/2] riscv: errata: Add ERRATA_THEAD_WRITE_ONCE fixup
@ 2025-07-13 15:53 guoren
2025-07-13 15:53 ` [PATCH V2 1/2] riscv: Move vendor errata definitions to new header guoren
` (2 more replies)
0 siblings, 3 replies; 16+ messages in thread
From: guoren @ 2025-07-13 15:53 UTC (permalink / raw)
To: palmer, guoren, conor, alexghiti, paul.walmsley, bjorn, eobras,
corbet, peterlin, rabenda.cn
Cc: linux-riscv, linux-kernel
From: "Guo Ren (Alibaba DAMO Academy)" <guoren@kernel.org>
The early version of XuanTie C9xx cores has a store merge buffer
delay problem. The store merge buffer could improve the store queue
performance by merging multi-store requests, but when there are not
continued store requests, the prior single store request would be
waiting in the store queue for a long time. That would cause
significant problems for communication between multi-cores. This
problem was found on sg2042 & th1520 platforms with the qspinlock
lock torture test.
Changelog:
V2:
- Add new header file for errata_list_vendors.
- Rebase newest kernel version.
V1:
https://lore.kernel.org/all/20241214143039.4139398-1-guoren@kernel.org/
Guo Ren (Alibaba DAMO Academy) (2):
riscv: Move vendor errata definitions to new header
riscv: errata: Add ERRATA_THEAD_WRITE_ONCE fixup
arch/riscv/Kconfig.errata | 17 ++++++++++
arch/riscv/errata/thead/errata.c | 20 ++++++++++++
arch/riscv/include/asm/errata_list.h | 19 +----------
arch/riscv/include/asm/errata_list_vendors.h | 25 ++++++++++++++
arch/riscv/include/asm/rwonce.h | 34 ++++++++++++++++++++
include/asm-generic/rwonce.h | 2 ++
6 files changed, 99 insertions(+), 18 deletions(-)
create mode 100644 arch/riscv/include/asm/errata_list_vendors.h
create mode 100644 arch/riscv/include/asm/rwonce.h
--
2.40.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH V2 1/2] riscv: Move vendor errata definitions to new header
2025-07-13 15:53 [PATCH V2 0/2] riscv: errata: Add ERRATA_THEAD_WRITE_ONCE fixup guoren
@ 2025-07-13 15:53 ` guoren
2025-07-15 13:13 ` Han Gao
2025-07-17 8:21 ` Alexandre Ghiti
2025-07-13 15:53 ` [PATCH V2 2/2] riscv: errata: Add ERRATA_THEAD_WRITE_ONCE fixup guoren
2025-08-06 17:15 ` [PATCH V2 0/2] " patchwork-bot+linux-riscv
2 siblings, 2 replies; 16+ messages in thread
From: guoren @ 2025-07-13 15:53 UTC (permalink / raw)
To: palmer, guoren, conor, alexghiti, paul.walmsley, bjorn, eobras,
corbet, peterlin, rabenda.cn
Cc: linux-riscv, linux-kernel
From: "Guo Ren (Alibaba DAMO Academy)" <guoren@kernel.org>
Move vendor errata definitions into errata_list_vendors.h.
Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
---
arch/riscv/include/asm/errata_list.h | 19 +---------------
arch/riscv/include/asm/errata_list_vendors.h | 24 ++++++++++++++++++++
2 files changed, 25 insertions(+), 18 deletions(-)
create mode 100644 arch/riscv/include/asm/errata_list_vendors.h
diff --git a/arch/riscv/include/asm/errata_list.h b/arch/riscv/include/asm/errata_list.h
index 6e426ed7919a..18c9f7ee9b7c 100644
--- a/arch/riscv/include/asm/errata_list.h
+++ b/arch/riscv/include/asm/errata_list.h
@@ -10,24 +10,7 @@
#include <asm/insn-def.h>
#include <asm/hwcap.h>
#include <asm/vendorid_list.h>
-
-#ifdef CONFIG_ERRATA_ANDES
-#define ERRATA_ANDES_NO_IOCP 0
-#define ERRATA_ANDES_NUMBER 1
-#endif
-
-#ifdef CONFIG_ERRATA_SIFIVE
-#define ERRATA_SIFIVE_CIP_453 0
-#define ERRATA_SIFIVE_CIP_1200 1
-#define ERRATA_SIFIVE_NUMBER 2
-#endif
-
-#ifdef CONFIG_ERRATA_THEAD
-#define ERRATA_THEAD_MAE 0
-#define ERRATA_THEAD_PMU 1
-#define ERRATA_THEAD_GHOSTWRITE 2
-#define ERRATA_THEAD_NUMBER 3
-#endif
+#include <asm/errata_list_vendors.h>
#ifdef __ASSEMBLY__
diff --git a/arch/riscv/include/asm/errata_list_vendors.h b/arch/riscv/include/asm/errata_list_vendors.h
new file mode 100644
index 000000000000..a37d1558f39f
--- /dev/null
+++ b/arch/riscv/include/asm/errata_list_vendors.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef ASM_ERRATA_LIST_VENDORS_H
+#define ASM_ERRATA_LIST_VENDORS_H
+
+#ifdef CONFIG_ERRATA_ANDES
+#define ERRATA_ANDES_NO_IOCP 0
+#define ERRATA_ANDES_NUMBER 1
+#endif
+
+#ifdef CONFIG_ERRATA_SIFIVE
+#define ERRATA_SIFIVE_CIP_453 0
+#define ERRATA_SIFIVE_CIP_1200 1
+#define ERRATA_SIFIVE_NUMBER 2
+#endif
+
+#ifdef CONFIG_ERRATA_THEAD
+#define ERRATA_THEAD_MAE 0
+#define ERRATA_THEAD_PMU 1
+#define ERRATA_THEAD_GHOSTWRITE 2
+#define ERRATA_THEAD_NUMBER 3
+#endif
+
+#endif
--
2.40.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH V2 2/2] riscv: errata: Add ERRATA_THEAD_WRITE_ONCE fixup
2025-07-13 15:53 [PATCH V2 0/2] riscv: errata: Add ERRATA_THEAD_WRITE_ONCE fixup guoren
2025-07-13 15:53 ` [PATCH V2 1/2] riscv: Move vendor errata definitions to new header guoren
@ 2025-07-13 15:53 ` guoren
2025-07-15 3:02 ` Drew Fustini
` (2 more replies)
2025-08-06 17:15 ` [PATCH V2 0/2] " patchwork-bot+linux-riscv
2 siblings, 3 replies; 16+ messages in thread
From: guoren @ 2025-07-13 15:53 UTC (permalink / raw)
To: palmer, guoren, conor, alexghiti, paul.walmsley, bjorn, eobras,
corbet, peterlin, rabenda.cn
Cc: linux-riscv, linux-kernel, Leonardo Bras
From: "Guo Ren (Alibaba DAMO Academy)" <guoren@kernel.org>
The early version of XuanTie C910 core has a store merge buffer
delay problem. The store merge buffer could improve the store queue
performance by merging multi-store requests, but when there are not
continued store requests, the prior single store request would be
waiting in the store queue for a long time. That would cause
significant problems for communication between multi-cores. This
problem was found on sg2042 & th1520 platforms with the qspinlock
lock torture test.
So appending a fence w.o could immediately flush the store merge
buffer and let other cores see the write result.
This will apply the WRITE_ONCE errata to handle the non-standard
behavior via appending a fence w.o instruction for WRITE_ONCE().
This problem is only observed on the sg2042 hardware platform by
running the lock_torture test program for half an hour. The problem
was not found in the user space application, because interrupt can
break the livelock.
Reviewed-by: Leonardo Bras <leobras@redhat.com>
Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
---
arch/riscv/Kconfig.errata | 17 ++++++++++
arch/riscv/errata/thead/errata.c | 20 ++++++++++++
arch/riscv/include/asm/errata_list_vendors.h | 3 +-
arch/riscv/include/asm/rwonce.h | 34 ++++++++++++++++++++
include/asm-generic/rwonce.h | 2 ++
5 files changed, 75 insertions(+), 1 deletion(-)
create mode 100644 arch/riscv/include/asm/rwonce.h
diff --git a/arch/riscv/Kconfig.errata b/arch/riscv/Kconfig.errata
index e318119d570d..d2c982ba5373 100644
--- a/arch/riscv/Kconfig.errata
+++ b/arch/riscv/Kconfig.errata
@@ -130,4 +130,21 @@ config ERRATA_THEAD_GHOSTWRITE
If you don't know what to do here, say "Y".
+config ERRATA_THEAD_WRITE_ONCE
+ bool "Apply T-Head WRITE_ONCE errata"
+ depends on ERRATA_THEAD
+ default y
+ help
+ The early version of T-Head C9xx cores of sg2042 & th1520 have a store
+ merge buffer delay problem. The store merge buffer could improve the
+ store queue performance by merging multi-store requests, but when there
+ are no continued store requests, the prior single store request would be
+ waiting in the store queue for a long time. That would cause signifi-
+ cant problems for communication between multi-cores. Appending a
+ fence w.o could immediately flush the store merge buffer and let other
+ cores see the write result.
+
+ This will apply the WRITE_ONCE errata to handle the non-standard beh-
+ avior via appending a fence w.o instruction for WRITE_ONCE().
+
endmenu # "CPU errata selection"
diff --git a/arch/riscv/errata/thead/errata.c b/arch/riscv/errata/thead/errata.c
index 0b942183f708..fbe46f2fa8fb 100644
--- a/arch/riscv/errata/thead/errata.c
+++ b/arch/riscv/errata/thead/errata.c
@@ -168,6 +168,23 @@ static bool errata_probe_ghostwrite(unsigned int stage,
return true;
}
+static bool errata_probe_write_once(unsigned int stage,
+ unsigned long arch_id, unsigned long impid)
+{
+ if (!IS_ENABLED(CONFIG_ERRATA_THEAD_WRITE_ONCE))
+ return false;
+
+ /* target-c9xx cores report arch_id and impid as 0 */
+ if (arch_id != 0 || impid != 0)
+ return false;
+
+ if (stage == RISCV_ALTERNATIVES_BOOT ||
+ stage == RISCV_ALTERNATIVES_MODULE)
+ return true;
+
+ return false;
+}
+
static u32 thead_errata_probe(unsigned int stage,
unsigned long archid, unsigned long impid)
{
@@ -183,6 +200,9 @@ static u32 thead_errata_probe(unsigned int stage,
errata_probe_ghostwrite(stage, archid, impid);
+ if (errata_probe_write_once(stage, archid, impid))
+ cpu_req_errata |= BIT(ERRATA_THEAD_WRITE_ONCE);
+
return cpu_req_errata;
}
diff --git a/arch/riscv/include/asm/errata_list_vendors.h b/arch/riscv/include/asm/errata_list_vendors.h
index a37d1558f39f..a7473cb8874d 100644
--- a/arch/riscv/include/asm/errata_list_vendors.h
+++ b/arch/riscv/include/asm/errata_list_vendors.h
@@ -18,7 +18,8 @@
#define ERRATA_THEAD_MAE 0
#define ERRATA_THEAD_PMU 1
#define ERRATA_THEAD_GHOSTWRITE 2
-#define ERRATA_THEAD_NUMBER 3
+#define ERRATA_THEAD_WRITE_ONCE 3
+#define ERRATA_THEAD_NUMBER 4
#endif
#endif
diff --git a/arch/riscv/include/asm/rwonce.h b/arch/riscv/include/asm/rwonce.h
new file mode 100644
index 000000000000..081793d4d772
--- /dev/null
+++ b/arch/riscv/include/asm/rwonce.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __ASM_RWONCE_H
+#define __ASM_RWONCE_H
+
+#include <linux/compiler_types.h>
+#include <asm/alternative-macros.h>
+#include <asm/vendorid_list.h>
+#include <asm/errata_list_vendors.h>
+
+#if defined(CONFIG_ERRATA_THEAD_WRITE_ONCE) && !defined(NO_ALTERNATIVE)
+
+#define write_once_fence() \
+do { \
+ asm volatile(ALTERNATIVE( \
+ "nop", \
+ "fence w, o", \
+ THEAD_VENDOR_ID, \
+ ERRATA_THEAD_WRITE_ONCE, \
+ CONFIG_ERRATA_THEAD_WRITE_ONCE) \
+ : : : "memory"); \
+} while (0)
+
+#define __WRITE_ONCE(x, val) \
+do { \
+ *(volatile typeof(x) *)&(x) = (val); \
+ write_once_fence(); \
+} while (0)
+
+#endif /* defined(CONFIG_ERRATA_THEAD_WRITE_ONCE) && !defined(NO_ALTERNATIVE) */
+
+#include <asm-generic/rwonce.h>
+
+#endif /* __ASM_RWONCE_H */
diff --git a/include/asm-generic/rwonce.h b/include/asm-generic/rwonce.h
index 52b969c7cef9..4e2d941f15a1 100644
--- a/include/asm-generic/rwonce.h
+++ b/include/asm-generic/rwonce.h
@@ -50,10 +50,12 @@
__READ_ONCE(x); \
})
+#ifndef __WRITE_ONCE
#define __WRITE_ONCE(x, val) \
do { \
*(volatile typeof(x) *)&(x) = (val); \
} while (0)
+#endif
#define WRITE_ONCE(x, val) \
do { \
--
2.40.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH V2 2/2] riscv: errata: Add ERRATA_THEAD_WRITE_ONCE fixup
2025-07-13 15:53 ` [PATCH V2 2/2] riscv: errata: Add ERRATA_THEAD_WRITE_ONCE fixup guoren
@ 2025-07-15 3:02 ` Drew Fustini
2025-07-15 6:14 ` Guo Ren
2025-07-15 13:14 ` Han Gao
2025-07-17 8:22 ` Alexandre Ghiti
2 siblings, 1 reply; 16+ messages in thread
From: Drew Fustini @ 2025-07-15 3:02 UTC (permalink / raw)
To: guoren
Cc: palmer, conor, alexghiti, paul.walmsley, bjorn, eobras, corbet,
peterlin, rabenda.cn, linux-riscv, linux-kernel, Leonardo Bras
On Sun, Jul 13, 2025 at 11:53:21AM -0400, guoren@kernel.org wrote:
> From: "Guo Ren (Alibaba DAMO Academy)" <guoren@kernel.org>
>
> The early version of XuanTie C910 core has a store merge buffer
> delay problem. The store merge buffer could improve the store queue
> performance by merging multi-store requests, but when there are not
> continued store requests, the prior single store request would be
> waiting in the store queue for a long time. That would cause
> significant problems for communication between multi-cores. This
> problem was found on sg2042 & th1520 platforms with the qspinlock
> lock torture test.
>
> So appending a fence w.o could immediately flush the store merge
> buffer and let other cores see the write result.
>
> This will apply the WRITE_ONCE errata to handle the non-standard
> behavior via appending a fence w.o instruction for WRITE_ONCE().
>
> This problem is only observed on the sg2042 hardware platform by
> running the lock_torture test program for half an hour. The problem
> was not found in the user space application, because interrupt can
> break the livelock.
The first paragraph states the problem was found on both the SG2042 and
TH1520, but this paragraph states it is only observed on the SG2042. Is
worth me trying to run lock_torture on the TH1520 for many hours?
Thanks,
Drew
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH V2 2/2] riscv: errata: Add ERRATA_THEAD_WRITE_ONCE fixup
2025-07-15 3:02 ` Drew Fustini
@ 2025-07-15 6:14 ` Guo Ren
0 siblings, 0 replies; 16+ messages in thread
From: Guo Ren @ 2025-07-15 6:14 UTC (permalink / raw)
To: Drew Fustini
Cc: palmer, conor, alexghiti, paul.walmsley, bjorn, eobras, corbet,
peterlin, rabenda.cn, linux-riscv, linux-kernel, Leonardo Bras
On Tue, Jul 15, 2025 at 11:02 AM Drew Fustini <fustini@kernel.org> wrote:
>
> On Sun, Jul 13, 2025 at 11:53:21AM -0400, guoren@kernel.org wrote:
> > From: "Guo Ren (Alibaba DAMO Academy)" <guoren@kernel.org>
> >
> > The early version of XuanTie C910 core has a store merge buffer
> > delay problem. The store merge buffer could improve the store queue
> > performance by merging multi-store requests, but when there are not
> > continued store requests, the prior single store request would be
> > waiting in the store queue for a long time. That would cause
> > significant problems for communication between multi-cores. This
> > problem was found on sg2042 & th1520 platforms with the qspinlock
> > lock torture test.
> >
> > So appending a fence w.o could immediately flush the store merge
> > buffer and let other cores see the write result.
> >
> > This will apply the WRITE_ONCE errata to handle the non-standard
> > behavior via appending a fence w.o instruction for WRITE_ONCE().
> >
> > This problem is only observed on the sg2042 hardware platform by
> > running the lock_torture test program for half an hour. The problem
> > was not found in the user space application, because interrupt can
> > break the livelock.
>
> The first paragraph states the problem was found on both the SG2042 and
> TH1520, but this paragraph states it is only observed on the SG2042. Is
> worth me trying to run lock_torture on the TH1520 for many hours?
We didn't observe that problem on the 1520 due to its small number of cores.
But, we still recommend the th1520 involve this patch for potential write delay.
>
> Thanks,
> Drew
--
Best Regards
Guo Ren
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH V2 1/2] riscv: Move vendor errata definitions to new header
2025-07-13 15:53 ` [PATCH V2 1/2] riscv: Move vendor errata definitions to new header guoren
@ 2025-07-15 13:13 ` Han Gao
2025-07-17 8:21 ` Alexandre Ghiti
1 sibling, 0 replies; 16+ messages in thread
From: Han Gao @ 2025-07-15 13:13 UTC (permalink / raw)
To: guoren
Cc: palmer, conor, alexghiti, paul.walmsley, bjorn, eobras, corbet,
peterlin, linux-riscv, linux-kernel
On Sun, Jul 13, 2025 at 11:53 PM <guoren@kernel.org> wrote:
>
> From: "Guo Ren (Alibaba DAMO Academy)" <guoren@kernel.org>
>
> Move vendor errata definitions into errata_list_vendors.h.
>
> Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
> ---
> arch/riscv/include/asm/errata_list.h | 19 +---------------
> arch/riscv/include/asm/errata_list_vendors.h | 24 ++++++++++++++++++++
> 2 files changed, 25 insertions(+), 18 deletions(-)
> create mode 100644 arch/riscv/include/asm/errata_list_vendors.h
>
> diff --git a/arch/riscv/include/asm/errata_list.h b/arch/riscv/include/asm/errata_list.h
> index 6e426ed7919a..18c9f7ee9b7c 100644
> --- a/arch/riscv/include/asm/errata_list.h
> +++ b/arch/riscv/include/asm/errata_list.h
> @@ -10,24 +10,7 @@
> #include <asm/insn-def.h>
> #include <asm/hwcap.h>
> #include <asm/vendorid_list.h>
> -
> -#ifdef CONFIG_ERRATA_ANDES
> -#define ERRATA_ANDES_NO_IOCP 0
> -#define ERRATA_ANDES_NUMBER 1
> -#endif
> -
> -#ifdef CONFIG_ERRATA_SIFIVE
> -#define ERRATA_SIFIVE_CIP_453 0
> -#define ERRATA_SIFIVE_CIP_1200 1
> -#define ERRATA_SIFIVE_NUMBER 2
> -#endif
> -
> -#ifdef CONFIG_ERRATA_THEAD
> -#define ERRATA_THEAD_MAE 0
> -#define ERRATA_THEAD_PMU 1
> -#define ERRATA_THEAD_GHOSTWRITE 2
> -#define ERRATA_THEAD_NUMBER 3
> -#endif
> +#include <asm/errata_list_vendors.h>
>
> #ifdef __ASSEMBLY__
>
> diff --git a/arch/riscv/include/asm/errata_list_vendors.h b/arch/riscv/include/asm/errata_list_vendors.h
> new file mode 100644
> index 000000000000..a37d1558f39f
> --- /dev/null
> +++ b/arch/riscv/include/asm/errata_list_vendors.h
> @@ -0,0 +1,24 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +
> +#ifndef ASM_ERRATA_LIST_VENDORS_H
> +#define ASM_ERRATA_LIST_VENDORS_H
> +
> +#ifdef CONFIG_ERRATA_ANDES
> +#define ERRATA_ANDES_NO_IOCP 0
> +#define ERRATA_ANDES_NUMBER 1
> +#endif
> +
> +#ifdef CONFIG_ERRATA_SIFIVE
> +#define ERRATA_SIFIVE_CIP_453 0
> +#define ERRATA_SIFIVE_CIP_1200 1
> +#define ERRATA_SIFIVE_NUMBER 2
> +#endif
> +
> +#ifdef CONFIG_ERRATA_THEAD
> +#define ERRATA_THEAD_MAE 0
> +#define ERRATA_THEAD_PMU 1
> +#define ERRATA_THEAD_GHOSTWRITE 2
> +#define ERRATA_THEAD_NUMBER 3
> +#endif
> +
> +#endif
> --
> 2.40.1
>
Tested-by: Han Gao <rabenda.cn@gmail.com>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH V2 2/2] riscv: errata: Add ERRATA_THEAD_WRITE_ONCE fixup
2025-07-13 15:53 ` [PATCH V2 2/2] riscv: errata: Add ERRATA_THEAD_WRITE_ONCE fixup guoren
2025-07-15 3:02 ` Drew Fustini
@ 2025-07-15 13:14 ` Han Gao
2025-07-17 8:22 ` Alexandre Ghiti
2 siblings, 0 replies; 16+ messages in thread
From: Han Gao @ 2025-07-15 13:14 UTC (permalink / raw)
To: guoren
Cc: palmer, conor, alexghiti, paul.walmsley, bjorn, eobras, corbet,
peterlin, linux-riscv, linux-kernel, Leonardo Bras
On Sun, Jul 13, 2025 at 11:53 PM <guoren@kernel.org> wrote:
>
> From: "Guo Ren (Alibaba DAMO Academy)" <guoren@kernel.org>
>
> The early version of XuanTie C910 core has a store merge buffer
> delay problem. The store merge buffer could improve the store queue
> performance by merging multi-store requests, but when there are not
> continued store requests, the prior single store request would be
> waiting in the store queue for a long time. That would cause
> significant problems for communication between multi-cores. This
> problem was found on sg2042 & th1520 platforms with the qspinlock
> lock torture test.
>
> So appending a fence w.o could immediately flush the store merge
> buffer and let other cores see the write result.
>
> This will apply the WRITE_ONCE errata to handle the non-standard
> behavior via appending a fence w.o instruction for WRITE_ONCE().
>
> This problem is only observed on the sg2042 hardware platform by
> running the lock_torture test program for half an hour. The problem
> was not found in the user space application, because interrupt can
> break the livelock.
>
> Reviewed-by: Leonardo Bras <leobras@redhat.com>
> Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
> ---
> arch/riscv/Kconfig.errata | 17 ++++++++++
> arch/riscv/errata/thead/errata.c | 20 ++++++++++++
> arch/riscv/include/asm/errata_list_vendors.h | 3 +-
> arch/riscv/include/asm/rwonce.h | 34 ++++++++++++++++++++
> include/asm-generic/rwonce.h | 2 ++
> 5 files changed, 75 insertions(+), 1 deletion(-)
> create mode 100644 arch/riscv/include/asm/rwonce.h
>
> diff --git a/arch/riscv/Kconfig.errata b/arch/riscv/Kconfig.errata
> index e318119d570d..d2c982ba5373 100644
> --- a/arch/riscv/Kconfig.errata
> +++ b/arch/riscv/Kconfig.errata
> @@ -130,4 +130,21 @@ config ERRATA_THEAD_GHOSTWRITE
>
> If you don't know what to do here, say "Y".
>
> +config ERRATA_THEAD_WRITE_ONCE
> + bool "Apply T-Head WRITE_ONCE errata"
> + depends on ERRATA_THEAD
> + default y
> + help
> + The early version of T-Head C9xx cores of sg2042 & th1520 have a store
> + merge buffer delay problem. The store merge buffer could improve the
> + store queue performance by merging multi-store requests, but when there
> + are no continued store requests, the prior single store request would be
> + waiting in the store queue for a long time. That would cause signifi-
> + cant problems for communication between multi-cores. Appending a
> + fence w.o could immediately flush the store merge buffer and let other
> + cores see the write result.
> +
> + This will apply the WRITE_ONCE errata to handle the non-standard beh-
> + avior via appending a fence w.o instruction for WRITE_ONCE().
> +
> endmenu # "CPU errata selection"
> diff --git a/arch/riscv/errata/thead/errata.c b/arch/riscv/errata/thead/errata.c
> index 0b942183f708..fbe46f2fa8fb 100644
> --- a/arch/riscv/errata/thead/errata.c
> +++ b/arch/riscv/errata/thead/errata.c
> @@ -168,6 +168,23 @@ static bool errata_probe_ghostwrite(unsigned int stage,
> return true;
> }
>
> +static bool errata_probe_write_once(unsigned int stage,
> + unsigned long arch_id, unsigned long impid)
> +{
> + if (!IS_ENABLED(CONFIG_ERRATA_THEAD_WRITE_ONCE))
> + return false;
> +
> + /* target-c9xx cores report arch_id and impid as 0 */
> + if (arch_id != 0 || impid != 0)
> + return false;
> +
> + if (stage == RISCV_ALTERNATIVES_BOOT ||
> + stage == RISCV_ALTERNATIVES_MODULE)
> + return true;
> +
> + return false;
> +}
> +
> static u32 thead_errata_probe(unsigned int stage,
> unsigned long archid, unsigned long impid)
> {
> @@ -183,6 +200,9 @@ static u32 thead_errata_probe(unsigned int stage,
>
> errata_probe_ghostwrite(stage, archid, impid);
>
> + if (errata_probe_write_once(stage, archid, impid))
> + cpu_req_errata |= BIT(ERRATA_THEAD_WRITE_ONCE);
> +
> return cpu_req_errata;
> }
>
> diff --git a/arch/riscv/include/asm/errata_list_vendors.h b/arch/riscv/include/asm/errata_list_vendors.h
> index a37d1558f39f..a7473cb8874d 100644
> --- a/arch/riscv/include/asm/errata_list_vendors.h
> +++ b/arch/riscv/include/asm/errata_list_vendors.h
> @@ -18,7 +18,8 @@
> #define ERRATA_THEAD_MAE 0
> #define ERRATA_THEAD_PMU 1
> #define ERRATA_THEAD_GHOSTWRITE 2
> -#define ERRATA_THEAD_NUMBER 3
> +#define ERRATA_THEAD_WRITE_ONCE 3
> +#define ERRATA_THEAD_NUMBER 4
> #endif
>
> #endif
> diff --git a/arch/riscv/include/asm/rwonce.h b/arch/riscv/include/asm/rwonce.h
> new file mode 100644
> index 000000000000..081793d4d772
> --- /dev/null
> +++ b/arch/riscv/include/asm/rwonce.h
> @@ -0,0 +1,34 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +#ifndef __ASM_RWONCE_H
> +#define __ASM_RWONCE_H
> +
> +#include <linux/compiler_types.h>
> +#include <asm/alternative-macros.h>
> +#include <asm/vendorid_list.h>
> +#include <asm/errata_list_vendors.h>
> +
> +#if defined(CONFIG_ERRATA_THEAD_WRITE_ONCE) && !defined(NO_ALTERNATIVE)
> +
> +#define write_once_fence() \
> +do { \
> + asm volatile(ALTERNATIVE( \
> + "nop", \
> + "fence w, o", \
> + THEAD_VENDOR_ID, \
> + ERRATA_THEAD_WRITE_ONCE, \
> + CONFIG_ERRATA_THEAD_WRITE_ONCE) \
> + : : : "memory"); \
> +} while (0)
> +
> +#define __WRITE_ONCE(x, val) \
> +do { \
> + *(volatile typeof(x) *)&(x) = (val); \
> + write_once_fence(); \
> +} while (0)
> +
> +#endif /* defined(CONFIG_ERRATA_THEAD_WRITE_ONCE) && !defined(NO_ALTERNATIVE) */
> +
> +#include <asm-generic/rwonce.h>
> +
> +#endif /* __ASM_RWONCE_H */
> diff --git a/include/asm-generic/rwonce.h b/include/asm-generic/rwonce.h
> index 52b969c7cef9..4e2d941f15a1 100644
> --- a/include/asm-generic/rwonce.h
> +++ b/include/asm-generic/rwonce.h
> @@ -50,10 +50,12 @@
> __READ_ONCE(x); \
> })
>
> +#ifndef __WRITE_ONCE
> #define __WRITE_ONCE(x, val) \
> do { \
> *(volatile typeof(x) *)&(x) = (val); \
> } while (0)
> +#endif
>
> #define WRITE_ONCE(x, val) \
> do { \
> --
> 2.40.1
>
Tested-by: Han Gao <rabenda.cn@gmail.com>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH V2 1/2] riscv: Move vendor errata definitions to new header
2025-07-13 15:53 ` [PATCH V2 1/2] riscv: Move vendor errata definitions to new header guoren
2025-07-15 13:13 ` Han Gao
@ 2025-07-17 8:21 ` Alexandre Ghiti
1 sibling, 0 replies; 16+ messages in thread
From: Alexandre Ghiti @ 2025-07-17 8:21 UTC (permalink / raw)
To: guoren, palmer, conor, alexghiti, paul.walmsley, bjorn, eobras,
corbet, peterlin, rabenda.cn
Cc: linux-riscv, linux-kernel
Hi Guo,
On 7/13/25 17:53, guoren@kernel.org wrote:
> From: "Guo Ren (Alibaba DAMO Academy)" <guoren@kernel.org>
>
> Move vendor errata definitions into errata_list_vendors.h.
>
> Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
> ---
> arch/riscv/include/asm/errata_list.h | 19 +---------------
> arch/riscv/include/asm/errata_list_vendors.h | 24 ++++++++++++++++++++
> 2 files changed, 25 insertions(+), 18 deletions(-)
> create mode 100644 arch/riscv/include/asm/errata_list_vendors.h
>
> diff --git a/arch/riscv/include/asm/errata_list.h b/arch/riscv/include/asm/errata_list.h
> index 6e426ed7919a..18c9f7ee9b7c 100644
> --- a/arch/riscv/include/asm/errata_list.h
> +++ b/arch/riscv/include/asm/errata_list.h
> @@ -10,24 +10,7 @@
> #include <asm/insn-def.h>
> #include <asm/hwcap.h>
> #include <asm/vendorid_list.h>
> -
> -#ifdef CONFIG_ERRATA_ANDES
> -#define ERRATA_ANDES_NO_IOCP 0
> -#define ERRATA_ANDES_NUMBER 1
> -#endif
> -
> -#ifdef CONFIG_ERRATA_SIFIVE
> -#define ERRATA_SIFIVE_CIP_453 0
> -#define ERRATA_SIFIVE_CIP_1200 1
> -#define ERRATA_SIFIVE_NUMBER 2
> -#endif
> -
> -#ifdef CONFIG_ERRATA_THEAD
> -#define ERRATA_THEAD_MAE 0
> -#define ERRATA_THEAD_PMU 1
> -#define ERRATA_THEAD_GHOSTWRITE 2
> -#define ERRATA_THEAD_NUMBER 3
> -#endif
> +#include <asm/errata_list_vendors.h>
>
> #ifdef __ASSEMBLY__
>
> diff --git a/arch/riscv/include/asm/errata_list_vendors.h b/arch/riscv/include/asm/errata_list_vendors.h
> new file mode 100644
> index 000000000000..a37d1558f39f
> --- /dev/null
> +++ b/arch/riscv/include/asm/errata_list_vendors.h
> @@ -0,0 +1,24 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +
> +#ifndef ASM_ERRATA_LIST_VENDORS_H
> +#define ASM_ERRATA_LIST_VENDORS_H
> +
> +#ifdef CONFIG_ERRATA_ANDES
> +#define ERRATA_ANDES_NO_IOCP 0
> +#define ERRATA_ANDES_NUMBER 1
> +#endif
> +
> +#ifdef CONFIG_ERRATA_SIFIVE
> +#define ERRATA_SIFIVE_CIP_453 0
> +#define ERRATA_SIFIVE_CIP_1200 1
> +#define ERRATA_SIFIVE_NUMBER 2
> +#endif
> +
> +#ifdef CONFIG_ERRATA_THEAD
> +#define ERRATA_THEAD_MAE 0
> +#define ERRATA_THEAD_PMU 1
> +#define ERRATA_THEAD_GHOSTWRITE 2
> +#define ERRATA_THEAD_NUMBER 3
> +#endif
> +
> +#endif
Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Thanks,
Alex
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH V2 2/2] riscv: errata: Add ERRATA_THEAD_WRITE_ONCE fixup
2025-07-13 15:53 ` [PATCH V2 2/2] riscv: errata: Add ERRATA_THEAD_WRITE_ONCE fixup guoren
2025-07-15 3:02 ` Drew Fustini
2025-07-15 13:14 ` Han Gao
@ 2025-07-17 8:22 ` Alexandre Ghiti
2025-10-07 21:36 ` Han Gao
2 siblings, 1 reply; 16+ messages in thread
From: Alexandre Ghiti @ 2025-07-17 8:22 UTC (permalink / raw)
To: guoren, palmer, conor, alexghiti, paul.walmsley, bjorn, eobras,
corbet, peterlin, rabenda.cn
Cc: linux-riscv, linux-kernel, Leonardo Bras
On 7/13/25 17:53, guoren@kernel.org wrote:
> From: "Guo Ren (Alibaba DAMO Academy)" <guoren@kernel.org>
>
> The early version of XuanTie C910 core has a store merge buffer
> delay problem. The store merge buffer could improve the store queue
> performance by merging multi-store requests, but when there are not
> continued store requests, the prior single store request would be
> waiting in the store queue for a long time. That would cause
> significant problems for communication between multi-cores. This
> problem was found on sg2042 & th1520 platforms with the qspinlock
> lock torture test.
>
> So appending a fence w.o could immediately flush the store merge
> buffer and let other cores see the write result.
>
> This will apply the WRITE_ONCE errata to handle the non-standard
> behavior via appending a fence w.o instruction for WRITE_ONCE().
>
> This problem is only observed on the sg2042 hardware platform by
> running the lock_torture test program for half an hour. The problem
> was not found in the user space application, because interrupt can
> break the livelock.
>
> Reviewed-by: Leonardo Bras <leobras@redhat.com>
> Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
> ---
> arch/riscv/Kconfig.errata | 17 ++++++++++
> arch/riscv/errata/thead/errata.c | 20 ++++++++++++
> arch/riscv/include/asm/errata_list_vendors.h | 3 +-
> arch/riscv/include/asm/rwonce.h | 34 ++++++++++++++++++++
> include/asm-generic/rwonce.h | 2 ++
> 5 files changed, 75 insertions(+), 1 deletion(-)
> create mode 100644 arch/riscv/include/asm/rwonce.h
>
> diff --git a/arch/riscv/Kconfig.errata b/arch/riscv/Kconfig.errata
> index e318119d570d..d2c982ba5373 100644
> --- a/arch/riscv/Kconfig.errata
> +++ b/arch/riscv/Kconfig.errata
> @@ -130,4 +130,21 @@ config ERRATA_THEAD_GHOSTWRITE
>
> If you don't know what to do here, say "Y".
>
> +config ERRATA_THEAD_WRITE_ONCE
> + bool "Apply T-Head WRITE_ONCE errata"
> + depends on ERRATA_THEAD
> + default y
> + help
> + The early version of T-Head C9xx cores of sg2042 & th1520 have a store
> + merge buffer delay problem. The store merge buffer could improve the
> + store queue performance by merging multi-store requests, but when there
> + are no continued store requests, the prior single store request would be
> + waiting in the store queue for a long time. That would cause signifi-
> + cant problems for communication between multi-cores. Appending a
> + fence w.o could immediately flush the store merge buffer and let other
> + cores see the write result.
> +
> + This will apply the WRITE_ONCE errata to handle the non-standard beh-
> + avior via appending a fence w.o instruction for WRITE_ONCE().
> +
> endmenu # "CPU errata selection"
> diff --git a/arch/riscv/errata/thead/errata.c b/arch/riscv/errata/thead/errata.c
> index 0b942183f708..fbe46f2fa8fb 100644
> --- a/arch/riscv/errata/thead/errata.c
> +++ b/arch/riscv/errata/thead/errata.c
> @@ -168,6 +168,23 @@ static bool errata_probe_ghostwrite(unsigned int stage,
> return true;
> }
>
> +static bool errata_probe_write_once(unsigned int stage,
> + unsigned long arch_id, unsigned long impid)
> +{
> + if (!IS_ENABLED(CONFIG_ERRATA_THEAD_WRITE_ONCE))
> + return false;
> +
> + /* target-c9xx cores report arch_id and impid as 0 */
> + if (arch_id != 0 || impid != 0)
> + return false;
> +
> + if (stage == RISCV_ALTERNATIVES_BOOT ||
> + stage == RISCV_ALTERNATIVES_MODULE)
> + return true;
> +
> + return false;
> +}
> +
> static u32 thead_errata_probe(unsigned int stage,
> unsigned long archid, unsigned long impid)
> {
> @@ -183,6 +200,9 @@ static u32 thead_errata_probe(unsigned int stage,
>
> errata_probe_ghostwrite(stage, archid, impid);
>
> + if (errata_probe_write_once(stage, archid, impid))
> + cpu_req_errata |= BIT(ERRATA_THEAD_WRITE_ONCE);
> +
> return cpu_req_errata;
> }
>
> diff --git a/arch/riscv/include/asm/errata_list_vendors.h b/arch/riscv/include/asm/errata_list_vendors.h
> index a37d1558f39f..a7473cb8874d 100644
> --- a/arch/riscv/include/asm/errata_list_vendors.h
> +++ b/arch/riscv/include/asm/errata_list_vendors.h
> @@ -18,7 +18,8 @@
> #define ERRATA_THEAD_MAE 0
> #define ERRATA_THEAD_PMU 1
> #define ERRATA_THEAD_GHOSTWRITE 2
> -#define ERRATA_THEAD_NUMBER 3
> +#define ERRATA_THEAD_WRITE_ONCE 3
> +#define ERRATA_THEAD_NUMBER 4
> #endif
>
> #endif
> diff --git a/arch/riscv/include/asm/rwonce.h b/arch/riscv/include/asm/rwonce.h
> new file mode 100644
> index 000000000000..081793d4d772
> --- /dev/null
> +++ b/arch/riscv/include/asm/rwonce.h
> @@ -0,0 +1,34 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +#ifndef __ASM_RWONCE_H
> +#define __ASM_RWONCE_H
> +
> +#include <linux/compiler_types.h>
> +#include <asm/alternative-macros.h>
> +#include <asm/vendorid_list.h>
> +#include <asm/errata_list_vendors.h>
> +
> +#if defined(CONFIG_ERRATA_THEAD_WRITE_ONCE) && !defined(NO_ALTERNATIVE)
> +
> +#define write_once_fence() \
> +do { \
> + asm volatile(ALTERNATIVE( \
> + "nop", \
> + "fence w, o", \
> + THEAD_VENDOR_ID, \
> + ERRATA_THEAD_WRITE_ONCE, \
> + CONFIG_ERRATA_THEAD_WRITE_ONCE) \
> + : : : "memory"); \
> +} while (0)
> +
> +#define __WRITE_ONCE(x, val) \
> +do { \
> + *(volatile typeof(x) *)&(x) = (val); \
> + write_once_fence(); \
> +} while (0)
> +
> +#endif /* defined(CONFIG_ERRATA_THEAD_WRITE_ONCE) && !defined(NO_ALTERNATIVE) */
> +
> +#include <asm-generic/rwonce.h>
> +
> +#endif /* __ASM_RWONCE_H */
> diff --git a/include/asm-generic/rwonce.h b/include/asm-generic/rwonce.h
> index 52b969c7cef9..4e2d941f15a1 100644
> --- a/include/asm-generic/rwonce.h
> +++ b/include/asm-generic/rwonce.h
> @@ -50,10 +50,12 @@
> __READ_ONCE(x); \
> })
>
> +#ifndef __WRITE_ONCE
> #define __WRITE_ONCE(x, val) \
> do { \
> *(volatile typeof(x) *)&(x) = (val); \
> } while (0)
> +#endif
>
> #define WRITE_ONCE(x, val) \
> do { \
I'll send this patchset in my next PR for 6.17:
Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Thanks,
Alex
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH V2 0/2] riscv: errata: Add ERRATA_THEAD_WRITE_ONCE fixup
2025-07-13 15:53 [PATCH V2 0/2] riscv: errata: Add ERRATA_THEAD_WRITE_ONCE fixup guoren
2025-07-13 15:53 ` [PATCH V2 1/2] riscv: Move vendor errata definitions to new header guoren
2025-07-13 15:53 ` [PATCH V2 2/2] riscv: errata: Add ERRATA_THEAD_WRITE_ONCE fixup guoren
@ 2025-08-06 17:15 ` patchwork-bot+linux-riscv
2 siblings, 0 replies; 16+ messages in thread
From: patchwork-bot+linux-riscv @ 2025-08-06 17:15 UTC (permalink / raw)
To: Guo Ren
Cc: linux-riscv, palmer, conor, alexghiti, paul.walmsley, bjorn,
eobras, corbet, peterlin, rabenda.cn, linux-kernel
Hello:
This series was applied to riscv/linux.git (for-next)
by Alexandre Ghiti <alexghiti@rivosinc.com>:
On Sun, 13 Jul 2025 11:53:19 -0400 you wrote:
> From: "Guo Ren (Alibaba DAMO Academy)" <guoren@kernel.org>
>
> The early version of XuanTie C9xx cores has a store merge buffer
> delay problem. The store merge buffer could improve the store queue
> performance by merging multi-store requests, but when there are not
> continued store requests, the prior single store request would be
> waiting in the store queue for a long time. That would cause
> significant problems for communication between multi-cores. This
> problem was found on sg2042 & th1520 platforms with the qspinlock
> lock torture test.
>
> [...]
Here is the summary with links:
- [V2,1/2] riscv: Move vendor errata definitions to new header
https://git.kernel.org/riscv/c/736d67e4f0d0
- [V2,2/2] riscv: errata: Add ERRATA_THEAD_WRITE_ONCE fixup
https://git.kernel.org/riscv/c/b7f09bd30ca8
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH V2 2/2] riscv: errata: Add ERRATA_THEAD_WRITE_ONCE fixup
2025-07-17 8:22 ` Alexandre Ghiti
@ 2025-10-07 21:36 ` Han Gao
2025-10-09 7:29 ` Alexandre Ghiti
0 siblings, 1 reply; 16+ messages in thread
From: Han Gao @ 2025-10-07 21:36 UTC (permalink / raw)
To: Alexandre Ghiti
Cc: guoren, palmer, conor, alexghiti, paul.walmsley, bjorn, eobras,
corbet, peterlin, linux-riscv, linux-kernel, Leonardo Bras
Hi Alex
This patch is included in the 6.17 merge window but not in the
6.18 merge window.
Is it possible that the patch was missed?
On Thu, Jul 17, 2025 at 4:22 PM Alexandre Ghiti <alex@ghiti.fr> wrote:
>
> On 7/13/25 17:53, guoren@kernel.org wrote:
> > From: "Guo Ren (Alibaba DAMO Academy)" <guoren@kernel.org>
> >
> > The early version of XuanTie C910 core has a store merge buffer
> > delay problem. The store merge buffer could improve the store queue
> > performance by merging multi-store requests, but when there are not
> > continued store requests, the prior single store request would be
> > waiting in the store queue for a long time. That would cause
> > significant problems for communication between multi-cores. This
> > problem was found on sg2042 & th1520 platforms with the qspinlock
> > lock torture test.
> >
> > So appending a fence w.o could immediately flush the store merge
> > buffer and let other cores see the write result.
> >
> > This will apply the WRITE_ONCE errata to handle the non-standard
> > behavior via appending a fence w.o instruction for WRITE_ONCE().
> >
> > This problem is only observed on the sg2042 hardware platform by
> > running the lock_torture test program for half an hour. The problem
> > was not found in the user space application, because interrupt can
> > break the livelock.
> >
> > Reviewed-by: Leonardo Bras <leobras@redhat.com>
> > Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
> > ---
> > arch/riscv/Kconfig.errata | 17 ++++++++++
> > arch/riscv/errata/thead/errata.c | 20 ++++++++++++
> > arch/riscv/include/asm/errata_list_vendors.h | 3 +-
> > arch/riscv/include/asm/rwonce.h | 34 ++++++++++++++++++++
> > include/asm-generic/rwonce.h | 2 ++
> > 5 files changed, 75 insertions(+), 1 deletion(-)
> > create mode 100644 arch/riscv/include/asm/rwonce.h
> >
> > diff --git a/arch/riscv/Kconfig.errata b/arch/riscv/Kconfig.errata
> > index e318119d570d..d2c982ba5373 100644
> > --- a/arch/riscv/Kconfig.errata
> > +++ b/arch/riscv/Kconfig.errata
> > @@ -130,4 +130,21 @@ config ERRATA_THEAD_GHOSTWRITE
> >
> > If you don't know what to do here, say "Y".
> >
> > +config ERRATA_THEAD_WRITE_ONCE
> > + bool "Apply T-Head WRITE_ONCE errata"
> > + depends on ERRATA_THEAD
> > + default y
> > + help
> > + The early version of T-Head C9xx cores of sg2042 & th1520 have a store
> > + merge buffer delay problem. The store merge buffer could improve the
> > + store queue performance by merging multi-store requests, but when there
> > + are no continued store requests, the prior single store request would be
> > + waiting in the store queue for a long time. That would cause signifi-
> > + cant problems for communication between multi-cores. Appending a
> > + fence w.o could immediately flush the store merge buffer and let other
> > + cores see the write result.
> > +
> > + This will apply the WRITE_ONCE errata to handle the non-standard beh-
> > + avior via appending a fence w.o instruction for WRITE_ONCE().
> > +
> > endmenu # "CPU errata selection"
> > diff --git a/arch/riscv/errata/thead/errata.c b/arch/riscv/errata/thead/errata.c
> > index 0b942183f708..fbe46f2fa8fb 100644
> > --- a/arch/riscv/errata/thead/errata.c
> > +++ b/arch/riscv/errata/thead/errata.c
> > @@ -168,6 +168,23 @@ static bool errata_probe_ghostwrite(unsigned int stage,
> > return true;
> > }
> >
> > +static bool errata_probe_write_once(unsigned int stage,
> > + unsigned long arch_id, unsigned long impid)
> > +{
> > + if (!IS_ENABLED(CONFIG_ERRATA_THEAD_WRITE_ONCE))
> > + return false;
> > +
> > + /* target-c9xx cores report arch_id and impid as 0 */
> > + if (arch_id != 0 || impid != 0)
> > + return false;
> > +
> > + if (stage == RISCV_ALTERNATIVES_BOOT ||
> > + stage == RISCV_ALTERNATIVES_MODULE)
> > + return true;
> > +
> > + return false;
> > +}
> > +
> > static u32 thead_errata_probe(unsigned int stage,
> > unsigned long archid, unsigned long impid)
> > {
> > @@ -183,6 +200,9 @@ static u32 thead_errata_probe(unsigned int stage,
> >
> > errata_probe_ghostwrite(stage, archid, impid);
> >
> > + if (errata_probe_write_once(stage, archid, impid))
> > + cpu_req_errata |= BIT(ERRATA_THEAD_WRITE_ONCE);
> > +
> > return cpu_req_errata;
> > }
> >
> > diff --git a/arch/riscv/include/asm/errata_list_vendors.h b/arch/riscv/include/asm/errata_list_vendors.h
> > index a37d1558f39f..a7473cb8874d 100644
> > --- a/arch/riscv/include/asm/errata_list_vendors.h
> > +++ b/arch/riscv/include/asm/errata_list_vendors.h
> > @@ -18,7 +18,8 @@
> > #define ERRATA_THEAD_MAE 0
> > #define ERRATA_THEAD_PMU 1
> > #define ERRATA_THEAD_GHOSTWRITE 2
> > -#define ERRATA_THEAD_NUMBER 3
> > +#define ERRATA_THEAD_WRITE_ONCE 3
> > +#define ERRATA_THEAD_NUMBER 4
> > #endif
> >
> > #endif
> > diff --git a/arch/riscv/include/asm/rwonce.h b/arch/riscv/include/asm/rwonce.h
> > new file mode 100644
> > index 000000000000..081793d4d772
> > --- /dev/null
> > +++ b/arch/riscv/include/asm/rwonce.h
> > @@ -0,0 +1,34 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +
> > +#ifndef __ASM_RWONCE_H
> > +#define __ASM_RWONCE_H
> > +
> > +#include <linux/compiler_types.h>
> > +#include <asm/alternative-macros.h>
> > +#include <asm/vendorid_list.h>
> > +#include <asm/errata_list_vendors.h>
> > +
> > +#if defined(CONFIG_ERRATA_THEAD_WRITE_ONCE) && !defined(NO_ALTERNATIVE)
> > +
> > +#define write_once_fence() \
> > +do { \
> > + asm volatile(ALTERNATIVE( \
> > + "nop", \
> > + "fence w, o", \
> > + THEAD_VENDOR_ID, \
> > + ERRATA_THEAD_WRITE_ONCE, \
> > + CONFIG_ERRATA_THEAD_WRITE_ONCE) \
> > + : : : "memory"); \
> > +} while (0)
> > +
> > +#define __WRITE_ONCE(x, val) \
> > +do { \
> > + *(volatile typeof(x) *)&(x) = (val); \
> > + write_once_fence(); \
> > +} while (0)
> > +
> > +#endif /* defined(CONFIG_ERRATA_THEAD_WRITE_ONCE) && !defined(NO_ALTERNATIVE) */
> > +
> > +#include <asm-generic/rwonce.h>
> > +
> > +#endif /* __ASM_RWONCE_H */
> > diff --git a/include/asm-generic/rwonce.h b/include/asm-generic/rwonce.h
> > index 52b969c7cef9..4e2d941f15a1 100644
> > --- a/include/asm-generic/rwonce.h
> > +++ b/include/asm-generic/rwonce.h
> > @@ -50,10 +50,12 @@
> > __READ_ONCE(x); \
> > })
> >
> > +#ifndef __WRITE_ONCE
> > #define __WRITE_ONCE(x, val) \
> > do { \
> > *(volatile typeof(x) *)&(x) = (val); \
> > } while (0)
> > +#endif
> >
> > #define WRITE_ONCE(x, val) \
> > do { \
>
> I'll send this patchset in my next PR for 6.17:
>
> Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
>
> Thanks,
>
> Alex
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH V2 2/2] riscv: errata: Add ERRATA_THEAD_WRITE_ONCE fixup
2025-10-07 21:36 ` Han Gao
@ 2025-10-09 7:29 ` Alexandre Ghiti
2025-10-15 3:37 ` Paul Walmsley
0 siblings, 1 reply; 16+ messages in thread
From: Alexandre Ghiti @ 2025-10-09 7:29 UTC (permalink / raw)
To: Han Gao
Cc: Alexandre Ghiti, guoren, palmer, conor, paul.walmsley, bjorn,
eobras, corbet, peterlin, linux-riscv, linux-kernel,
Leonardo Bras
Hi Han,
On Tue, Oct 7, 2025 at 11:36 PM Han Gao <rabenda.cn@gmail.com> wrote:
>
> Hi Alex
> This patch is included in the 6.17 merge window but not in the
> 6.18 merge window.
> Is it possible that the patch was missed?
Unfortunately, I can't say, you should ask the maintainers.
Thanks,
Alex
>
> On Thu, Jul 17, 2025 at 4:22 PM Alexandre Ghiti <alex@ghiti.fr> wrote:
> >
> > On 7/13/25 17:53, guoren@kernel.org wrote:
> > > From: "Guo Ren (Alibaba DAMO Academy)" <guoren@kernel.org>
> > >
> > > The early version of XuanTie C910 core has a store merge buffer
> > > delay problem. The store merge buffer could improve the store queue
> > > performance by merging multi-store requests, but when there are not
> > > continued store requests, the prior single store request would be
> > > waiting in the store queue for a long time. That would cause
> > > significant problems for communication between multi-cores. This
> > > problem was found on sg2042 & th1520 platforms with the qspinlock
> > > lock torture test.
> > >
> > > So appending a fence w.o could immediately flush the store merge
> > > buffer and let other cores see the write result.
> > >
> > > This will apply the WRITE_ONCE errata to handle the non-standard
> > > behavior via appending a fence w.o instruction for WRITE_ONCE().
> > >
> > > This problem is only observed on the sg2042 hardware platform by
> > > running the lock_torture test program for half an hour. The problem
> > > was not found in the user space application, because interrupt can
> > > break the livelock.
> > >
> > > Reviewed-by: Leonardo Bras <leobras@redhat.com>
> > > Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
> > > ---
> > > arch/riscv/Kconfig.errata | 17 ++++++++++
> > > arch/riscv/errata/thead/errata.c | 20 ++++++++++++
> > > arch/riscv/include/asm/errata_list_vendors.h | 3 +-
> > > arch/riscv/include/asm/rwonce.h | 34 ++++++++++++++++++++
> > > include/asm-generic/rwonce.h | 2 ++
> > > 5 files changed, 75 insertions(+), 1 deletion(-)
> > > create mode 100644 arch/riscv/include/asm/rwonce.h
> > >
> > > diff --git a/arch/riscv/Kconfig.errata b/arch/riscv/Kconfig.errata
> > > index e318119d570d..d2c982ba5373 100644
> > > --- a/arch/riscv/Kconfig.errata
> > > +++ b/arch/riscv/Kconfig.errata
> > > @@ -130,4 +130,21 @@ config ERRATA_THEAD_GHOSTWRITE
> > >
> > > If you don't know what to do here, say "Y".
> > >
> > > +config ERRATA_THEAD_WRITE_ONCE
> > > + bool "Apply T-Head WRITE_ONCE errata"
> > > + depends on ERRATA_THEAD
> > > + default y
> > > + help
> > > + The early version of T-Head C9xx cores of sg2042 & th1520 have a store
> > > + merge buffer delay problem. The store merge buffer could improve the
> > > + store queue performance by merging multi-store requests, but when there
> > > + are no continued store requests, the prior single store request would be
> > > + waiting in the store queue for a long time. That would cause signifi-
> > > + cant problems for communication between multi-cores. Appending a
> > > + fence w.o could immediately flush the store merge buffer and let other
> > > + cores see the write result.
> > > +
> > > + This will apply the WRITE_ONCE errata to handle the non-standard beh-
> > > + avior via appending a fence w.o instruction for WRITE_ONCE().
> > > +
> > > endmenu # "CPU errata selection"
> > > diff --git a/arch/riscv/errata/thead/errata.c b/arch/riscv/errata/thead/errata.c
> > > index 0b942183f708..fbe46f2fa8fb 100644
> > > --- a/arch/riscv/errata/thead/errata.c
> > > +++ b/arch/riscv/errata/thead/errata.c
> > > @@ -168,6 +168,23 @@ static bool errata_probe_ghostwrite(unsigned int stage,
> > > return true;
> > > }
> > >
> > > +static bool errata_probe_write_once(unsigned int stage,
> > > + unsigned long arch_id, unsigned long impid)
> > > +{
> > > + if (!IS_ENABLED(CONFIG_ERRATA_THEAD_WRITE_ONCE))
> > > + return false;
> > > +
> > > + /* target-c9xx cores report arch_id and impid as 0 */
> > > + if (arch_id != 0 || impid != 0)
> > > + return false;
> > > +
> > > + if (stage == RISCV_ALTERNATIVES_BOOT ||
> > > + stage == RISCV_ALTERNATIVES_MODULE)
> > > + return true;
> > > +
> > > + return false;
> > > +}
> > > +
> > > static u32 thead_errata_probe(unsigned int stage,
> > > unsigned long archid, unsigned long impid)
> > > {
> > > @@ -183,6 +200,9 @@ static u32 thead_errata_probe(unsigned int stage,
> > >
> > > errata_probe_ghostwrite(stage, archid, impid);
> > >
> > > + if (errata_probe_write_once(stage, archid, impid))
> > > + cpu_req_errata |= BIT(ERRATA_THEAD_WRITE_ONCE);
> > > +
> > > return cpu_req_errata;
> > > }
> > >
> > > diff --git a/arch/riscv/include/asm/errata_list_vendors.h b/arch/riscv/include/asm/errata_list_vendors.h
> > > index a37d1558f39f..a7473cb8874d 100644
> > > --- a/arch/riscv/include/asm/errata_list_vendors.h
> > > +++ b/arch/riscv/include/asm/errata_list_vendors.h
> > > @@ -18,7 +18,8 @@
> > > #define ERRATA_THEAD_MAE 0
> > > #define ERRATA_THEAD_PMU 1
> > > #define ERRATA_THEAD_GHOSTWRITE 2
> > > -#define ERRATA_THEAD_NUMBER 3
> > > +#define ERRATA_THEAD_WRITE_ONCE 3
> > > +#define ERRATA_THEAD_NUMBER 4
> > > #endif
> > >
> > > #endif
> > > diff --git a/arch/riscv/include/asm/rwonce.h b/arch/riscv/include/asm/rwonce.h
> > > new file mode 100644
> > > index 000000000000..081793d4d772
> > > --- /dev/null
> > > +++ b/arch/riscv/include/asm/rwonce.h
> > > @@ -0,0 +1,34 @@
> > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > +
> > > +#ifndef __ASM_RWONCE_H
> > > +#define __ASM_RWONCE_H
> > > +
> > > +#include <linux/compiler_types.h>
> > > +#include <asm/alternative-macros.h>
> > > +#include <asm/vendorid_list.h>
> > > +#include <asm/errata_list_vendors.h>
> > > +
> > > +#if defined(CONFIG_ERRATA_THEAD_WRITE_ONCE) && !defined(NO_ALTERNATIVE)
> > > +
> > > +#define write_once_fence() \
> > > +do { \
> > > + asm volatile(ALTERNATIVE( \
> > > + "nop", \
> > > + "fence w, o", \
> > > + THEAD_VENDOR_ID, \
> > > + ERRATA_THEAD_WRITE_ONCE, \
> > > + CONFIG_ERRATA_THEAD_WRITE_ONCE) \
> > > + : : : "memory"); \
> > > +} while (0)
> > > +
> > > +#define __WRITE_ONCE(x, val) \
> > > +do { \
> > > + *(volatile typeof(x) *)&(x) = (val); \
> > > + write_once_fence(); \
> > > +} while (0)
> > > +
> > > +#endif /* defined(CONFIG_ERRATA_THEAD_WRITE_ONCE) && !defined(NO_ALTERNATIVE) */
> > > +
> > > +#include <asm-generic/rwonce.h>
> > > +
> > > +#endif /* __ASM_RWONCE_H */
> > > diff --git a/include/asm-generic/rwonce.h b/include/asm-generic/rwonce.h
> > > index 52b969c7cef9..4e2d941f15a1 100644
> > > --- a/include/asm-generic/rwonce.h
> > > +++ b/include/asm-generic/rwonce.h
> > > @@ -50,10 +50,12 @@
> > > __READ_ONCE(x); \
> > > })
> > >
> > > +#ifndef __WRITE_ONCE
> > > #define __WRITE_ONCE(x, val) \
> > > do { \
> > > *(volatile typeof(x) *)&(x) = (val); \
> > > } while (0)
> > > +#endif
> > >
> > > #define WRITE_ONCE(x, val) \
> > > do { \
> >
> > I'll send this patchset in my next PR for 6.17:
> >
> > Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
> >
> > Thanks,
> >
> > Alex
> >
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH V2 2/2] riscv: errata: Add ERRATA_THEAD_WRITE_ONCE fixup
2025-10-09 7:29 ` Alexandre Ghiti
@ 2025-10-15 3:37 ` Paul Walmsley
2025-10-15 7:53 ` Guo Ren
` (2 more replies)
0 siblings, 3 replies; 16+ messages in thread
From: Paul Walmsley @ 2025-10-15 3:37 UTC (permalink / raw)
To: Han Gao, guoren
Cc: Alexandre Ghiti, Alexandre Ghiti, palmer, conor, paul.walmsley,
bjorn, eobras, corbet, peterlin, linux-riscv, linux-kernel,
Leonardo Bras
[-- Attachment #1: Type: text/plain, Size: 556 bytes --]
Hello Han Gao, Guo Ren,
Sorry for the delay in responding -
On Tue, Oct 7, 2025 at 11:36 PM Han Gao <rabenda.cn@gmail.com> wrote:
> This patch is included in the 6.17 merge window but not in the
> 6.18 merge window.
> Is it possible that the patch was missed?
This was almost sent upstream as part of the v6.18 merge window, but given
that it adds the ability for architectures to override WRITE_ONCE, I think
it needs one more attempt at gathering feedback before we do. I'll send
that out this week.
thanks for your patience,
- Paul
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH V2 2/2] riscv: errata: Add ERRATA_THEAD_WRITE_ONCE fixup
2025-10-15 3:37 ` Paul Walmsley
@ 2025-10-15 7:53 ` Guo Ren
2025-12-12 16:37 ` Han Gao
2026-01-15 11:10 ` Yao Zi
2 siblings, 0 replies; 16+ messages in thread
From: Guo Ren @ 2025-10-15 7:53 UTC (permalink / raw)
To: Paul Walmsley
Cc: Han Gao, Alexandre Ghiti, Alexandre Ghiti, palmer, conor,
paul.walmsley, bjorn, eobras, corbet, peterlin, linux-riscv,
linux-kernel, Leonardo Bras
On Wed, Oct 15, 2025 at 11:37 AM Paul Walmsley <pjw@kernel.org> wrote:
>
> Hello Han Gao, Guo Ren,
>
> Sorry for the delay in responding -
>
> On Tue, Oct 7, 2025 at 11:36 PM Han Gao <rabenda.cn@gmail.com> wrote:
>
> > This patch is included in the 6.17 merge window but not in the
> > 6.18 merge window.
> > Is it possible that the patch was missed?
>
> This was almost sent upstream as part of the v6.18 merge window, but given
> that it adds the ability for architectures to override WRITE_ONCE, I think
> it needs one more attempt at gathering feedback before we do. I'll send
> that out this week.
Thanks, Paul, for the effort on this patch. Yes, overriding WRITE_ONCE
needs more public feedback; it makes sense to us. This errata from the
c910 early version causes issues for the community, but some SoCs,
such as th1520 and sg2042, need it to prevent potential risks.
>
> thanks for your patience,
>
> - Paul
--
Best Regards
Guo Ren
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH V2 2/2] riscv: errata: Add ERRATA_THEAD_WRITE_ONCE fixup
2025-10-15 3:37 ` Paul Walmsley
2025-10-15 7:53 ` Guo Ren
@ 2025-12-12 16:37 ` Han Gao
2026-01-15 11:10 ` Yao Zi
2 siblings, 0 replies; 16+ messages in thread
From: Han Gao @ 2025-12-12 16:37 UTC (permalink / raw)
To: Paul Walmsley
Cc: guoren, Alexandre Ghiti, Alexandre Ghiti, palmer, conor,
paul.walmsley, bjorn, eobras, corbet, peterlin, linux-riscv,
linux-kernel, Leonardo Bras
Hi, Paul
This patch is still not being considered for merging in 6.19. Is there
some new issue?
On Wed, Oct 15, 2025 at 12:37 PM Paul Walmsley <pjw@kernel.org> wrote:
>
> Hello Han Gao, Guo Ren,
>
> Sorry for the delay in responding -
>
> On Tue, Oct 7, 2025 at 11:36 PM Han Gao <rabenda.cn@gmail.com> wrote:
>
> > This patch is included in the 6.17 merge window but not in the
> > 6.18 merge window.
> > Is it possible that the patch was missed?
>
> This was almost sent upstream as part of the v6.18 merge window, but given
> that it adds the ability for architectures to override WRITE_ONCE, I think
> it needs one more attempt at gathering feedback before we do. I'll send
> that out this week.
>
> thanks for your patience,
>
> - Paul
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH V2 2/2] riscv: errata: Add ERRATA_THEAD_WRITE_ONCE fixup
2025-10-15 3:37 ` Paul Walmsley
2025-10-15 7:53 ` Guo Ren
2025-12-12 16:37 ` Han Gao
@ 2026-01-15 11:10 ` Yao Zi
2 siblings, 0 replies; 16+ messages in thread
From: Yao Zi @ 2026-01-15 11:10 UTC (permalink / raw)
To: Paul Walmsley, Han Gao, guoren
Cc: Alexandre Ghiti, Alexandre Ghiti, palmer, conor, paul.walmsley,
bjorn, eobras, corbet, peterlin, linux-riscv, linux-kernel,
Leonardo Bras
On Tue, Oct 14, 2025 at 09:37:47PM -0600, Paul Walmsley wrote:
> Hello Han Gao, Guo Ren,
>
> Sorry for the delay in responding -
>
> On Tue, Oct 7, 2025 at 11:36 PM Han Gao <rabenda.cn@gmail.com> wrote:
>
> > This patch is included in the 6.17 merge window but not in the
> > 6.18 merge window.
> > Is it possible that the patch was missed?
>
> This was almost sent upstream as part of the v6.18 merge window, but given
> that it adds the ability for architectures to override WRITE_ONCE, I think
> it needs one more attempt at gathering feedback before we do. I'll send
> that out this week.
>
> thanks for your patience,
Hi Paul,
Could this series be queued for 6.20? It has been more than two months,
and seems no more feedback has come up. Thanks for your work!
> - Paul
Best regards,
Yao Zi
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2026-01-15 11:11 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-13 15:53 [PATCH V2 0/2] riscv: errata: Add ERRATA_THEAD_WRITE_ONCE fixup guoren
2025-07-13 15:53 ` [PATCH V2 1/2] riscv: Move vendor errata definitions to new header guoren
2025-07-15 13:13 ` Han Gao
2025-07-17 8:21 ` Alexandre Ghiti
2025-07-13 15:53 ` [PATCH V2 2/2] riscv: errata: Add ERRATA_THEAD_WRITE_ONCE fixup guoren
2025-07-15 3:02 ` Drew Fustini
2025-07-15 6:14 ` Guo Ren
2025-07-15 13:14 ` Han Gao
2025-07-17 8:22 ` Alexandre Ghiti
2025-10-07 21:36 ` Han Gao
2025-10-09 7:29 ` Alexandre Ghiti
2025-10-15 3:37 ` Paul Walmsley
2025-10-15 7:53 ` Guo Ren
2025-12-12 16:37 ` Han Gao
2026-01-15 11:10 ` Yao Zi
2025-08-06 17:15 ` [PATCH V2 0/2] " patchwork-bot+linux-riscv
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox