1d58439d3SEugene Kobyak /* SPDX-License-Identifier: BSD-3-Clause
2d58439d3SEugene Kobyak * Copyright (C) 2023 Intel Corporation.
3d58439d3SEugene Kobyak * All rights reserved.
4d58439d3SEugene Kobyak */
5d58439d3SEugene Kobyak
6d58439d3SEugene Kobyak #include "spdk/event.h"
7d58439d3SEugene Kobyak #include "spdk/accel.h"
8d58439d3SEugene Kobyak
9d58439d3SEugene Kobyak #define TEST_XFER_SIZE 4096
10d58439d3SEugene Kobyak #define FILL_PATTERN 255
11d58439d3SEugene Kobyak
12d58439d3SEugene Kobyak enum test_state {
13d58439d3SEugene Kobyak TEST_STATE_FILL,
14d58439d3SEugene Kobyak TEST_STATE_COPY,
15d58439d3SEugene Kobyak TEST_STATE_COMPARE,
16d58439d3SEugene Kobyak TEST_STATE_WAIT_COMPLETION,
17d58439d3SEugene Kobyak TEST_STATE_DONE
18d58439d3SEugene Kobyak };
19d58439d3SEugene Kobyak
20d58439d3SEugene Kobyak struct test_ctx {
21d58439d3SEugene Kobyak enum test_state state;
22d58439d3SEugene Kobyak int status;
23d58439d3SEugene Kobyak char buf1[TEST_XFER_SIZE];
24d58439d3SEugene Kobyak char buf2[TEST_XFER_SIZE];
25d58439d3SEugene Kobyak struct spdk_io_channel *ch;
26d58439d3SEugene Kobyak };
27d58439d3SEugene Kobyak
28d58439d3SEugene Kobyak static void
test_ctx_fail(struct test_ctx * ctx)29d58439d3SEugene Kobyak test_ctx_fail(struct test_ctx *ctx)
30d58439d3SEugene Kobyak {
31d58439d3SEugene Kobyak ctx->status = 1;
32d58439d3SEugene Kobyak ctx->state = TEST_STATE_DONE;
33d58439d3SEugene Kobyak }
34d58439d3SEugene Kobyak
35d58439d3SEugene Kobyak static void process_accel(void *);
36d58439d3SEugene Kobyak
37d58439d3SEugene Kobyak static void
fill_cb(void * arg,int status)38d58439d3SEugene Kobyak fill_cb(void *arg, int status)
39d58439d3SEugene Kobyak {
40d58439d3SEugene Kobyak struct test_ctx *ctx = arg;
41d58439d3SEugene Kobyak char expected[TEST_XFER_SIZE];
42d58439d3SEugene Kobyak
43d58439d3SEugene Kobyak printf("Running fill callback\n");
44d58439d3SEugene Kobyak if (status != 0) {
45d58439d3SEugene Kobyak test_ctx_fail(ctx);
46d58439d3SEugene Kobyak goto out;
47d58439d3SEugene Kobyak }
48d58439d3SEugene Kobyak
49d58439d3SEugene Kobyak memset(expected, FILL_PATTERN, sizeof(expected));
50d58439d3SEugene Kobyak if (memcmp(ctx->buf1, expected, TEST_XFER_SIZE) != 0) {
51d58439d3SEugene Kobyak SPDK_ERRLOG("Fill failed: buffer mismatch\n");
52d58439d3SEugene Kobyak test_ctx_fail(ctx);
53d58439d3SEugene Kobyak goto out;
54d58439d3SEugene Kobyak }
55d58439d3SEugene Kobyak
56d58439d3SEugene Kobyak ctx->state = TEST_STATE_COPY;
57d58439d3SEugene Kobyak out:
58d58439d3SEugene Kobyak process_accel(ctx);
59d58439d3SEugene Kobyak }
60d58439d3SEugene Kobyak
61d58439d3SEugene Kobyak static void
copy_cb(void * arg,int status)62d58439d3SEugene Kobyak copy_cb(void *arg, int status)
63d58439d3SEugene Kobyak {
64d58439d3SEugene Kobyak struct test_ctx *ctx = arg;
65d58439d3SEugene Kobyak
66d58439d3SEugene Kobyak printf("Running copy callback\n");
67d58439d3SEugene Kobyak if (status != 0) {
68d58439d3SEugene Kobyak test_ctx_fail(ctx);
69d58439d3SEugene Kobyak goto out;
70d58439d3SEugene Kobyak }
71d58439d3SEugene Kobyak if (memcmp(ctx->buf1, ctx->buf2, TEST_XFER_SIZE) != 0) {
72d58439d3SEugene Kobyak SPDK_ERRLOG("Copy failed: buffer mismatch\n");
73d58439d3SEugene Kobyak test_ctx_fail(ctx);
74d58439d3SEugene Kobyak goto out;
75d58439d3SEugene Kobyak }
76d58439d3SEugene Kobyak
77d58439d3SEugene Kobyak ctx->state = TEST_STATE_COMPARE;
78d58439d3SEugene Kobyak out:
79d58439d3SEugene Kobyak process_accel(ctx);
80d58439d3SEugene Kobyak }
81d58439d3SEugene Kobyak
82d58439d3SEugene Kobyak static void
compare_cb(void * arg,int status)83d58439d3SEugene Kobyak compare_cb(void *arg, int status)
84d58439d3SEugene Kobyak {
85d58439d3SEugene Kobyak struct test_ctx *ctx = arg;
86d58439d3SEugene Kobyak
87d58439d3SEugene Kobyak printf("Running compare callback\n");
88d58439d3SEugene Kobyak if (status != 0) {
89d58439d3SEugene Kobyak test_ctx_fail(ctx);
90d58439d3SEugene Kobyak goto out;
91d58439d3SEugene Kobyak }
92d58439d3SEugene Kobyak if (memcmp(ctx->buf1, ctx->buf2, TEST_XFER_SIZE) != 0) {
93d58439d3SEugene Kobyak SPDK_ERRLOG("Compare failed: buffer mismatch\n");
94d58439d3SEugene Kobyak test_ctx_fail(ctx);
95d58439d3SEugene Kobyak goto out;
96d58439d3SEugene Kobyak }
97d58439d3SEugene Kobyak
98d58439d3SEugene Kobyak ctx->state = TEST_STATE_DONE;
99d58439d3SEugene Kobyak out:
100d58439d3SEugene Kobyak process_accel(ctx);
101d58439d3SEugene Kobyak }
102d58439d3SEugene Kobyak
103d58439d3SEugene Kobyak static void
process_accel(void * _ctx)104d58439d3SEugene Kobyak process_accel(void *_ctx)
105d58439d3SEugene Kobyak {
106d58439d3SEugene Kobyak int rc;
107d58439d3SEugene Kobyak struct test_ctx *ctx = _ctx;
108d58439d3SEugene Kobyak enum test_state prev_state;
109d58439d3SEugene Kobyak
110d58439d3SEugene Kobyak do {
111d58439d3SEugene Kobyak prev_state = ctx->state;
112d58439d3SEugene Kobyak
113d58439d3SEugene Kobyak switch (ctx->state) {
114d58439d3SEugene Kobyak case TEST_STATE_FILL:
115d58439d3SEugene Kobyak memset(ctx->buf1, 0, sizeof(ctx->buf1));
116d58439d3SEugene Kobyak memset(ctx->buf2, 0, sizeof(ctx->buf2));
117d58439d3SEugene Kobyak ctx->state = TEST_STATE_WAIT_COMPLETION;
118d58439d3SEugene Kobyak /* Submit fill command */
119d58439d3SEugene Kobyak rc = spdk_accel_submit_fill(ctx->ch, ctx->buf1, FILL_PATTERN,
120*79e2a56fSKonrad Sztyber TEST_XFER_SIZE, fill_cb, ctx);
121d58439d3SEugene Kobyak if (rc) {
122d58439d3SEugene Kobyak SPDK_ERRLOG("ERROR running submit fill! exiting.\n");
123d58439d3SEugene Kobyak test_ctx_fail(ctx);
124d58439d3SEugene Kobyak }
125d58439d3SEugene Kobyak break;
126d58439d3SEugene Kobyak case TEST_STATE_COPY:
127d58439d3SEugene Kobyak ctx->state = TEST_STATE_WAIT_COMPLETION;
128d58439d3SEugene Kobyak /* Submit copy command */
129d58439d3SEugene Kobyak rc = spdk_accel_submit_copy(ctx->ch, ctx->buf1, ctx->buf2,
130*79e2a56fSKonrad Sztyber TEST_XFER_SIZE, copy_cb, ctx);
131d58439d3SEugene Kobyak if (rc) {
132d58439d3SEugene Kobyak SPDK_ERRLOG("ERROR running submit copy! exiting.\n");
133d58439d3SEugene Kobyak test_ctx_fail(ctx);
134d58439d3SEugene Kobyak }
135d58439d3SEugene Kobyak break;
136d58439d3SEugene Kobyak case TEST_STATE_COMPARE:
137d58439d3SEugene Kobyak ctx->state = TEST_STATE_WAIT_COMPLETION;
138d58439d3SEugene Kobyak /* Submit compare command */
139d58439d3SEugene Kobyak rc = spdk_accel_submit_compare(ctx->ch, ctx->buf1, ctx->buf2,
140d58439d3SEugene Kobyak TEST_XFER_SIZE, compare_cb, ctx);
141d58439d3SEugene Kobyak if (rc) {
142d58439d3SEugene Kobyak SPDK_ERRLOG("ERROR running submit compare! exiting.\n");
143d58439d3SEugene Kobyak test_ctx_fail(ctx);
144d58439d3SEugene Kobyak }
145d58439d3SEugene Kobyak break;
146d58439d3SEugene Kobyak case TEST_STATE_WAIT_COMPLETION:
147d58439d3SEugene Kobyak break;
148d58439d3SEugene Kobyak case TEST_STATE_DONE:
149d58439d3SEugene Kobyak spdk_put_io_channel(ctx->ch);
150d58439d3SEugene Kobyak spdk_app_stop(ctx->status);
151d58439d3SEugene Kobyak break;
152d58439d3SEugene Kobyak }
153d58439d3SEugene Kobyak } while (ctx->state != prev_state);
154d58439d3SEugene Kobyak }
155d58439d3SEugene Kobyak
156d58439d3SEugene Kobyak static void
start_accel(void * _ctx)157d58439d3SEugene Kobyak start_accel(void *_ctx)
158d58439d3SEugene Kobyak {
159d58439d3SEugene Kobyak struct test_ctx *ctx = _ctx;
160d58439d3SEugene Kobyak
161d58439d3SEugene Kobyak ctx->ch = spdk_accel_get_io_channel();
162d58439d3SEugene Kobyak if (ctx->ch == NULL) {
163d58439d3SEugene Kobyak SPDK_ERRLOG("Failed to get IO channel\n");
164d58439d3SEugene Kobyak spdk_app_stop(1);
165d58439d3SEugene Kobyak return;
166d58439d3SEugene Kobyak }
167d58439d3SEugene Kobyak
168d58439d3SEugene Kobyak process_accel(ctx);
169d58439d3SEugene Kobyak }
170d58439d3SEugene Kobyak
171d58439d3SEugene Kobyak int
main(int argc,char ** argv)172d58439d3SEugene Kobyak main(int argc, char **argv)
173d58439d3SEugene Kobyak {
174d58439d3SEugene Kobyak int rc;
175d58439d3SEugene Kobyak struct spdk_app_opts opts = {};
176d58439d3SEugene Kobyak struct test_ctx ctx = {.state = TEST_STATE_FILL, .status = 0};
177d58439d3SEugene Kobyak
178d58439d3SEugene Kobyak spdk_app_opts_init(&opts, sizeof(opts));
179d58439d3SEugene Kobyak opts.name = "accel_external_module";
1805db859daSKrzysztof Karas opts.rpc_addr = NULL;
181d58439d3SEugene Kobyak
182d58439d3SEugene Kobyak /*
183d58439d3SEugene Kobyak * Parse built-in SPDK command line parameters as well
184d58439d3SEugene Kobyak * as our custom one(s).
185d58439d3SEugene Kobyak */
186d58439d3SEugene Kobyak if ((rc = spdk_app_parse_args(argc, argv, &opts, NULL, NULL, NULL,
187d58439d3SEugene Kobyak NULL)) != SPDK_APP_PARSE_ARGS_SUCCESS) {
188d58439d3SEugene Kobyak exit(rc);
189d58439d3SEugene Kobyak }
190d58439d3SEugene Kobyak
191d58439d3SEugene Kobyak rc = spdk_app_start(&opts, start_accel, &ctx);
192d58439d3SEugene Kobyak
193d58439d3SEugene Kobyak spdk_app_fini();
194d58439d3SEugene Kobyak return rc;
195d58439d3SEugene Kobyak }
196