xref: /spdk/lib/accel/accel_rpc.c (revision 307b8c112ffd90a26d53dd15fad67bd9038ef526)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (c) Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #include "accel_internal.h"
7 
8 #include "spdk/rpc.h"
9 #include "spdk/util.h"
10 #include "spdk/event.h"
11 #include "spdk/stdinc.h"
12 #include "spdk/env.h"
13 
14 const char *g_opcode_strings[ACCEL_OPC_LAST] = {
15 	"copy", "fill", "dualcast", "compare", "crc32c", "copy_crc32c",
16 	"compress", "decompress"
17 };
18 
19 static int
20 _get_opc_name(enum accel_opcode opcode, const char **opcode_name)
21 {
22 	int rc = 0;
23 
24 	if (opcode < ACCEL_OPC_LAST) {
25 		*opcode_name = g_opcode_strings[opcode];
26 	} else {
27 		/* invalid opcode */
28 		rc = -EINVAL;
29 	}
30 
31 	return rc;
32 }
33 
34 static void
35 rpc_accel_get_opc_assignments(struct spdk_jsonrpc_request *request,
36 			      const struct spdk_json_val *params)
37 {
38 	struct spdk_json_write_ctx *w;
39 	enum accel_opcode opcode;
40 	const char *name, *module_name = NULL;
41 	int rc;
42 
43 	if (params != NULL) {
44 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
45 						 "accel_get_opc_assignments requires no parameters");
46 		return;
47 	}
48 
49 	w = spdk_jsonrpc_begin_result(request);
50 
51 	spdk_json_write_object_begin(w);
52 	for (opcode = 0; opcode < ACCEL_OPC_LAST; opcode++) {
53 		rc = _get_opc_name(opcode, &name);
54 		if (rc == 0) {
55 			rc = spdk_accel_get_opc_module_name(opcode, &module_name);
56 			if (rc != 0) {
57 				/* This isn't fatal but throw an informational message if we
58 				 * cant get an module name right now */
59 				SPDK_NOTICELOG("FYI error (%d) getting module name.\n", rc);
60 			}
61 			spdk_json_write_named_string(w, name, module_name);
62 		} else {
63 			/* this should never happen */
64 			SPDK_ERRLOG("Invalid opcode (%d)).\n", opcode);
65 			assert(0);
66 		}
67 	}
68 	spdk_json_write_object_end(w);
69 
70 	spdk_jsonrpc_end_result(request, w);
71 }
72 SPDK_RPC_REGISTER("accel_get_opc_assignments", rpc_accel_get_opc_assignments,
73 		  SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
74 
75 static void
76 rpc_dump_module_info(struct module_info *info)
77 {
78 	struct spdk_json_write_ctx *w = info->w;
79 	const char *name;
80 	uint32_t i;
81 	int rc;
82 
83 	spdk_json_write_object_begin(w);
84 
85 	spdk_json_write_named_string(w, "module", info->name);
86 	spdk_json_write_named_array_begin(w, "supported ops");
87 
88 	for (i = 0; i < info->num_ops; i++) {
89 		rc = _get_opc_name(i, &name);
90 		if (rc == 0) {
91 			spdk_json_write_string(w, name);
92 		} else {
93 			/* this should never happen */
94 			SPDK_ERRLOG("Invalid opcode (%d)).\n", i);
95 			assert(0);
96 		}
97 	}
98 
99 	spdk_json_write_array_end(w);
100 	spdk_json_write_object_end(w);
101 }
102 
103 static void
104 rpc_accel_get_module_info(struct spdk_jsonrpc_request *request,
105 			  const struct spdk_json_val *params)
106 {
107 	struct module_info info;
108 
109 	if (params != NULL) {
110 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
111 						 "accel_get_module_info requires no parameters");
112 		return;
113 	}
114 
115 	info.w = spdk_jsonrpc_begin_result(request);
116 	spdk_json_write_array_begin(info.w);
117 
118 	_accel_for_each_module(&info, rpc_dump_module_info);
119 
120 	spdk_json_write_array_end(info.w);
121 	spdk_jsonrpc_end_result(request, info.w);
122 }
123 SPDK_RPC_REGISTER("accel_get_module_info", rpc_accel_get_module_info,
124 		  SPDK_RPC_RUNTIME)
125 SPDK_RPC_REGISTER_ALIAS_DEPRECATED(accel_get_module_info, accel_get_engine_info)
126 
127 struct rpc_accel_assign_opc {
128 	char *opname;
129 	char *module;
130 };
131 
132 static const struct spdk_json_object_decoder rpc_accel_assign_opc_decoders[] = {
133 	{"opname", offsetof(struct rpc_accel_assign_opc, opname), spdk_json_decode_string},
134 	{"module", offsetof(struct rpc_accel_assign_opc, module), spdk_json_decode_string},
135 };
136 
137 static void
138 free_accel_assign_opc(struct rpc_accel_assign_opc *r)
139 {
140 	free(r->opname);
141 	free(r->module);
142 }
143 
144 static void
145 rpc_accel_assign_opc(struct spdk_jsonrpc_request *request,
146 		     const struct spdk_json_val *params)
147 {
148 	struct rpc_accel_assign_opc req = {};
149 	enum accel_opcode opcode;
150 	bool found = false;
151 	int rc;
152 
153 	if (spdk_json_decode_object(params, rpc_accel_assign_opc_decoders,
154 				    SPDK_COUNTOF(rpc_accel_assign_opc_decoders),
155 				    &req)) {
156 		SPDK_DEBUGLOG(accel, "spdk_json_decode_object failed\n");
157 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR,
158 						 "spdk_json_decode_object failed");
159 		goto cleanup;
160 	}
161 
162 	for (opcode = 0; opcode < ACCEL_OPC_LAST; opcode++) {
163 		if (strcmp(g_opcode_strings[opcode], req.opname) == 0) {
164 			found = true;
165 			break;
166 		}
167 	}
168 
169 	if (found == false) {
170 		SPDK_DEBUGLOG(accel, "Invalid operation name\n");
171 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
172 						 "spdk_json_decode_object failed");
173 		goto cleanup;
174 	}
175 
176 	rc = spdk_accel_assign_opc(opcode, req.module);
177 	if (rc) {
178 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
179 						 "error assigning opcode");
180 		goto cleanup;
181 	}
182 
183 	SPDK_NOTICELOG("Operation %s will be assigned to module %s\n", req.opname, req.module);
184 	spdk_jsonrpc_send_bool_response(request, true);
185 
186 cleanup:
187 	free_accel_assign_opc(&req);
188 
189 }
190 SPDK_RPC_REGISTER("accel_assign_opc", rpc_accel_assign_opc, SPDK_RPC_STARTUP)
191