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