]> granicus.if.org Git - zfs/commitdiff
Vectorized fletcher_4 must be 128-bit aligned
authorBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 28 Jun 2016 20:31:21 +0000 (13:31 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 29 Jun 2016 18:22:22 +0000 (11:22 -0700)
The fletcher_4_native() and fletcher_4_byteswap() functions may only
safely use the vectorized implementations when the buffer is 128-bit
aligned.  This is because both the AVX2 and SSE implementations process
four 32-bit words per iterations.  Fallback to the scalar implementation
which only processes a single 32-bit word for unaligned buffers.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Gvozden Neskovic <neskovic@gmail.com>
Issue #4330

module/zcommon/zfs_fletcher.c

index 2c2d01d5c2c501cba975229e03d818a6bdaf4ea0..e76c5b8a5835f896fade2bf4572b4baeb4392184 100644 (file)
@@ -334,7 +334,12 @@ fletcher_4_impl_get(void)
 void
 fletcher_4_native(const void *buf, uint64_t size, zio_cksum_t *zcp)
 {
-       const fletcher_4_ops_t *ops = fletcher_4_impl_get();
+       const fletcher_4_ops_t *ops;
+
+       if (IS_P2ALIGNED(size, 4 * sizeof (uint32_t)))
+               ops = fletcher_4_impl_get();
+       else
+               ops = &fletcher_4_scalar_ops;
 
        ops->init(zcp);
        ops->compute(buf, size, zcp);
@@ -345,7 +350,12 @@ fletcher_4_native(const void *buf, uint64_t size, zio_cksum_t *zcp)
 void
 fletcher_4_byteswap(const void *buf, uint64_t size, zio_cksum_t *zcp)
 {
-       const fletcher_4_ops_t *ops = fletcher_4_impl_get();
+       const fletcher_4_ops_t *ops;
+
+       if (IS_P2ALIGNED(size, 4 * sizeof (uint32_t)))
+               ops = fletcher_4_impl_get();
+       else
+               ops = &fletcher_4_scalar_ops;
 
        ops->init(zcp);
        ops->compute_byteswap(buf, size, zcp);