Commit d58439d3 authored by Eugene Kobyak's avatar Eugene Kobyak Committed by Tomasz Zawadzki
Browse files

external_code/accel: Add external accel driver



Example implementation of accel driver. This change includes the accel driver itself and application to test it.

Change-Id: Ic4615cb45f1dc059ff5b9adf7f7a5cc29ee5f81b
Signed-off-by: default avatarEugene Kobyak <eugene.kobyak@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/20458


Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
Reviewed-by: default avatarArtur Paszkiewicz <artur.paszkiewicz@intel.com>
parent 19377d66
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -37,8 +37,10 @@ test/unit/lib/iscsi/common
test/unit/lib/json_mock

# These files are in the external_code directory which doesn't get compiled with SPDK.
test/external_code/accel/accel_module
test/external_code/accel/accel_run
test/external_code/accel/module
test/external_code/accel/driver
test/external_code/accel/app_module
test/external_code/accel/app_driver
test/external_code/hello_world/hello_bdev
test/external_code/passthru/vbdev_passthru
test/external_code/passthru/vbdev_passthru_rpc
+11 −5
Original line number Diff line number Diff line
@@ -50,11 +50,17 @@ hello_world_bdev_static: passthru_static
hello_world_no_bdev_static:
	$(MAKE) --directory=hello_world alone_static

accel_shared:
	$(MAKE) --directory=accel shared
accel_module_shared:
	$(MAKE) --directory=accel shared_module

accel_static:
	$(MAKE) --directory=accel static
accel_driver_shared:
	$(MAKE) --directory=accel shared_driver

accel_module_static:
	$(MAKE) --directory=accel static_module

accel_driver_static:
	$(MAKE) --directory=accel static_driver

passthru_shared:
	$(MAKE) --directory=passthru shared
@@ -72,4 +78,4 @@ clean:
	rm -f ./hello_world/hello_bdev
	rm -f ./passthru/libpassthru_external.*
	rm -f ./nvme/*.{so,o} ./nvme/identify
	rm -f ./accel/accel_module
	rm -f ./accel/*.{so,o} ./accel/module ./accel/driver
+19 −6
Original line number Diff line number Diff line
@@ -9,13 +9,26 @@ SYS_LIB := $(shell PKG_CONFIG_PATH="$(PKG_CONFIG_PATH)" pkg-config --libs --stat
SPDK_LIB := $(shell PKG_CONFIG_PATH="$(PKG_CONFIG_PATH)" pkg-config \
		--libs spdk_event spdk_event_accel spdk_accel spdk_env_dpdk)

shared:
	$(CC) $(COMMON_CFLAGS) -c -fPIC accel_module.c -o accel_module.o
	$(CC) $(COMMON_CFLAGS) -shared accel_module.o -o libaccel_external.so
	$(CC) $(COMMON_CFLAGS) -o accel_module accel_run.c -L. -laccel_external \
shared_module:
	$(CC) $(COMMON_CFLAGS) -c -fPIC module.c -o module.o
	$(CC) $(COMMON_CFLAGS) -shared module.o -o libaccel_external_module.so
	$(CC) $(COMMON_CFLAGS) -o module app_module.c -g -L. -laccel_external_module \
		-lspdk $(SPDK_LIB)

static:
	$(CC) $(COMMON_CFLAGS) -o accel_module accel_module.c accel_run.c -pthread \
shared_driver:
	$(CC) $(COMMON_CFLAGS) -c -fPIC module.c -o module.o
	$(CC) $(COMMON_CFLAGS) -c -fPIC driver.c -o driver.o
	$(CC) $(COMMON_CFLAGS) -shared module.o driver.o -o libaccel_external_driver.so
	$(CC) $(COMMON_CFLAGS) -o driver app_driver.c -g -L. -laccel_external_driver \
		-lspdk $(SPDK_LIB)

static_module:
	$(CC) $(COMMON_CFLAGS) -o module module.c app_module.c -pthread \
		-Wl,--whole-archive,-Bstatic $(SPDK_LIB) \
		-Wl,--no-whole-archive,-Bdynamic $(SYS_LIB)

static_driver:
	$(CC) $(COMMON_CFLAGS) -o driver module.c driver.c app_driver.c \
		-Wl,--whole-archive,-Bstatic $(SPDK_LIB) \
		-Wl,--no-whole-archive,-Bdynamic $(SYS_LIB) \
		-pthread
+156 −0
Original line number Diff line number Diff line
/*   SPDX-License-Identifier: BSD-3-Clause
 *   Copyright (C) 2023 Intel Corporation.
 *   All rights reserved.
 */

#include "spdk/event.h"
#include "spdk/accel.h"

#define TEST_XFER_SIZE 4096
#define INITIAL_PATTERN_0 0
#define INITIAL_PATTERN_1 1
#define INITIAL_PATTERN_2 2
#define FILL_PATTERN_1 255
#define FILL_PATTERN_2 111
#define IOVCNT 1

struct test_ctx {
	char *driver_name;
	struct spdk_io_channel *ch;
	char buf1[TEST_XFER_SIZE];
	char buf1_bck[TEST_XFER_SIZE];
	char buf2[TEST_XFER_SIZE];
	char buf2_bck[TEST_XFER_SIZE];
	struct iovec iov1, iov2, iov1_bck, iov2_bck;
};

static void
test_seq_complete_cb(void *_ctx, int status)
{
	struct test_ctx *ctx = _ctx;
	char expected_buf1[TEST_XFER_SIZE], expected_buf2[TEST_XFER_SIZE];
	char expected_buf1_bck[TEST_XFER_SIZE], expected_buf2_bck[TEST_XFER_SIZE];

	printf("Running sequence callback\n");

	if (status != 0) {
		SPDK_ERRLOG("Unexpected status code: %d", status);
		goto out;
	}

	memset(expected_buf1, FILL_PATTERN_1, sizeof(expected_buf1));
	memset(expected_buf2, FILL_PATTERN_2, sizeof(expected_buf2));
	memset(expected_buf1_bck, 1, sizeof(expected_buf2));
	memset(expected_buf2_bck, 2, sizeof(expected_buf2));

	if (memcmp(ctx->buf1, expected_buf1, TEST_XFER_SIZE) != 0 ||
	    memcmp(ctx->buf2, expected_buf2, TEST_XFER_SIZE) != 0 ||
	    memcmp(ctx->buf1_bck, expected_buf1_bck, TEST_XFER_SIZE != 0) ||
	    memcmp(ctx->buf2_bck, expected_buf2_bck, TEST_XFER_SIZE != 0)) {
		SPDK_ERRLOG("Sequence failed: buffers mismatch\n");
		status = 1;
	}
out:
	spdk_put_io_channel(ctx->ch);
	spdk_app_stop(status);
}

static void
start_driver(void *_ctx)
{
	int rc = 0, completed = 0;
	struct test_ctx *ctx = _ctx;
	struct spdk_accel_sequence *seq = NULL;

	ctx->ch = spdk_accel_get_io_channel();
	if (ctx->ch == NULL) {
		SPDK_ERRLOG("Failed to get IO channel\n");
		spdk_app_stop(1);
		return;
	}

	/* Prepare buffers */
	memset(ctx->buf1, INITIAL_PATTERN_1, TEST_XFER_SIZE);
	memset(ctx->buf2, INITIAL_PATTERN_2, TEST_XFER_SIZE);
	memset(ctx->buf1_bck, INITIAL_PATTERN_0, TEST_XFER_SIZE);
	memset(ctx->buf2_bck, INITIAL_PATTERN_0, TEST_XFER_SIZE);

	ctx->iov1.iov_base = ctx->buf1;
	ctx->iov1.iov_len = TEST_XFER_SIZE;

	ctx->iov2.iov_base = ctx->buf2;
	ctx->iov2.iov_len = TEST_XFER_SIZE;

	ctx->iov1_bck.iov_base = ctx->buf1_bck;
	ctx->iov1_bck.iov_len = TEST_XFER_SIZE;

	ctx->iov2_bck.iov_base = ctx->buf2_bck;
	ctx->iov2_bck.iov_len = TEST_XFER_SIZE;

	/* Test driver implementation. Test scenario is:
	 *	copy buf1 -> buf1_bck
	 *	fill buf1 <- FILL_PATTERN_1
	 *	copy buf2 -> buf2_bck
	 *	fill buf2 <- FILL_PATTERN_2
	 */
	rc = spdk_accel_append_copy(&seq, ctx->ch, &ctx->iov1_bck, IOVCNT, NULL, NULL,
				    &ctx->iov1, IOVCNT, NULL, NULL, 0,
				    NULL, NULL);
	if (rc) {
		SPDK_ERRLOG("ERROR running append copy 1! exiting.\n");
		goto error;
	}
	rc = spdk_accel_append_fill(&seq, ctx->ch, &ctx->buf1, TEST_XFER_SIZE,
				    NULL, NULL, FILL_PATTERN_1, 0,
				    NULL, NULL);
	if (rc) {
		SPDK_ERRLOG("ERROR running append fill 1! exiting.\n");
		goto error;
	}
	rc = spdk_accel_append_copy(&seq, ctx->ch, &ctx->iov2_bck, IOVCNT, NULL, NULL,
				    &ctx->iov2, IOVCNT, NULL, NULL, 0,
				    NULL, NULL);
	if (rc) {
		SPDK_ERRLOG("ERROR running append copy 2! exiting.\n");
		goto error;
	}
	rc = spdk_accel_append_fill(&seq, ctx->ch, &ctx->buf2, TEST_XFER_SIZE,
				    NULL, NULL, FILL_PATTERN_2, 0,
				    NULL, NULL);
	if (rc) {
		SPDK_ERRLOG("ERROR running append fill 2! exiting.\n");
		goto error;
	}
	spdk_accel_sequence_finish(seq, test_seq_complete_cb, ctx);
	return;
error:
	spdk_accel_sequence_abort(seq);
	spdk_put_io_channel(ctx->ch);
	spdk_app_stop(rc);
}

int
main(int argc, char **argv)
{
	int rc;
	struct spdk_app_opts opts = {};
	struct test_ctx ctx = {};

	spdk_app_opts_init(&opts, sizeof(opts));
	opts.name = "accel_external_driver";

	/*
	 * Parse built-in SPDK command line parameters as well
	 * as our custom one(s).
	 */
	if ((rc = spdk_app_parse_args(argc, argv, &opts, NULL, NULL, NULL,
				      NULL)) != SPDK_APP_PARSE_ARGS_SUCCESS) {
		exit(rc);
	}

	rc = spdk_app_start(&opts, start_driver, &ctx);

	/* Gracefully close out all of the SPDK subsystems. */
	spdk_app_fini();
	return rc;
}
+14 −6
Original line number Diff line number Diff line
@@ -169,17 +169,25 @@ start_accel(void *_ctx)
}

int
main(void)
main(int argc, char **argv)
{
	int rc;
	struct spdk_app_opts g_opts = {};
	struct spdk_app_opts opts = {};
	struct test_ctx ctx = {.state = TEST_STATE_FILL, .status = 0};

	spdk_app_opts_init(&g_opts, sizeof(g_opts));
	g_opts.name = "accel_external_opts";
	g_opts.reactor_mask = "0x1";
	spdk_app_opts_init(&opts, sizeof(opts));
	opts.name = "accel_external_module";

	rc = spdk_app_start(&g_opts, start_accel, &ctx);
	/*
	 * Parse built-in SPDK command line parameters as well
	 * as our custom one(s).
	 */
	if ((rc = spdk_app_parse_args(argc, argv, &opts, NULL, NULL, NULL,
				      NULL)) != SPDK_APP_PARSE_ARGS_SUCCESS) {
		exit(rc);
	}

	rc = spdk_app_start(&opts, start_accel, &ctx);

	spdk_app_fini();
	return rc;
Loading