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