Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2020 Intel Corporation.
3 : : * Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES.
4 : : * All rights reserved.
5 : : */
6 : :
7 : : #include "accel_internal.h"
8 : : #include "spdk/accel_module.h"
9 : :
10 : : #include "spdk/rpc.h"
11 : : #include "spdk/util.h"
12 : : #include "spdk/event.h"
13 : : #include "spdk/stdinc.h"
14 : : #include "spdk/string.h"
15 : : #include "spdk/env.h"
16 : :
17 : : static void
18 : 41 : rpc_accel_get_opc_assignments(struct spdk_jsonrpc_request *request,
19 : : const struct spdk_json_val *params)
20 : : {
21 : : struct spdk_json_write_ctx *w;
22 : : enum spdk_accel_opcode opcode;
23 : 41 : const char *name, *module_name = NULL;
24 : : int rc;
25 : :
26 [ - + ]: 41 : if (params != NULL) {
27 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
28 : : "accel_get_opc_assignments requires no parameters");
29 : 0 : return;
30 : : }
31 : :
32 : 41 : w = spdk_jsonrpc_begin_result(request);
33 : :
34 : 41 : spdk_json_write_object_begin(w);
35 [ + + ]: 656 : for (opcode = 0; opcode < SPDK_ACCEL_OPC_LAST; opcode++) {
36 : 615 : name = spdk_accel_get_opcode_name(opcode);
37 [ + - ]: 615 : if (name != NULL) {
38 : 615 : rc = spdk_accel_get_opc_module_name(opcode, &module_name);
39 [ + - ]: 615 : if (rc == 0) {
40 : 615 : spdk_json_write_named_string(w, name, module_name);
41 : : } else {
42 : : /* This isn't fatal but throw an informational message if we
43 : : * cant get an module name right now */
44 : 0 : SPDK_NOTICELOG("FYI error (%d) getting module name.\n", rc);
45 : : }
46 : : } else {
47 : : /* this should never happen */
48 : 0 : SPDK_ERRLOG("Invalid opcode (%d)).\n", opcode);
49 : 0 : assert(0);
50 : : }
51 : : }
52 : 41 : spdk_json_write_object_end(w);
53 : :
54 : 41 : spdk_jsonrpc_end_result(request, w);
55 : : }
56 : 2852 : SPDK_RPC_REGISTER("accel_get_opc_assignments", rpc_accel_get_opc_assignments, SPDK_RPC_RUNTIME)
57 : :
58 : : static void
59 : 0 : rpc_dump_module_info(struct module_info *info)
60 : : {
61 : 0 : struct spdk_json_write_ctx *w = info->w;
62 : : const char *name;
63 : : uint32_t i;
64 : :
65 : 0 : spdk_json_write_object_begin(w);
66 : :
67 : 0 : spdk_json_write_named_string(w, "module", info->name);
68 : 0 : spdk_json_write_named_array_begin(w, "supported ops");
69 : :
70 [ # # ]: 0 : for (i = 0; i < info->num_ops; i++) {
71 : 0 : name = spdk_accel_get_opcode_name(info->ops[i]);
72 [ # # ]: 0 : if (name != NULL) {
73 : 0 : spdk_json_write_string(w, name);
74 : : } else {
75 : : /* this should never happen */
76 : 0 : SPDK_ERRLOG("Invalid opcode (%d)).\n", info->ops[i]);
77 : 0 : assert(0);
78 : : }
79 : : }
80 : :
81 : 0 : spdk_json_write_array_end(w);
82 : 0 : spdk_json_write_object_end(w);
83 : 0 : }
84 : :
85 : : static void
86 : 0 : rpc_accel_get_module_info(struct spdk_jsonrpc_request *request,
87 : : const struct spdk_json_val *params)
88 : : {
89 : 0 : struct module_info info;
90 : :
91 [ # # ]: 0 : if (params != NULL) {
92 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
93 : : "accel_get_module_info requires no parameters");
94 : 0 : return;
95 : : }
96 : :
97 : 0 : info.w = spdk_jsonrpc_begin_result(request);
98 : 0 : spdk_json_write_array_begin(info.w);
99 : :
100 : 0 : _accel_for_each_module(&info, rpc_dump_module_info);
101 : :
102 : 0 : spdk_json_write_array_end(info.w);
103 : 0 : spdk_jsonrpc_end_result(request, info.w);
104 : : }
105 : 2852 : SPDK_RPC_REGISTER("accel_get_module_info", rpc_accel_get_module_info, SPDK_RPC_RUNTIME)
106 : 2852 : SPDK_RPC_REGISTER_ALIAS_DEPRECATED(accel_get_module_info, accel_get_engine_info)
107 : :
108 : : struct rpc_accel_assign_opc {
109 : : char *opname;
110 : : char *module;
111 : : };
112 : :
113 : : static const struct spdk_json_object_decoder rpc_accel_assign_opc_decoders[] = {
114 : : {"opname", offsetof(struct rpc_accel_assign_opc, opname), spdk_json_decode_string},
115 : : {"module", offsetof(struct rpc_accel_assign_opc, module), spdk_json_decode_string},
116 : : };
117 : :
118 : : static void
119 : 89 : free_accel_assign_opc(struct rpc_accel_assign_opc *r)
120 : : {
121 : 89 : free(r->opname);
122 : 89 : free(r->module);
123 : 89 : }
124 : :
125 : : static void
126 : 89 : rpc_accel_assign_opc(struct spdk_jsonrpc_request *request,
127 : : const struct spdk_json_val *params)
128 : : {
129 : 89 : struct rpc_accel_assign_opc req = {};
130 : : const char *opcode_str;
131 : : enum spdk_accel_opcode opcode;
132 : 89 : bool found = false;
133 : : int rc;
134 : :
135 [ - + ]: 89 : if (spdk_json_decode_object(params, rpc_accel_assign_opc_decoders,
136 : : SPDK_COUNTOF(rpc_accel_assign_opc_decoders),
137 : : &req)) {
138 [ # # # # ]: 0 : SPDK_DEBUGLOG(accel, "spdk_json_decode_object failed\n");
139 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR,
140 : : "spdk_json_decode_object failed");
141 : 0 : goto cleanup;
142 : : }
143 : :
144 [ + - ]: 492 : for (opcode = 0; opcode < SPDK_ACCEL_OPC_LAST; opcode++) {
145 : 492 : opcode_str = spdk_accel_get_opcode_name(opcode);
146 [ - + ]: 492 : assert(opcode_str != NULL);
147 [ + + - + : 492 : if (strcmp(opcode_str, req.opname) == 0) {
+ + ]
148 : 89 : found = true;
149 : 89 : break;
150 : : }
151 : : }
152 : :
153 [ - + ]: 89 : if (found == false) {
154 [ # # # # ]: 0 : SPDK_DEBUGLOG(accel, "Invalid operation name\n");
155 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
156 : : "spdk_json_decode_object failed");
157 : 0 : goto cleanup;
158 : : }
159 : :
160 : 89 : rc = spdk_accel_assign_opc(opcode, req.module);
161 [ - + ]: 89 : if (rc) {
162 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
163 : : "error assigning opcode");
164 : 0 : goto cleanup;
165 : : }
166 : :
167 : 89 : SPDK_NOTICELOG("Operation %s will be assigned to module %s\n", req.opname, req.module);
168 : 89 : spdk_jsonrpc_send_bool_response(request, true);
169 : :
170 : 89 : cleanup:
171 : 89 : free_accel_assign_opc(&req);
172 : :
173 : 89 : }
174 : 2852 : SPDK_RPC_REGISTER("accel_assign_opc", rpc_accel_assign_opc, SPDK_RPC_STARTUP)
175 : :
176 : : struct rpc_accel_crypto_key_create {
177 : : struct spdk_accel_crypto_key_create_param param;
178 : : };
179 : :
180 : : static const struct spdk_json_object_decoder rpc_accel_dek_create_decoders[] = {
181 : : {"cipher", offsetof(struct rpc_accel_crypto_key_create, param.cipher), spdk_json_decode_string},
182 : : {"key", offsetof(struct rpc_accel_crypto_key_create, param.hex_key), spdk_json_decode_string},
183 : : {"key2", offsetof(struct rpc_accel_crypto_key_create, param.hex_key2), spdk_json_decode_string, true},
184 : : {"tweak_mode", offsetof(struct rpc_accel_crypto_key_create, param.tweak_mode), spdk_json_decode_string, true},
185 : : {"name", offsetof(struct rpc_accel_crypto_key_create, param.key_name), spdk_json_decode_string},
186 : : };
187 : :
188 : : static void
189 : 109 : rpc_accel_crypto_key_create(struct spdk_jsonrpc_request *request,
190 : : const struct spdk_json_val *params)
191 : : {
192 : 109 : struct rpc_accel_crypto_key_create req = {};
193 : : size_t key_size;
194 : : int rc;
195 : :
196 [ - + ]: 109 : if (spdk_json_decode_object(params, rpc_accel_dek_create_decoders,
197 : : SPDK_COUNTOF(rpc_accel_dek_create_decoders),
198 : : &req)) {
199 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR,
200 : : "spdk_json_decode_object failed");
201 : 0 : goto cleanup;
202 : : }
203 : :
204 : 109 : rc = spdk_accel_crypto_key_create(&req.param);
205 [ - + ]: 109 : if (rc) {
206 : 0 : spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
207 : : "failed to create DEK, rc %d", rc);
208 : : } else {
209 : 109 : spdk_jsonrpc_send_bool_response(request, true);
210 : : }
211 : :
212 : 109 : cleanup:
213 : 109 : free(req.param.cipher);
214 [ + - ]: 109 : if (req.param.hex_key) {
215 [ - + ]: 109 : key_size = strnlen(req.param.hex_key, SPDK_ACCEL_CRYPTO_KEY_MAX_HEX_LENGTH);
216 : 109 : spdk_memset_s(req.param.hex_key, key_size, 0, key_size);
217 : 109 : free(req.param.hex_key);
218 : : }
219 [ + + ]: 109 : if (req.param.hex_key2) {
220 [ - + ]: 54 : key_size = strnlen(req.param.hex_key2, SPDK_ACCEL_CRYPTO_KEY_MAX_HEX_LENGTH);
221 : 54 : spdk_memset_s(req.param.hex_key2, key_size, 0, key_size);
222 : 54 : free(req.param.hex_key2);
223 : : }
224 : 109 : free(req.param.tweak_mode);
225 : 109 : free(req.param.key_name);
226 : 109 : }
227 : 2852 : SPDK_RPC_REGISTER("accel_crypto_key_create", rpc_accel_crypto_key_create, SPDK_RPC_RUNTIME)
228 : :
229 : : struct rpc_accel_crypto_keys_get_ctx {
230 : : char *key_name;
231 : : };
232 : :
233 : : static const struct spdk_json_object_decoder rpc_accel_crypto_keys_get_decoders[] = {
234 : : {"key_name", offsetof(struct rpc_accel_crypto_keys_get_ctx, key_name), spdk_json_decode_string, true},
235 : : };
236 : :
237 : : static void
238 : 9 : rpc_accel_crypto_keys_get(struct spdk_jsonrpc_request *request,
239 : : const struct spdk_json_val *params)
240 : : {
241 : 9 : struct rpc_accel_crypto_keys_get_ctx req = {};
242 : 9 : struct spdk_accel_crypto_key *key = NULL;
243 : : struct spdk_json_write_ctx *w;
244 : :
245 [ + - - + ]: 9 : if (params && spdk_json_decode_object(params, rpc_accel_crypto_keys_get_decoders,
246 : : SPDK_COUNTOF(rpc_accel_crypto_keys_get_decoders),
247 : : &req)) {
248 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR,
249 : : "spdk_json_decode_object failed");
250 : 0 : free(req.key_name);
251 : 0 : return;
252 : : }
253 : :
254 [ + - ]: 9 : if (req.key_name) {
255 : 9 : key = spdk_accel_crypto_key_get(req.key_name);
256 : 9 : free(req.key_name);
257 [ - + ]: 9 : if (!key) {
258 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "key was not found\n");
259 : 0 : return;
260 : : }
261 : : }
262 : :
263 : 9 : w = spdk_jsonrpc_begin_result(request);
264 : 9 : spdk_json_write_array_begin(w);
265 : :
266 [ + - ]: 9 : if (key) {
267 : 9 : _accel_crypto_key_dump_param(w, key);
268 : : } else {
269 : 0 : _accel_crypto_keys_dump_param(w);
270 : : }
271 : :
272 : 9 : spdk_json_write_array_end(w);
273 : 9 : spdk_jsonrpc_end_result(request, w);
274 : : }
275 : 2852 : SPDK_RPC_REGISTER("accel_crypto_keys_get", rpc_accel_crypto_keys_get, SPDK_RPC_RUNTIME)
276 : :
277 : : static const struct spdk_json_object_decoder rpc_accel_crypto_key_destroy_decoders[] = {
278 : : {"key_name", offsetof(struct rpc_accel_crypto_keys_get_ctx, key_name), spdk_json_decode_string},
279 : : };
280 : :
281 : : static void
282 : 0 : rpc_accel_crypto_key_destroy(struct spdk_jsonrpc_request *request,
283 : : const struct spdk_json_val *params)
284 : : {
285 : 0 : struct rpc_accel_crypto_keys_get_ctx req = {};
286 : 0 : struct spdk_accel_crypto_key *key = NULL;
287 : : int rc;
288 : :
289 [ # # ]: 0 : if (spdk_json_decode_object(params, rpc_accel_crypto_key_destroy_decoders,
290 : : SPDK_COUNTOF(rpc_accel_crypto_key_destroy_decoders),
291 : : &req)) {
292 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR,
293 : : "spdk_json_decode_object failed");
294 : 0 : free(req.key_name);
295 : 0 : return;
296 : : }
297 : :
298 : 0 : key = spdk_accel_crypto_key_get(req.key_name);
299 [ # # ]: 0 : if (!key) {
300 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
301 : : "No key object found");
302 : 0 : free(req.key_name);
303 : 0 : return;
304 : :
305 : : }
306 : 0 : rc = spdk_accel_crypto_key_destroy(key);
307 [ # # ]: 0 : if (rc) {
308 : 0 : spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
309 : : "Failed to destroy key, rc %d\n", rc);
310 : : } else {
311 : 0 : spdk_jsonrpc_send_bool_response(request, true);
312 : : }
313 : :
314 : 0 : free(req.key_name);
315 : : }
316 : 2852 : SPDK_RPC_REGISTER("accel_crypto_key_destroy", rpc_accel_crypto_key_destroy, SPDK_RPC_RUNTIME)
317 : :
318 : : struct rpc_accel_set_driver {
319 : : char *name;
320 : : };
321 : :
322 : : static const struct spdk_json_object_decoder rpc_accel_set_driver_decoders[] = {
323 : : {"name", offsetof(struct rpc_accel_set_driver, name), spdk_json_decode_string},
324 : : };
325 : :
326 : : static void
327 : 0 : free_rpc_accel_set_driver(struct rpc_accel_set_driver *r)
328 : : {
329 : 0 : free(r->name);
330 : 0 : }
331 : :
332 : : static void
333 : 0 : rpc_accel_set_driver(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params)
334 : : {
335 : 0 : struct rpc_accel_set_driver req = {};
336 : : int rc;
337 : :
338 [ # # ]: 0 : if (spdk_json_decode_object(params, rpc_accel_set_driver_decoders,
339 : : SPDK_COUNTOF(rpc_accel_set_driver_decoders), &req)) {
340 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR,
341 : : "spdk_json_decode_object failed");
342 : 0 : return;
343 : : }
344 : :
345 : 0 : rc = spdk_accel_set_driver(req.name);
346 [ # # ]: 0 : if (rc != 0) {
347 : 0 : spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
348 : 0 : goto cleanup;
349 : : }
350 : :
351 : 0 : SPDK_NOTICELOG("Using accel driver: %s\n", req.name);
352 : 0 : spdk_jsonrpc_send_bool_response(request, true);
353 : 0 : cleanup:
354 : 0 : free_rpc_accel_set_driver(&req);
355 : : }
356 : 2852 : SPDK_RPC_REGISTER("accel_set_driver", rpc_accel_set_driver, SPDK_RPC_STARTUP)
357 : :
358 : : struct rpc_accel_opts {
359 : : uint32_t small_cache_size;
360 : : uint32_t large_cache_size;
361 : : uint32_t task_count;
362 : : uint32_t sequence_count;
363 : : uint32_t buf_count;
364 : : };
365 : :
366 : : static const struct spdk_json_object_decoder rpc_accel_set_options_decoders[] = {
367 : : {"small_cache_size", offsetof(struct rpc_accel_opts, small_cache_size), spdk_json_decode_uint32, true},
368 : : {"large_cache_size", offsetof(struct rpc_accel_opts, large_cache_size), spdk_json_decode_uint32, true},
369 : : {"task_count", offsetof(struct rpc_accel_opts, task_count), spdk_json_decode_uint32, true},
370 : : {"sequence_count", offsetof(struct rpc_accel_opts, sequence_count), spdk_json_decode_uint32, true},
371 : : {"buf_count", offsetof(struct rpc_accel_opts, buf_count), spdk_json_decode_uint32, true},
372 : : };
373 : :
374 : : static void
375 : 220 : rpc_accel_set_options(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params)
376 : : {
377 : 107 : struct rpc_accel_opts rpc_opts;
378 : 107 : struct spdk_accel_opts opts;
379 : : int rc;
380 : :
381 : : /* We can't pass spdk_accel_opts directly to spdk_json_decode_object(), because that
382 : : * structure is packed, leading to undefined behavior due to misaligned pointer access */
383 : 220 : spdk_accel_get_opts(&opts, sizeof(opts));
384 : 220 : rpc_opts.small_cache_size = opts.small_cache_size;
385 : 220 : rpc_opts.large_cache_size = opts.large_cache_size;
386 : 220 : rpc_opts.task_count = opts.task_count;
387 : 220 : rpc_opts.sequence_count = opts.sequence_count;
388 : 220 : rpc_opts.buf_count = opts.buf_count;
389 : :
390 [ - + ]: 220 : if (spdk_json_decode_object(params, rpc_accel_set_options_decoders,
391 : : SPDK_COUNTOF(rpc_accel_set_options_decoders), &rpc_opts)) {
392 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR,
393 : : "spdk_json_decode_object failed");
394 : 0 : return;
395 : : }
396 : :
397 : 220 : opts.small_cache_size = rpc_opts.small_cache_size;
398 : 220 : opts.large_cache_size = rpc_opts.large_cache_size;
399 : 220 : opts.task_count = rpc_opts.task_count;
400 : 220 : opts.sequence_count = rpc_opts.sequence_count;
401 : 220 : opts.buf_count = rpc_opts.buf_count;
402 : :
403 : 220 : rc = spdk_accel_set_opts(&opts);
404 [ - + ]: 220 : if (rc != 0) {
405 : 0 : spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
406 : 0 : return;
407 : : }
408 : :
409 : 220 : spdk_jsonrpc_send_bool_response(request, true);
410 : : }
411 : 2852 : SPDK_RPC_REGISTER("accel_set_options", rpc_accel_set_options, SPDK_RPC_STARTUP)
412 : :
413 : : static void
414 : 52 : rpc_accel_get_stats_done(struct accel_stats *stats, void *cb_arg)
415 : : {
416 : 52 : struct spdk_jsonrpc_request *request = cb_arg;
417 : : struct spdk_json_write_ctx *w;
418 : 0 : const char *module_name;
419 : : int i, rc;
420 : :
421 : 52 : w = spdk_jsonrpc_begin_result(request);
422 : 52 : spdk_json_write_object_begin(w);
423 : :
424 : 52 : spdk_json_write_named_uint64(w, "sequence_executed", stats->sequence_executed);
425 : 52 : spdk_json_write_named_uint64(w, "sequence_failed", stats->sequence_failed);
426 : 52 : spdk_json_write_named_uint64(w, "sequence_outstanding", stats->sequence_outstanding);
427 : 52 : spdk_json_write_named_array_begin(w, "operations");
428 [ + + ]: 832 : for (i = 0; i < SPDK_ACCEL_OPC_LAST; ++i) {
429 [ + + ]: 780 : if (stats->operations[i].executed + stats->operations[i].failed == 0) {
430 : 652 : continue;
431 : : }
432 : 128 : rc = spdk_accel_get_opc_module_name(i, &module_name);
433 [ - + ]: 128 : if (rc) {
434 : 0 : continue;
435 : : }
436 : 128 : spdk_json_write_object_begin(w);
437 : 128 : spdk_json_write_named_string(w, "opcode", spdk_accel_get_opcode_name(i));
438 : 128 : spdk_json_write_named_string(w, "module_name", module_name);
439 : 128 : spdk_json_write_named_uint64(w, "executed", stats->operations[i].executed);
440 : 128 : spdk_json_write_named_uint64(w, "failed", stats->operations[i].failed);
441 : 128 : spdk_json_write_named_uint64(w, "num_bytes", stats->operations[i].num_bytes);
442 : 128 : spdk_json_write_object_end(w);
443 : : }
444 : 52 : spdk_json_write_array_end(w);
445 : :
446 : 52 : spdk_json_write_named_uint64(w, "retry_task", stats->retry.task);
447 : 52 : spdk_json_write_named_uint64(w, "retry_sequence", stats->retry.sequence);
448 : 52 : spdk_json_write_named_uint64(w, "retry_iobuf", stats->retry.iobuf);
449 : 52 : spdk_json_write_named_uint64(w, "retry_bufdesc", stats->retry.bufdesc);
450 : :
451 : 52 : spdk_json_write_object_end(w);
452 : 52 : spdk_jsonrpc_end_result(request, w);
453 : 52 : }
454 : :
455 : : static void
456 : 52 : rpc_accel_get_stats(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params)
457 : : {
458 : : int rc;
459 : :
460 : 52 : rc = accel_get_stats(rpc_accel_get_stats_done, request);
461 [ - + ]: 52 : if (rc != 0) {
462 : 0 : spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
463 : : }
464 : 52 : }
465 : 2852 : SPDK_RPC_REGISTER("accel_get_stats", rpc_accel_get_stats, SPDK_RPC_RUNTIME)
|