xref: /spdk/test/external_code/accel/app_driver.c (revision b217432fa83bdca50a1723d18a32b9fac1a7d8f9)
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 INITIAL_PATTERN_0 0
11 #define INITIAL_PATTERN_1 1
12 #define INITIAL_PATTERN_2 2
13 #define FILL_PATTERN_1 255
14 #define FILL_PATTERN_2 111
15 #define IOVCNT 1
16 
17 struct test_ctx {
18 	char *driver_name;
19 	struct spdk_io_channel *ch;
20 	char buf1[TEST_XFER_SIZE];
21 	char buf1_bck[TEST_XFER_SIZE];
22 	char buf2[TEST_XFER_SIZE];
23 	char buf2_bck[TEST_XFER_SIZE];
24 	struct iovec iov1, iov2, iov1_bck, iov2_bck;
25 };
26 
27 static void
28 test_seq_complete_cb(void *_ctx, int status)
29 {
30 	struct test_ctx *ctx = _ctx;
31 	char expected_buf1[TEST_XFER_SIZE], expected_buf2[TEST_XFER_SIZE];
32 	char expected_buf1_bck[TEST_XFER_SIZE], expected_buf2_bck[TEST_XFER_SIZE];
33 
34 	printf("Running sequence callback\n");
35 
36 	if (status != 0) {
37 		SPDK_ERRLOG("Unexpected status code: %d", status);
38 		goto out;
39 	}
40 
41 	memset(expected_buf1, FILL_PATTERN_1, sizeof(expected_buf1));
42 	memset(expected_buf2, FILL_PATTERN_2, sizeof(expected_buf2));
43 	memset(expected_buf1_bck, 1, sizeof(expected_buf2));
44 	memset(expected_buf2_bck, 2, sizeof(expected_buf2));
45 
46 	if (memcmp(ctx->buf1, expected_buf1, TEST_XFER_SIZE) != 0 ||
47 	    memcmp(ctx->buf2, expected_buf2, TEST_XFER_SIZE) != 0 ||
48 	    memcmp(ctx->buf1_bck, expected_buf1_bck, TEST_XFER_SIZE != 0) ||
49 	    memcmp(ctx->buf2_bck, expected_buf2_bck, TEST_XFER_SIZE != 0)) {
50 		SPDK_ERRLOG("Sequence failed: buffers mismatch\n");
51 		status = 1;
52 	}
53 out:
54 	spdk_put_io_channel(ctx->ch);
55 	spdk_app_stop(status);
56 }
57 
58 static void
59 start_driver(void *_ctx)
60 {
61 	int rc = 0, completed = 0;
62 	struct test_ctx *ctx = _ctx;
63 	struct spdk_accel_sequence *seq = NULL;
64 
65 	ctx->ch = spdk_accel_get_io_channel();
66 	if (ctx->ch == NULL) {
67 		SPDK_ERRLOG("Failed to get IO channel\n");
68 		spdk_app_stop(1);
69 		return;
70 	}
71 
72 	/* Prepare buffers */
73 	memset(ctx->buf1, INITIAL_PATTERN_1, TEST_XFER_SIZE);
74 	memset(ctx->buf2, INITIAL_PATTERN_2, TEST_XFER_SIZE);
75 	memset(ctx->buf1_bck, INITIAL_PATTERN_0, TEST_XFER_SIZE);
76 	memset(ctx->buf2_bck, INITIAL_PATTERN_0, TEST_XFER_SIZE);
77 
78 	ctx->iov1.iov_base = ctx->buf1;
79 	ctx->iov1.iov_len = TEST_XFER_SIZE;
80 
81 	ctx->iov2.iov_base = ctx->buf2;
82 	ctx->iov2.iov_len = TEST_XFER_SIZE;
83 
84 	ctx->iov1_bck.iov_base = ctx->buf1_bck;
85 	ctx->iov1_bck.iov_len = TEST_XFER_SIZE;
86 
87 	ctx->iov2_bck.iov_base = ctx->buf2_bck;
88 	ctx->iov2_bck.iov_len = TEST_XFER_SIZE;
89 
90 	/* Test driver implementation. Test scenario is:
91 	 *	copy buf1 -> buf1_bck
92 	 *	fill buf1 <- FILL_PATTERN_1
93 	 *	copy buf2 -> buf2_bck
94 	 *	fill buf2 <- FILL_PATTERN_2
95 	 */
96 	rc = spdk_accel_append_copy(&seq, ctx->ch, &ctx->iov1_bck, IOVCNT, NULL, NULL,
97 				    &ctx->iov1, IOVCNT, NULL, NULL,
98 				    NULL, NULL);
99 	if (rc) {
100 		SPDK_ERRLOG("ERROR running append copy 1! exiting.\n");
101 		goto error;
102 	}
103 	rc = spdk_accel_append_fill(&seq, ctx->ch, &ctx->buf1, TEST_XFER_SIZE,
104 				    NULL, NULL, FILL_PATTERN_1,
105 				    NULL, NULL);
106 	if (rc) {
107 		SPDK_ERRLOG("ERROR running append fill 1! exiting.\n");
108 		goto error;
109 	}
110 	rc = spdk_accel_append_copy(&seq, ctx->ch, &ctx->iov2_bck, IOVCNT, NULL, NULL,
111 				    &ctx->iov2, IOVCNT, NULL, NULL,
112 				    NULL, NULL);
113 	if (rc) {
114 		SPDK_ERRLOG("ERROR running append copy 2! exiting.\n");
115 		goto error;
116 	}
117 	rc = spdk_accel_append_fill(&seq, ctx->ch, &ctx->buf2, TEST_XFER_SIZE,
118 				    NULL, NULL, FILL_PATTERN_2,
119 				    NULL, NULL);
120 	if (rc) {
121 		SPDK_ERRLOG("ERROR running append fill 2! exiting.\n");
122 		goto error;
123 	}
124 	spdk_accel_sequence_finish(seq, test_seq_complete_cb, ctx);
125 	return;
126 error:
127 	spdk_accel_sequence_abort(seq);
128 	spdk_put_io_channel(ctx->ch);
129 	spdk_app_stop(rc);
130 }
131 
132 int
133 main(int argc, char **argv)
134 {
135 	int rc;
136 	struct spdk_app_opts opts = {};
137 	struct test_ctx ctx = {};
138 
139 	spdk_app_opts_init(&opts, sizeof(opts));
140 	opts.name = "accel_external_driver";
141 	opts.rpc_addr = NULL;
142 
143 	/*
144 	 * Parse built-in SPDK command line parameters as well
145 	 * as our custom one(s).
146 	 */
147 	if ((rc = spdk_app_parse_args(argc, argv, &opts, NULL, NULL, NULL,
148 				      NULL)) != SPDK_APP_PARSE_ARGS_SUCCESS) {
149 		exit(rc);
150 	}
151 
152 	rc = spdk_app_start(&opts, start_driver, &ctx);
153 
154 	/* Gracefully close out all of the SPDK subsystems. */
155 	spdk_app_fini();
156 	return rc;
157 }
158