Commit 69c448a3 authored by Artur Paszkiewicz's avatar Artur Paszkiewicz Committed by Tomasz Zawadzki
Browse files

lib/util: add ISA-L accelerated xor generation



Signed-off-by: default avatarArtur Paszkiewicz <artur.paszkiewicz@intel.com>
Change-Id: I3ef9dadb4c68e92760c8426f0fffb7b249829e2b
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/12080


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
parent 7131bec4
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -108,6 +108,9 @@ For now we are using hard-coded PSK and only support TLS 1.3.

Added new functions: `spdk_hexlify` and `spdk_unhexlify`.

A new API `spdk_xor_gen` was added to generate XOR from multiple source buffers. It is going to be
used by `raid5f` for calculating parity.

### virtio

virtio-vhost-user no longer tries to support dynamic memory allocation.  The vhost target does

include/spdk/xor.h

0 → 100644
+42 −0
Original line number Diff line number Diff line
/*   SPDX-License-Identifier: BSD-3-Clause
 *   Copyright (c) Intel Corporation.
 *   All rights reserved.
 */

/**
 * \file
 * XOR utility functions
 */

#ifndef SPDK_XOR_H
#define SPDK_XOR_H

#include "spdk/stdinc.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * Generate XOR from multiple source buffers.
 *
 * \param dest Destination buffer.
 * \param sources Array of source buffers.
 * \param n Number of source buffers in the array.
 * \param len Length of each buffer in bytes.
 * \return 0 on success, negative error code otherwise.
 */
int spdk_xor_gen(void *dest, void **sources, uint32_t n, uint32_t len);

/**
 * Get the optimal buffer alignment for XOR functions.
 *
 * \return The alignment in bytes.
 */
size_t spdk_xor_get_optimal_alignment(void);

#ifdef __cplusplus
}
#endif

#endif /* SPDK_XOR_H */
+1 −1
Original line number Diff line number Diff line
@@ -11,7 +11,7 @@ SO_MINOR := 1

C_SRCS = base64.c bit_array.c cpuset.c crc16.c crc32.c crc32c.c crc32_ieee.c \
	 dif.c fd.c file.c hexlify.c iov.c math.c pipe.c strerror_tls.c string.c uuid.c \
	 fd_group.c zipf.c
	 fd_group.c xor.c zipf.c
LIBNAME = util
LOCAL_SYS_LIBS = -luuid

+4 −0
Original line number Diff line number Diff line
@@ -153,6 +153,10 @@
	spdk_fd_group_event_modify;
	spdk_fd_group_get_fd;

	# public functions in xor.h
	spdk_xor_gen;
	spdk_xor_get_optimal_alignment;

	# public functions in zipf.h
	spdk_zipf_create;
	spdk_zipf_free;

lib/util/xor.c

0 → 100644
+145 −0
Original line number Diff line number Diff line
/*   SPDX-License-Identifier: BSD-3-Clause
 *   Copyright (c) Intel Corporation.
 *   All rights reserved.
 */

#include "spdk/xor.h"
#include "spdk/config.h"
#include "spdk/assert.h"
#include "spdk/util.h"

/* maximum number of source buffers */
#define SPDK_XOR_MAX_SRC	256

static inline bool
is_aligned(void *ptr, size_t alignment)
{
	uintptr_t p = (uintptr_t)ptr;

	return p == SPDK_ALIGN_FLOOR(p, alignment);
}

static bool
buffers_aligned(void *dest, void **sources, uint32_t n, size_t alignment)
{
	uint32_t i;

	for (i = 0; i < n; i++) {
		if (!is_aligned(sources[i], alignment)) {
			return false;
		}
	}

	return is_aligned(dest, alignment);
}

static void
xor_gen_unaligned(void *dest, void **sources, uint32_t n, uint32_t len)
{
	uint32_t i, j;

	for (i = 0; i < len; i++) {
		uint8_t b = 0;

		for (j = 0; j < n; j++) {
			b ^= ((uint8_t *)sources[j])[i];
		}
		((uint8_t *)dest)[i] = b;
	}
}

static void
xor_gen_basic(void *dest, void **sources, uint32_t n, uint32_t len)
{
	uint32_t shift;
	uint32_t len_div, len_rem;
	uint32_t i, j;

	if (!buffers_aligned(dest, sources, n, sizeof(uint64_t))) {
		xor_gen_unaligned(dest, sources, n, len);
		return;
	}

	shift = spdk_u32log2(sizeof(uint64_t));
	len_div = len >> shift;
	len_rem = len_div << shift;

	for (i = 0; i < len_div; i++) {
		uint64_t w = 0;

		for (j = 0; j < n; j++) {
			w ^= ((uint64_t *)sources[j])[i];
		}
		((uint64_t *)dest)[i] = w;
	}

	if (len_rem < len) {
		void *sources2[SPDK_XOR_MAX_SRC];

		for (j = 0; j < n; j++) {
			sources2[j] = sources[j] + len_rem;
		}

		xor_gen_unaligned(dest + len_rem, sources2, n, len - len_rem);
	}
}

#ifdef SPDK_CONFIG_ISAL
#include "isa-l/include/raid.h"

#define SPDK_XOR_BUF_ALIGN 32

static int
do_xor_gen(void *dest, void **sources, uint32_t n, uint32_t len)
{
	if (buffers_aligned(dest, sources, n, SPDK_XOR_BUF_ALIGN)) {
		void *buffers[SPDK_XOR_MAX_SRC + 1];

		if (n >= INT_MAX) {
			return -EINVAL;
		}

		memcpy(buffers, sources, n * sizeof(buffers[0]));
		buffers[n] = dest;

		if (xor_gen(n + 1, len, buffers)) {
			return -EINVAL;
		}
	} else {
		xor_gen_basic(dest, sources, n, len);
	}

	return 0;
}

#else

#define SPDK_XOR_BUF_ALIGN sizeof(uint64_t)

static inline int
do_xor_gen(void *dest, void **sources, uint32_t n, uint32_t len)
{
	xor_gen_basic(dest, sources, n, len);
	return 0;
}

#endif

int
spdk_xor_gen(void *dest, void **sources, uint32_t n, uint32_t len)
{
	if (n < 2 || n > SPDK_XOR_MAX_SRC) {
		return -EINVAL;
	}

	return do_xor_gen(dest, sources, n, len);
}

size_t
spdk_xor_get_optimal_alignment(void)
{
	return SPDK_XOR_BUF_ALIGN;
}

SPDK_STATIC_ASSERT(SPDK_XOR_BUF_ALIGN > 0 && !(SPDK_XOR_BUF_ALIGN & (SPDK_XOR_BUF_ALIGN - 1)),
		   "Must be power of 2");
Loading