From: Ben Dooks <ben.dooks@codethink.co.uk>
To: kvm-riscv@lists.infradead.org
Subject: [PATCH v5 6/8] RISC-V: Use Zicboz in clear_page when available
Date: Fri, 24 Feb 2023 14:00:44 +0000 [thread overview]
Message-ID: <36abc02f-ef35-88a8-1fa8-ce7cebbae7ea@codethink.co.uk> (raw)
In-Reply-To: <20230221190916.572454-7-ajones@ventanamicro.com>
On 21/02/2023 19:09, Andrew Jones wrote:
> Using memset() to zero a 4K page takes 563 total instructions, where
> 20 are branches. clear_page(), with Zicboz and a 64 byte block size,
> takes 169 total instructions, where 4 are branches and 33 are nops.
> Even though the block size is a variable, thanks to alternatives, we
> can still implement a Duff device without having to do any preliminary
> calculations. This is achieved by using the alternatives' cpufeature
> value (the upper 16 bits of patch_id). The value used is the maximum
> zicboz block size order accepted at the patch site. This enables us
> to stop patching / unrolling when 4K bytes have been zeroed (we would
> loop and continue after 4K if the page size would be larger)
>
> For 4K pages, unrolling 16 times allows block sizes of 64 and 128 to
> only loop a few times and larger block sizes to not loop at all. Since
> cbo.zero doesn't take an offset, we also need an 'add' after each
> instruction, making the loop body 112 to 160 bytes. Hopefully this
> is small enough to not cause icache misses.
>
> Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
> Acked-by: Conor Dooley <conor.dooley@microchip.com>
> ---
> arch/riscv/Kconfig | 13 ++++++
> arch/riscv/include/asm/insn-def.h | 4 ++
> arch/riscv/include/asm/page.h | 6 ++-
> arch/riscv/kernel/cpufeature.c | 11 +++++
> arch/riscv/lib/Makefile | 1 +
> arch/riscv/lib/clear_page.S | 73 +++++++++++++++++++++++++++++++
> 6 files changed, 107 insertions(+), 1 deletion(-)
> create mode 100644 arch/riscv/lib/clear_page.S
[snip]
> diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
> index 0594989ead63..4a496552b812 100644
> --- a/arch/riscv/kernel/cpufeature.c
> +++ b/arch/riscv/kernel/cpufeature.c
> @@ -292,6 +292,17 @@ static bool riscv_cpufeature_patch_check(u16 id, u16 value)
> if (!value)
> return true;
>
> + switch (id) {
> + case RISCV_ISA_EXT_ZICBOZ:
> + /*
> + * Zicboz alternative applications provide the maximum
> + * supported block size order, or zero when it doesn't
> + * matter. If the current block size exceeds the maximum,
> + * then the alternative cannot be applied.
> + */
> + return riscv_cboz_block_size <= (1U << value);
> + }
> +
> return false;
> }
>
> diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
> index 6c74b0bedd60..26cb2502ecf8 100644
> --- a/arch/riscv/lib/Makefile
> +++ b/arch/riscv/lib/Makefile
> @@ -8,5 +8,6 @@ lib-y += strlen.o
> lib-y += strncmp.o
> lib-$(CONFIG_MMU) += uaccess.o
> lib-$(CONFIG_64BIT) += tishift.o
> +lib-$(CONFIG_RISCV_ISA_ZICBOZ) += clear_page.o
>
> obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
> diff --git a/arch/riscv/lib/clear_page.S b/arch/riscv/lib/clear_page.S
> new file mode 100644
> index 000000000000..7c7fa45b5ab5
> --- /dev/null
> +++ b/arch/riscv/lib/clear_page.S
> @@ -0,0 +1,73 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (c) 2023 Ventana Micro Systems Inc.
> + */
> +
> +#include <linux/linkage.h>
> +#include <asm/asm.h>
> +#include <asm/alternative-macros.h>
> +#include <asm/hwcap.h>
> +#include <asm/insn-def.h>
> +#include <asm/page.h>
> +
> +#define CBOZ_ALT(order, old, new) \
> + ALTERNATIVE(old, new, 0, \
> + ((order) << 16) | RISCV_ISA_EXT_ZICBOZ, \
> + CONFIG_RISCV_ISA_ZICBOZ)
> +
> +/* void clear_page(void *page) */
> +ENTRY(__clear_page)
> +WEAK(clear_page)
out of interest, why the __clear_page() entry and the
WEAK(clear_page)?
Just followed up with a patch to fix the modpost.
So far this seems to be working with qemu and a backport to 5.19.x
--
Ben Dooks http://www.codethink.co.uk/
Senior Engineer Codethink - Providing Genius
https://www.codethink.co.uk/privacy.html
WARNING: multiple messages have this Message-ID (diff)
From: Ben Dooks <ben.dooks@codethink.co.uk>
To: Andrew Jones <ajones@ventanamicro.com>,
linux-riscv@lists.infradead.org, devicetree@vger.kernel.org,
kvm-riscv@lists.infradead.org
Cc: 'Rob Herring ' <robh@kernel.org>,
'Jisheng Zhang ' <jszhang@kernel.org>,
'Anup Patel ' <apatel@ventanamicro.com>,
'Conor Dooley ' <conor.dooley@microchip.com>,
'Krzysztof Kozlowski ' <krzysztof.kozlowski+dt@linaro.org>,
'Heiko Stuebner ' <heiko@sntech.de>,
'Paul Walmsley ' <paul.walmsley@sifive.com>,
'Palmer Dabbelt ' <palmer@dabbelt.com>,
'Albert Ou ' <aou@eecs.berkeley.edu>,
'Atish Patra ' <atishp@rivosinc.com>
Subject: Re: [PATCH v5 6/8] RISC-V: Use Zicboz in clear_page when available
Date: Fri, 24 Feb 2023 14:00:44 +0000 [thread overview]
Message-ID: <36abc02f-ef35-88a8-1fa8-ce7cebbae7ea@codethink.co.uk> (raw)
In-Reply-To: <20230221190916.572454-7-ajones@ventanamicro.com>
On 21/02/2023 19:09, Andrew Jones wrote:
> Using memset() to zero a 4K page takes 563 total instructions, where
> 20 are branches. clear_page(), with Zicboz and a 64 byte block size,
> takes 169 total instructions, where 4 are branches and 33 are nops.
> Even though the block size is a variable, thanks to alternatives, we
> can still implement a Duff device without having to do any preliminary
> calculations. This is achieved by using the alternatives' cpufeature
> value (the upper 16 bits of patch_id). The value used is the maximum
> zicboz block size order accepted at the patch site. This enables us
> to stop patching / unrolling when 4K bytes have been zeroed (we would
> loop and continue after 4K if the page size would be larger)
>
> For 4K pages, unrolling 16 times allows block sizes of 64 and 128 to
> only loop a few times and larger block sizes to not loop at all. Since
> cbo.zero doesn't take an offset, we also need an 'add' after each
> instruction, making the loop body 112 to 160 bytes. Hopefully this
> is small enough to not cause icache misses.
>
> Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
> Acked-by: Conor Dooley <conor.dooley@microchip.com>
> ---
> arch/riscv/Kconfig | 13 ++++++
> arch/riscv/include/asm/insn-def.h | 4 ++
> arch/riscv/include/asm/page.h | 6 ++-
> arch/riscv/kernel/cpufeature.c | 11 +++++
> arch/riscv/lib/Makefile | 1 +
> arch/riscv/lib/clear_page.S | 73 +++++++++++++++++++++++++++++++
> 6 files changed, 107 insertions(+), 1 deletion(-)
> create mode 100644 arch/riscv/lib/clear_page.S
[snip]
> diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
> index 0594989ead63..4a496552b812 100644
> --- a/arch/riscv/kernel/cpufeature.c
> +++ b/arch/riscv/kernel/cpufeature.c
> @@ -292,6 +292,17 @@ static bool riscv_cpufeature_patch_check(u16 id, u16 value)
> if (!value)
> return true;
>
> + switch (id) {
> + case RISCV_ISA_EXT_ZICBOZ:
> + /*
> + * Zicboz alternative applications provide the maximum
> + * supported block size order, or zero when it doesn't
> + * matter. If the current block size exceeds the maximum,
> + * then the alternative cannot be applied.
> + */
> + return riscv_cboz_block_size <= (1U << value);
> + }
> +
> return false;
> }
>
> diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
> index 6c74b0bedd60..26cb2502ecf8 100644
> --- a/arch/riscv/lib/Makefile
> +++ b/arch/riscv/lib/Makefile
> @@ -8,5 +8,6 @@ lib-y += strlen.o
> lib-y += strncmp.o
> lib-$(CONFIG_MMU) += uaccess.o
> lib-$(CONFIG_64BIT) += tishift.o
> +lib-$(CONFIG_RISCV_ISA_ZICBOZ) += clear_page.o
>
> obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
> diff --git a/arch/riscv/lib/clear_page.S b/arch/riscv/lib/clear_page.S
> new file mode 100644
> index 000000000000..7c7fa45b5ab5
> --- /dev/null
> +++ b/arch/riscv/lib/clear_page.S
> @@ -0,0 +1,73 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (c) 2023 Ventana Micro Systems Inc.
> + */
> +
> +#include <linux/linkage.h>
> +#include <asm/asm.h>
> +#include <asm/alternative-macros.h>
> +#include <asm/hwcap.h>
> +#include <asm/insn-def.h>
> +#include <asm/page.h>
> +
> +#define CBOZ_ALT(order, old, new) \
> + ALTERNATIVE(old, new, 0, \
> + ((order) << 16) | RISCV_ISA_EXT_ZICBOZ, \
> + CONFIG_RISCV_ISA_ZICBOZ)
> +
> +/* void clear_page(void *page) */
> +ENTRY(__clear_page)
> +WEAK(clear_page)
out of interest, why the __clear_page() entry and the
WEAK(clear_page)?
Just followed up with a patch to fix the modpost.
So far this seems to be working with qemu and a backport to 5.19.x
--
Ben Dooks http://www.codethink.co.uk/
Senior Engineer Codethink - Providing Genius
https://www.codethink.co.uk/privacy.html
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
WARNING: multiple messages have this Message-ID (diff)
From: Ben Dooks <ben.dooks@codethink.co.uk>
To: Andrew Jones <ajones@ventanamicro.com>,
linux-riscv@lists.infradead.org, devicetree@vger.kernel.org,
kvm-riscv@lists.infradead.org
Cc: 'Rob Herring ' <robh@kernel.org>,
'Jisheng Zhang ' <jszhang@kernel.org>,
'Anup Patel ' <apatel@ventanamicro.com>,
'Conor Dooley ' <conor.dooley@microchip.com>,
'Krzysztof Kozlowski ' <krzysztof.kozlowski+dt@linaro.org>,
'Heiko Stuebner ' <heiko@sntech.de>,
'Paul Walmsley ' <paul.walmsley@sifive.com>,
'Palmer Dabbelt ' <palmer@dabbelt.com>,
'Albert Ou ' <aou@eecs.berkeley.edu>,
'Atish Patra ' <atishp@rivosinc.com>
Subject: Re: [PATCH v5 6/8] RISC-V: Use Zicboz in clear_page when available
Date: Fri, 24 Feb 2023 14:00:44 +0000 [thread overview]
Message-ID: <36abc02f-ef35-88a8-1fa8-ce7cebbae7ea@codethink.co.uk> (raw)
In-Reply-To: <20230221190916.572454-7-ajones@ventanamicro.com>
On 21/02/2023 19:09, Andrew Jones wrote:
> Using memset() to zero a 4K page takes 563 total instructions, where
> 20 are branches. clear_page(), with Zicboz and a 64 byte block size,
> takes 169 total instructions, where 4 are branches and 33 are nops.
> Even though the block size is a variable, thanks to alternatives, we
> can still implement a Duff device without having to do any preliminary
> calculations. This is achieved by using the alternatives' cpufeature
> value (the upper 16 bits of patch_id). The value used is the maximum
> zicboz block size order accepted at the patch site. This enables us
> to stop patching / unrolling when 4K bytes have been zeroed (we would
> loop and continue after 4K if the page size would be larger)
>
> For 4K pages, unrolling 16 times allows block sizes of 64 and 128 to
> only loop a few times and larger block sizes to not loop at all. Since
> cbo.zero doesn't take an offset, we also need an 'add' after each
> instruction, making the loop body 112 to 160 bytes. Hopefully this
> is small enough to not cause icache misses.
>
> Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
> Acked-by: Conor Dooley <conor.dooley@microchip.com>
> ---
> arch/riscv/Kconfig | 13 ++++++
> arch/riscv/include/asm/insn-def.h | 4 ++
> arch/riscv/include/asm/page.h | 6 ++-
> arch/riscv/kernel/cpufeature.c | 11 +++++
> arch/riscv/lib/Makefile | 1 +
> arch/riscv/lib/clear_page.S | 73 +++++++++++++++++++++++++++++++
> 6 files changed, 107 insertions(+), 1 deletion(-)
> create mode 100644 arch/riscv/lib/clear_page.S
[snip]
> diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
> index 0594989ead63..4a496552b812 100644
> --- a/arch/riscv/kernel/cpufeature.c
> +++ b/arch/riscv/kernel/cpufeature.c
> @@ -292,6 +292,17 @@ static bool riscv_cpufeature_patch_check(u16 id, u16 value)
> if (!value)
> return true;
>
> + switch (id) {
> + case RISCV_ISA_EXT_ZICBOZ:
> + /*
> + * Zicboz alternative applications provide the maximum
> + * supported block size order, or zero when it doesn't
> + * matter. If the current block size exceeds the maximum,
> + * then the alternative cannot be applied.
> + */
> + return riscv_cboz_block_size <= (1U << value);
> + }
> +
> return false;
> }
>
> diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
> index 6c74b0bedd60..26cb2502ecf8 100644
> --- a/arch/riscv/lib/Makefile
> +++ b/arch/riscv/lib/Makefile
> @@ -8,5 +8,6 @@ lib-y += strlen.o
> lib-y += strncmp.o
> lib-$(CONFIG_MMU) += uaccess.o
> lib-$(CONFIG_64BIT) += tishift.o
> +lib-$(CONFIG_RISCV_ISA_ZICBOZ) += clear_page.o
>
> obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
> diff --git a/arch/riscv/lib/clear_page.S b/arch/riscv/lib/clear_page.S
> new file mode 100644
> index 000000000000..7c7fa45b5ab5
> --- /dev/null
> +++ b/arch/riscv/lib/clear_page.S
> @@ -0,0 +1,73 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (c) 2023 Ventana Micro Systems Inc.
> + */
> +
> +#include <linux/linkage.h>
> +#include <asm/asm.h>
> +#include <asm/alternative-macros.h>
> +#include <asm/hwcap.h>
> +#include <asm/insn-def.h>
> +#include <asm/page.h>
> +
> +#define CBOZ_ALT(order, old, new) \
> + ALTERNATIVE(old, new, 0, \
> + ((order) << 16) | RISCV_ISA_EXT_ZICBOZ, \
> + CONFIG_RISCV_ISA_ZICBOZ)
> +
> +/* void clear_page(void *page) */
> +ENTRY(__clear_page)
> +WEAK(clear_page)
out of interest, why the __clear_page() entry and the
WEAK(clear_page)?
Just followed up with a patch to fix the modpost.
So far this seems to be working with qemu and a backport to 5.19.x
--
Ben Dooks http://www.codethink.co.uk/
Senior Engineer Codethink - Providing Genius
https://www.codethink.co.uk/privacy.html
next prev parent reply other threads:[~2023-02-24 14:00 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-02-21 19:09 [PATCH v5 0/8] RISC-V: Apply Zicboz to clear_page Andrew Jones
2023-02-21 19:09 ` Andrew Jones
2023-02-21 19:09 ` Andrew Jones
2023-02-21 19:09 ` [PATCH v5 1/8] RISC-V: alternatives: Support patching multiple insns in assembly Andrew Jones
2023-02-21 19:09 ` Andrew Jones
2023-02-21 19:09 ` Andrew Jones
2023-02-21 19:09 ` [PATCH v5 2/8] RISC-V: Factor out body of riscv_init_cbom_blocksize loop Andrew Jones
2023-02-21 19:09 ` Andrew Jones
2023-02-21 19:09 ` Andrew Jones
2023-02-21 19:09 ` [PATCH v5 3/8] dt-bindings: riscv: Document cboz-block-size Andrew Jones
2023-02-21 19:09 ` Andrew Jones
2023-02-21 19:09 ` Andrew Jones
2023-02-21 19:09 ` [PATCH v5 4/8] RISC-V: Add Zicboz detection and block size parsing Andrew Jones
2023-02-21 19:09 ` Andrew Jones
2023-02-21 19:09 ` Andrew Jones
2023-02-21 19:09 ` [PATCH v5 5/8] riscv: cpufeatures: Put the upper 16 bits of patch ID to work Andrew Jones
2023-02-21 19:09 ` Andrew Jones
2023-02-21 19:09 ` Andrew Jones
2023-02-22 17:27 ` Conor Dooley
2023-02-22 17:28 ` Conor Dooley
2023-02-22 17:27 ` Conor Dooley
2023-02-23 12:53 ` Andrew Jones
2023-02-23 12:53 ` Andrew Jones
2023-02-23 12:53 ` Andrew Jones
2023-02-21 19:09 ` [PATCH v5 6/8] RISC-V: Use Zicboz in clear_page when available Andrew Jones
2023-02-21 19:09 ` Andrew Jones
2023-02-21 19:09 ` Andrew Jones
2023-02-24 13:58 ` [PATCH] RISC-V: Fixup clear_page export when using Zicboz Ben Dooks
2023-02-24 14:18 ` Andrew Jones
2023-02-24 14:42 ` Ben Dooks
2023-02-24 15:19 ` Andrew Jones
2023-02-24 14:44 ` Sudip Mukherjee
2023-02-24 15:11 ` Andrew Jones
2023-02-24 14:00 ` Ben Dooks [this message]
2023-02-24 14:00 ` [PATCH v5 6/8] RISC-V: Use Zicboz in clear_page when available Ben Dooks
2023-02-24 14:00 ` Ben Dooks
2023-02-24 14:25 ` Andrew Jones
2023-02-24 14:25 ` Andrew Jones
2023-02-24 14:25 ` Andrew Jones
2023-02-24 14:36 ` Andrew Jones
2023-02-24 14:36 ` Andrew Jones
2023-02-24 14:36 ` Andrew Jones
2023-02-21 19:09 ` [PATCH v5 7/8] RISC-V: KVM: Provide UAPI for Zicboz block size Andrew Jones
2023-02-21 19:09 ` Andrew Jones
2023-02-21 19:09 ` Andrew Jones
2023-02-21 19:09 ` [PATCH v5 8/8] RISC-V: KVM: Expose Zicboz to the guest Andrew Jones
2023-02-21 19:09 ` Andrew Jones
2023-02-21 19:09 ` Andrew Jones
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=36abc02f-ef35-88a8-1fa8-ce7cebbae7ea@codethink.co.uk \
--to=ben.dooks@codethink.co.uk \
--cc=kvm-riscv@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.