From: Charlie Jenkins <charlie@rivosinc.com>
To: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org
Cc: Paul Walmsley <paul.walmsley@sifive.com>,
Palmer Dabbelt <palmer@dabbelt.com>,
Albert Ou <aou@eecs.berkeley.edu>,
Charlie Jenkins <charlie@rivosinc.com>
Subject: [PATCH 3/5] riscv: Vector checksum header
Date: Sat, 26 Aug 2023 18:26:08 -0700 [thread overview]
Message-ID: <20230826-optimize_checksum-v1-3-937501b4522a@rivosinc.com> (raw)
In-Reply-To: <20230826-optimize_checksum-v1-0-937501b4522a@rivosinc.com>
This patch is not ready for merge as vector support in the kernel is
limited. However, the code has been tested in QEMU so the algorithms
do work. It is written in assembly rather than using the GCC vector
instrinsics because they did not provide optimal code.
Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
---
arch/riscv/include/asm/checksum.h | 81 +++++++++++++++++++++++++++++++++++++++
1 file changed, 81 insertions(+)
diff --git a/arch/riscv/include/asm/checksum.h b/arch/riscv/include/asm/checksum.h
index af49b3409576..7e31c0ad6346 100644
--- a/arch/riscv/include/asm/checksum.h
+++ b/arch/riscv/include/asm/checksum.h
@@ -10,6 +10,10 @@
#include <linux/in6.h>
#include <linux/uaccess.h>
+#ifdef CONFIG_RISCV_ISA_V
+#include <riscv_vector.h>
+#endif
+
/* Default version is sufficient for 32 bit */
#ifdef CONFIG_64BIT
#define _HAVE_ARCH_IPV6_CSUM
@@ -36,6 +40,46 @@ static inline __sum16 csum_fold(__wsum sum)
* without the bitmanip extensions zba/zbb.
*/
#ifdef CONFIG_32BIT
+#ifdef CONFIG_RISCV_ISA_V
+static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
+{
+ vuint64m1_t prev_buffer;
+ vuint32m1_t curr_buffer;
+ unsigned int vl;
+ unsigned int high_result;
+ unsigned int low_result;
+
+ asm("vsetivli x0, 1, e64, ta, ma \n\t\
+ vmv.v.i %[prev_buffer], 0 \n\t\
+ 1: \n\t\
+ vsetvli %[vl], %[ihl], e32, m1, ta, ma \n\t\
+ vle32.v %[curr_buffer], (%[iph]) \n\t\
+ vwredsumu.vs %[prev_buffer], %[curr_buffer], %[prev_buffer] \n\t\
+ sub %[ihl], %[ihl], %[vl] \n\t"
+#ifdef CONFIG_RISCV_ISA_ZBA
+ "sh2add %[iph], %[vl], %[iph] \n\t"
+#else
+ "slli %[vl], %[vl], 2 \n\
+ add %[iph], %[vl], %[iph] \n\t"
+#endif
+ "bnez %[ihl], 1b \n\
+ vsetivli x0, 1, e64, m1, ta, ma \n\
+ vmv.x.s %[low_result], %[prev_buffer] \n\
+ addi %[vl], x0, 32 \n\
+ vsrl.vx %[prev_buffer], %[prev_buffer], %[vl] \n\
+ vmv.x.s %[high_result], %[prev_buffer]"
+ : [vl] "=&r" (vl), [prev_buffer] "=&vd" (prev_buffer),
+ [curr_buffer] "=&vd" (curr_buffer),
+ [high_result] "=&r" (high_result),
+ [low_result] "=&r" (low_result)
+ : [iph] "r" (iph), [ihl] "r" (ihl));
+
+ high_result += low_result;
+ high_result += high_result < low_result;
+ return csum_fold((__force __wsum)(high_result));
+}
+
+#else
static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
{
__wsum csum = 0;
@@ -47,8 +91,44 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
} while (++pos < ihl);
return csum_fold(csum);
}
+#endif
+#else
+
+#ifdef CONFIG_RISCV_ISA_V
+static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
+{
+ vuint64m1_t prev_buffer;
+ vuint32m1_t curr_buffer;
+ unsigned long vl;
+ unsigned long result;
+
+ asm("vsetivli x0, 1, e64, ta, ma \n\
+ vmv.v.i %[prev_buffer], 0 \n\
+ 1: \n\
+ # Setup 32-bit sum of iph \n\
+ vsetvli %[vl], %[ihl], e32, m1, ta, ma \n\
+ vle32.v %[curr_buffer], (%[iph]) \n\
+ # Sum each 32-bit segment of iph that can fit into a vector reg \n\
+ vwredsumu.vs %[prev_buffer], %[curr_buffer], %[prev_buffer] \n\
+ subw %[ihl], %[ihl], %[vl] \n\t"
+#ifdef CONFIG_RISCV_ISA_ZBA
+ "sh2add %[iph], %[vl], %[iph] \n\t"
#else
+ "slli %[vl], %[vl], 2 \n\
+ addw %[iph], %[vl], %[iph] \n\t"
+#endif
+ "# If not all of iph could fit into vector reg, do another sum \n\
+ bnez %[ihl], 1b \n\
+ vsetvli x0, x0, e64, m1, ta, ma \n\
+ vmv.x.s %[result], %[prev_buffer]"
+ : [vl] "=&r" (vl), [prev_buffer] "=&vd" (prev_buffer),
+ [curr_buffer] "=&vd" (curr_buffer), [result] "=&r" (result)
+ : [iph] "r" (iph), [ihl] "r" (ihl));
+ result += (result >> 32) | (result << 32);
+ return csum_fold((__force __wsum)(result >> 32));
+}
+#else
/*
* Quickly compute an IP checksum with the assumption that IPv4 headers will
* always be in multiples of 32-bits, and have an ihl of at least 5.
@@ -74,6 +154,7 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
return csum_fold((__force __wsum)(csum >> 32));
}
#endif
+#endif
#define ip_fast_csum ip_fast_csum
extern unsigned int do_csum(const unsigned char *buff, int len);
--
2.41.0
next prev parent reply other threads:[~2023-08-27 1:27 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-27 1:26 [PATCH 0/5] riscv: Add fine-tuned checksum functions Charlie Jenkins
2023-08-27 1:26 ` [PATCH 1/5] riscv: Checksum header Charlie Jenkins
2023-08-27 1:42 ` Conor Dooley
2023-08-27 2:00 ` Palmer Dabbelt
2023-08-27 10:28 ` Conor Dooley
2023-08-27 12:25 ` Conor Dooley
2023-08-28 16:55 ` Charlie Jenkins
2023-08-28 17:08 ` Conor Dooley
2023-08-28 18:20 ` Charlie Jenkins
2023-08-28 18:56 ` Conor Dooley
2023-08-28 21:39 ` Charlie Jenkins
2023-08-27 1:26 ` [PATCH 2/5] riscv: Add checksum library Charlie Jenkins
2023-08-27 1:26 ` Charlie Jenkins [this message]
2023-08-28 18:22 ` [PATCH 3/5] riscv: Vector checksum header Samuel Holland
2023-08-27 1:26 ` [PATCH 4/5] riscv: Vector checksum library Charlie Jenkins
2023-08-27 1:26 ` [PATCH 5/5] riscv: Test checksum functions Charlie Jenkins
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=20230826-optimize_checksum-v1-3-937501b4522a@rivosinc.com \
--to=charlie@rivosinc.com \
--cc=aou@eecs.berkeley.edu \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=palmer@dabbelt.com \
--cc=paul.walmsley@sifive.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®