summaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
authorDavid Quigley <[email protected]>2017-02-01 10:34:22 -0700
committerBrian Behlendorf <[email protected]>2017-02-01 09:34:22 -0800
commit2fe36b0bfb80a4955f6ff42b2448f432223f6011 (patch)
tree010c7c2eb7b90565a10543f1602b5bee1f4699d7 /module
parent544b8053dbb03de69950c232d1f1970bc36535b6 (diff)
Use fletcher_4 routines natively with `abd_iterate_func()`
This patch adds the necessary infrastructure for ABD to make use of the vectorized fletcher 4 routines. - export ABD compatible interface from fletcher_4 - add ABD fletcher_4 tests for data and metadata ABD types. Reviewed-by: Brian Behlendorf <[email protected]> Original-patch-by: Gvozden Neskovic <[email protected]> Signed-off-by: David Quigley <[email protected]> Closes #5589
Diffstat (limited to 'module')
-rw-r--r--module/zcommon/zfs_fletcher.c87
-rw-r--r--module/zfs/zio_checksum.c33
2 files changed, 112 insertions, 8 deletions
diff --git a/module/zcommon/zfs_fletcher.c b/module/zcommon/zfs_fletcher.c
index 1d1ea2e24..9cdf36d44 100644
--- a/module/zcommon/zfs_fletcher.c
+++ b/module/zcommon/zfs_fletcher.c
@@ -141,6 +141,7 @@
#include <sys/zfs_context.h>
#include <zfs_fletcher.h>
+#define FLETCHER_MIN_SIMD_SIZE 64
static void fletcher_4_scalar_init(fletcher_4_ctx_t *ctx);
static void fletcher_4_scalar_fini(fletcher_4_ctx_t *ctx, zio_cksum_t *zcp);
@@ -456,7 +457,7 @@ void
fletcher_4_native(const void *buf, uint64_t size,
const void *ctx_template, zio_cksum_t *zcp)
{
- const uint64_t p2size = P2ALIGN(size, 64);
+ const uint64_t p2size = P2ALIGN(size, FLETCHER_MIN_SIMD_SIZE);
ASSERT(IS_P2ALIGNED(size, sizeof (uint32_t)));
@@ -498,7 +499,7 @@ void
fletcher_4_byteswap(const void *buf, uint64_t size,
const void *ctx_template, zio_cksum_t *zcp)
{
- const uint64_t p2size = P2ALIGN(size, 64);
+ const uint64_t p2size = P2ALIGN(size, FLETCHER_MIN_SIMD_SIZE);
ASSERT(IS_P2ALIGNED(size, sizeof (uint32_t)));
@@ -778,6 +779,87 @@ fletcher_4_fini(void)
}
}
+/* ABD adapters */
+
+static void
+abd_fletcher_4_init(zio_abd_checksum_data_t *cdp)
+{
+ const fletcher_4_ops_t *ops = fletcher_4_impl_get();
+ cdp->acd_private = (void *) ops;
+
+ if (cdp->acd_byteorder == ZIO_CHECKSUM_NATIVE)
+ ops->init_native(cdp->acd_ctx);
+ else
+ ops->init_byteswap(cdp->acd_ctx);
+}
+
+static void
+abd_fletcher_4_fini(zio_abd_checksum_data_t *cdp)
+{
+ fletcher_4_ops_t *ops = (fletcher_4_ops_t *)cdp->acd_private;
+
+ ASSERT(ops);
+
+ if (cdp->acd_byteorder == ZIO_CHECKSUM_NATIVE)
+ ops->fini_native(cdp->acd_ctx, cdp->acd_zcp);
+ else
+ ops->fini_byteswap(cdp->acd_ctx, cdp->acd_zcp);
+}
+
+static void
+abd_fletcher_4_simd2scalar(boolean_t native, void *data, size_t size,
+ zio_abd_checksum_data_t *cdp)
+{
+ zio_cksum_t *zcp = cdp->acd_zcp;
+
+ ASSERT3U(size, <, FLETCHER_MIN_SIMD_SIZE);
+
+ abd_fletcher_4_fini(cdp);
+ cdp->acd_private = (void *)&fletcher_4_scalar_ops;
+
+ if (native)
+ fletcher_4_incremental_native(data, size, zcp);
+ else
+ fletcher_4_incremental_byteswap(data, size, zcp);
+}
+
+static int
+abd_fletcher_4_iter(void *data, size_t size, void *private)
+{
+ zio_abd_checksum_data_t *cdp = (zio_abd_checksum_data_t *)private;
+ fletcher_4_ctx_t *ctx = cdp->acd_ctx;
+ fletcher_4_ops_t *ops = (fletcher_4_ops_t *)cdp->acd_private;
+ boolean_t native = cdp->acd_byteorder == ZIO_CHECKSUM_NATIVE;
+ uint64_t asize = P2ALIGN(size, FLETCHER_MIN_SIMD_SIZE);
+
+ ASSERT(IS_P2ALIGNED(size, sizeof (uint32_t)));
+
+ if (asize > 0) {
+ if (native)
+ ops->compute_native(ctx, data, asize);
+ else
+ ops->compute_byteswap(ctx, data, asize);
+
+ size -= asize;
+ data = (char *)data + asize;
+ }
+
+ if (size > 0) {
+ ASSERT3U(size, <, FLETCHER_MIN_SIMD_SIZE);
+ /* At this point we have to switch to scalar impl */
+ abd_fletcher_4_simd2scalar(native, data, size, cdp);
+ }
+
+ return (0);
+}
+
+zio_abd_checksum_func_t fletcher_4_abd_ops = {
+ .acf_init = abd_fletcher_4_init,
+ .acf_fini = abd_fletcher_4_fini,
+ .acf_iter = abd_fletcher_4_iter
+};
+
+
#if defined(_KERNEL) && defined(HAVE_SPL)
#include <linux/mod_compat.h>
@@ -829,4 +911,5 @@ EXPORT_SYMBOL(fletcher_4_native_varsize);
EXPORT_SYMBOL(fletcher_4_byteswap);
EXPORT_SYMBOL(fletcher_4_incremental_native);
EXPORT_SYMBOL(fletcher_4_incremental_byteswap);
+EXPORT_SYMBOL(fletcher_4_abd_ops);
#endif
diff --git a/module/zfs/zio_checksum.c b/module/zfs/zio_checksum.c
index e65b3f061..703d9a5e5 100644
--- a/module/zfs/zio_checksum.c
+++ b/module/zfs/zio_checksum.c
@@ -119,14 +119,29 @@ abd_fletcher_2_byteswap(abd_t *abd, uint64_t size,
fletcher_2_incremental_byteswap, zcp);
}
+static inline void
+abd_fletcher_4_impl(abd_t *abd, uint64_t size, zio_abd_checksum_data_t *acdp)
+{
+ fletcher_4_abd_ops.acf_init(acdp);
+ abd_iterate_func(abd, 0, size, fletcher_4_abd_ops.acf_iter, acdp);
+ fletcher_4_abd_ops.acf_fini(acdp);
+}
+
/*ARGSUSED*/
void
abd_fletcher_4_native(abd_t *abd, uint64_t size,
const void *ctx_template, zio_cksum_t *zcp)
{
- fletcher_init(zcp);
- (void) abd_iterate_func(abd, 0, size,
- fletcher_4_incremental_native, zcp);
+ fletcher_4_ctx_t ctx;
+
+ zio_abd_checksum_data_t acd = {
+ .acd_byteorder = ZIO_CHECKSUM_NATIVE,
+ .acd_zcp = zcp,
+ .acd_ctx = &ctx
+ };
+
+ abd_fletcher_4_impl(abd, size, &acd);
+
}
/*ARGSUSED*/
@@ -134,9 +149,15 @@ void
abd_fletcher_4_byteswap(abd_t *abd, uint64_t size,
const void *ctx_template, zio_cksum_t *zcp)
{
- fletcher_init(zcp);
- (void) abd_iterate_func(abd, 0, size,
- fletcher_4_incremental_byteswap, zcp);
+ fletcher_4_ctx_t ctx;
+
+ zio_abd_checksum_data_t acd = {
+ .acd_byteorder = ZIO_CHECKSUM_BYTESWAP,
+ .acd_zcp = zcp,
+ .acd_ctx = &ctx
+ };
+
+ abd_fletcher_4_impl(abd, size, &acd);
}
zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = {