Messages in this thread | ![/](/images/icornerl.gif) | | Date | Thu, 16 Mar 2023 12:34:51 +0800 | Subject | Re: [PATCH V3] LoongArch: Make WriteCombine configurable for ioremap() | From | WANG Xuerui <> |
| |
On 3/15/23 16:53, Huacai Chen wrote: > LoongArch maintains cache coherency in hardware, but when paired with > LS7A chipsets the WUC attribute (Weak-ordered UnCached, which is similar > to WriteCombine) is out of the scope of cache coherency machanism for > PCIe devices (this is a PCIe protocol violation, which may be fixed in > newer chipsets). > > This means WUC can only used for write-only memory regions now, so this "can only be used for". Same for the Kconfig change. > option is disabled by default, making WUC silently fallback to SUC for > ioremap(). You can enable this option if the kernel is ensured to run on > hardware without this bug. > > Kernel parameter writecombine=on/off can be used to override the Kconfig > option. We normally want to document this in Documentation/admin-guide/kernel-parameters too. This can be done later (by you or me). > > Suggested-by: WANG Xuerui <kernel@xen0n.name> > Signed-off-by: Huacai Chen <chenhuacai@loongson.cn> > --- > V2: Add kernel prameter and update commit messages. > V3: Add a warning message for invalid kernel parameters. > > arch/loongarch/Kconfig | 16 ++++++++++++++++ > arch/loongarch/include/asm/io.h | 4 +++- > arch/loongarch/kernel/setup.c | 21 +++++++++++++++++++++ > 3 files changed, 40 insertions(+), 1 deletion(-) > > diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig > index 7fd51257e0ed..3ddde336e6a5 100644 > --- a/arch/loongarch/Kconfig > +++ b/arch/loongarch/Kconfig > @@ -447,6 +447,22 @@ config ARCH_IOREMAP > protection support. However, you can enable LoongArch DMW-based > ioremap() for better performance. > > +config ARCH_WRITECOMBINE > + bool "Enable WriteCombine (WUC) for ioremap()" > + help > + LoongArch maintains cache coherency in hardware, but when paired > + with LS7A chipsets the WUC attribute (Weak-ordered UnCached, which > + is similar to WriteCombine) is out of the scope of cache coherency > + machanism for PCIe devices (this is a PCIe protocol violation, which > + may be fixed in newer chipsets). > + > + This means WUC can only used for write-only memory regions now, so > + this option is disabled by default, making WUC silently fallback to > + SUC for ioremap(). You can enable this option if the kernel is ensured > + to run on hardware without this bug. > + > + You can override this setting via writecombine=on/off boot parameter. via the ... > + > config ARCH_STRICT_ALIGN > bool "Enable -mstrict-align to prevent unaligned accesses" if EXPERT > default y > diff --git a/arch/loongarch/include/asm/io.h b/arch/loongarch/include/asm/io.h > index 402a7d9e3a53..545e2708fbf7 100644 > --- a/arch/loongarch/include/asm/io.h > +++ b/arch/loongarch/include/asm/io.h > @@ -54,8 +54,10 @@ static inline void __iomem *ioremap_prot(phys_addr_t offset, unsigned long size, > * @offset: bus address of the memory > * @size: size of the resource to map > */ > +extern pgprot_t pgprot_wc; > + > #define ioremap_wc(offset, size) \ > - ioremap_prot((offset), (size), pgprot_val(PAGE_KERNEL_WUC)) > + ioremap_prot((offset), (size), pgprot_val(pgprot_wc)) > > #define ioremap_cache(offset, size) \ > ioremap_prot((offset), (size), pgprot_val(PAGE_KERNEL)) > diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c > index bae84ccf6d36..27f71f9531e1 100644 > --- a/arch/loongarch/kernel/setup.c > +++ b/arch/loongarch/kernel/setup.c > @@ -160,6 +160,27 @@ static void __init smbios_parse(void) > dmi_walk(find_tokens, NULL); > } > > +#ifdef CONFIG_ARCH_WRITECOMBINE > +pgprot_t pgprot_wc = PAGE_KERNEL_WUC; > +#else > +pgprot_t pgprot_wc = PAGE_KERNEL_SUC; > +#endif > + > +EXPORT_SYMBOL(pgprot_wc); > + > +static int __init setup_writecombine(char *p) > +{ > + if (!strcmp(p, "on")) > + pgprot_wc = PAGE_KERNEL_WUC; > + else if (!strcmp(p, "off")) > + pgprot_wc = PAGE_KERNEL_SUC; > + else > + pr_warn("Unknown writecombine setting \"%s\".\n", p); > + > + return 0; > +} > +early_param("writecombine", setup_writecombine); > + > static int usermem __initdata; > > static int __init early_parse_mem(char *p)
With the nits addressed:
Reviewed-by: WANG Xuerui <git@xen0n.name>
-- WANG "xen0n" Xuerui
Linux/LoongArch mailing list: https://lore.kernel.org/loongarch/
| ![\](/images/icornerr.gif) |