1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright (C) 2018 Intel Corporation.
3 * All rights reserved.
4 */
5
6 #include "spdk/rpc.h"
7 #include "spdk/util.h"
8 #include "spdk/trace.h"
9 #include "spdk/log.h"
10 #include "trace_internal.h"
11
12 struct rpc_tpoint_group {
13 char *name;
14 uint64_t tpoint_mask;
15 };
16
17 static void
free_rpc_tpoint_group(struct rpc_tpoint_group * p)18 free_rpc_tpoint_group(struct rpc_tpoint_group *p)
19 {
20 free(p->name);
21 }
22
23 static const struct spdk_json_object_decoder rpc_tpoint_mask_decoders[] = {
24 {"name", offsetof(struct rpc_tpoint_group, name), spdk_json_decode_string},
25 {"tpoint_mask", offsetof(struct rpc_tpoint_group, tpoint_mask), spdk_json_decode_uint64, true},
26 };
27
28 static void
rpc_trace_set_tpoint_mask(struct spdk_jsonrpc_request * request,const struct spdk_json_val * params)29 rpc_trace_set_tpoint_mask(struct spdk_jsonrpc_request *request,
30 const struct spdk_json_val *params)
31 {
32 struct rpc_tpoint_group req = {};
33 uint64_t tpoint_group_mask = 0;
34
35 if (spdk_json_decode_object(params, rpc_tpoint_mask_decoders,
36 SPDK_COUNTOF(rpc_tpoint_mask_decoders), &req)) {
37 SPDK_DEBUGLOG(trace, "spdk_json_decode_object failed\n");
38 goto invalid;
39 }
40
41 if (req.name == NULL) {
42 SPDK_DEBUGLOG(trace, "flag was NULL\n");
43 goto invalid;
44 }
45
46 tpoint_group_mask = spdk_trace_create_tpoint_group_mask(req.name);
47 if (tpoint_group_mask == 0) {
48 goto invalid;
49 }
50
51 spdk_trace_set_tpoints(spdk_u64log2(tpoint_group_mask), req.tpoint_mask);
52
53 free_rpc_tpoint_group(&req);
54
55 spdk_jsonrpc_send_bool_response(request, true);
56 return;
57
58 invalid:
59 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
60 free_rpc_tpoint_group(&req);
61 }
62 SPDK_RPC_REGISTER("trace_set_tpoint_mask", rpc_trace_set_tpoint_mask,
63 SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
64
65 static void
rpc_trace_clear_tpoint_mask(struct spdk_jsonrpc_request * request,const struct spdk_json_val * params)66 rpc_trace_clear_tpoint_mask(struct spdk_jsonrpc_request *request,
67 const struct spdk_json_val *params)
68 {
69 struct rpc_tpoint_group req = {};
70 uint64_t tpoint_group_mask = 0;
71
72 if (spdk_json_decode_object(params, rpc_tpoint_mask_decoders,
73 SPDK_COUNTOF(rpc_tpoint_mask_decoders), &req)) {
74 SPDK_DEBUGLOG(trace, "spdk_json_decode_object failed\n");
75 goto invalid;
76 }
77
78 if (req.name == NULL) {
79 SPDK_DEBUGLOG(trace, "flag was NULL\n");
80 goto invalid;
81 }
82
83 tpoint_group_mask = spdk_trace_create_tpoint_group_mask(req.name);
84 if (tpoint_group_mask == 0) {
85 goto invalid;
86 }
87
88 spdk_trace_clear_tpoints(spdk_u64log2(tpoint_group_mask), req.tpoint_mask);
89
90 free_rpc_tpoint_group(&req);
91
92 spdk_jsonrpc_send_bool_response(request, true);
93 return;
94
95 invalid:
96 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
97 free_rpc_tpoint_group(&req);
98 }
99 SPDK_RPC_REGISTER("trace_clear_tpoint_mask", rpc_trace_clear_tpoint_mask,
100 SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
101
102 static const struct spdk_json_object_decoder rpc_tpoint_group_decoders[] = {
103 {"name", offsetof(struct rpc_tpoint_group, name), spdk_json_decode_string},
104 };
105
106 static void
rpc_trace_enable_tpoint_group(struct spdk_jsonrpc_request * request,const struct spdk_json_val * params)107 rpc_trace_enable_tpoint_group(struct spdk_jsonrpc_request *request,
108 const struct spdk_json_val *params)
109 {
110 struct rpc_tpoint_group req = {};
111
112 if (spdk_json_decode_object(params, rpc_tpoint_group_decoders,
113 SPDK_COUNTOF(rpc_tpoint_group_decoders), &req)) {
114 SPDK_DEBUGLOG(trace, "spdk_json_decode_object failed\n");
115 goto invalid;
116 }
117
118 if (req.name == NULL) {
119 SPDK_DEBUGLOG(trace, "flag was NULL\n");
120 goto invalid;
121 }
122
123 if (spdk_trace_enable_tpoint_group(req.name)) {
124 goto invalid;
125 }
126
127 free_rpc_tpoint_group(&req);
128
129 spdk_jsonrpc_send_bool_response(request, true);
130 return;
131
132 invalid:
133 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
134 free_rpc_tpoint_group(&req);
135 }
136 SPDK_RPC_REGISTER("trace_enable_tpoint_group", rpc_trace_enable_tpoint_group,
137 SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
138
139 static void
rpc_trace_disable_tpoint_group(struct spdk_jsonrpc_request * request,const struct spdk_json_val * params)140 rpc_trace_disable_tpoint_group(struct spdk_jsonrpc_request *request,
141 const struct spdk_json_val *params)
142 {
143 struct rpc_tpoint_group req = {};
144
145 if (spdk_json_decode_object(params, rpc_tpoint_group_decoders,
146 SPDK_COUNTOF(rpc_tpoint_group_decoders), &req)) {
147 SPDK_DEBUGLOG(trace, "spdk_json_decode_object failed\n");
148 goto invalid;
149 }
150
151 if (req.name == NULL) {
152 SPDK_DEBUGLOG(trace, "flag was NULL\n");
153 goto invalid;
154 }
155
156 if (spdk_trace_disable_tpoint_group(req.name)) {
157 goto invalid;
158 }
159
160 free_rpc_tpoint_group(&req);
161
162 spdk_jsonrpc_send_bool_response(request, true);
163 return;
164
165 invalid:
166 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
167 free_rpc_tpoint_group(&req);
168 }
169 SPDK_RPC_REGISTER("trace_disable_tpoint_group", rpc_trace_disable_tpoint_group,
170 SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
171
172 static void
rpc_trace_get_tpoint_group_mask(struct spdk_jsonrpc_request * request,const struct spdk_json_val * params)173 rpc_trace_get_tpoint_group_mask(struct spdk_jsonrpc_request *request,
174 const struct spdk_json_val *params)
175 {
176 uint64_t tpoint_group_mask;
177 char mask_str[20];
178 bool enabled;
179 struct spdk_json_write_ctx *w;
180 struct spdk_trace_register_fn *register_fn;
181
182 if (params != NULL) {
183 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
184 "trace_get_tpoint_group_mask requires no parameters");
185 return;
186 }
187
188 w = spdk_jsonrpc_begin_result(request);
189 tpoint_group_mask = spdk_trace_get_tpoint_group_mask();
190
191 spdk_json_write_object_begin(w);
192
193 snprintf(mask_str, sizeof(mask_str), "0x%" PRIx64, tpoint_group_mask);
194 spdk_json_write_named_string(w, "tpoint_group_mask", mask_str);
195
196 register_fn = spdk_trace_get_first_register_fn();
197 while (register_fn) {
198 enabled = spdk_trace_get_tpoint_mask(register_fn->tgroup_id) != 0;
199
200 spdk_json_write_named_object_begin(w, register_fn->name);
201 spdk_json_write_named_bool(w, "enabled", enabled);
202
203 snprintf(mask_str, sizeof(mask_str), "0x%lx", (1UL << register_fn->tgroup_id));
204 spdk_json_write_named_string(w, "mask", mask_str);
205 spdk_json_write_object_end(w);
206
207 register_fn = spdk_trace_get_next_register_fn(register_fn);
208 }
209
210 spdk_json_write_object_end(w);
211 spdk_jsonrpc_end_result(request, w);
212 }
213 SPDK_RPC_REGISTER("trace_get_tpoint_group_mask", rpc_trace_get_tpoint_group_mask,
214 SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
215
216 static void
rpc_trace_get_info(struct spdk_jsonrpc_request * request,const struct spdk_json_val * params)217 rpc_trace_get_info(struct spdk_jsonrpc_request *request,
218 const struct spdk_json_val *params)
219 {
220 char shm_path[128];
221 uint64_t tpoint_group_mask;
222 uint64_t tpoint_mask;
223 char tpoint_mask_str[20];
224 char mask_str[20];
225 struct spdk_json_write_ctx *w;
226 struct spdk_trace_register_fn *register_fn;
227
228 if (params != NULL) {
229 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
230 "trace_get_info requires no parameters");
231 return;
232 }
233
234 snprintf(shm_path, sizeof(shm_path), "/dev/shm%s", trace_get_shm_name());
235 tpoint_group_mask = spdk_trace_get_tpoint_group_mask();
236
237 w = spdk_jsonrpc_begin_result(request);
238 spdk_json_write_object_begin(w);
239 spdk_json_write_named_string(w, "tpoint_shm_path", shm_path);
240
241 snprintf(mask_str, sizeof(mask_str), "0x%" PRIx64, tpoint_group_mask);
242 spdk_json_write_named_string(w, "tpoint_group_mask", mask_str);
243
244 register_fn = spdk_trace_get_first_register_fn();
245 while (register_fn) {
246
247 tpoint_mask = spdk_trace_get_tpoint_mask(register_fn->tgroup_id);
248
249 spdk_json_write_named_object_begin(w, register_fn->name);
250 snprintf(mask_str, sizeof(mask_str), "0x%lx", (1UL << register_fn->tgroup_id));
251 spdk_json_write_named_string(w, "mask", mask_str);
252 snprintf(tpoint_mask_str, sizeof(tpoint_mask_str), "0x%lx", tpoint_mask);
253 spdk_json_write_named_string(w, "tpoint_mask", tpoint_mask_str);
254 spdk_json_write_object_end(w);
255
256 register_fn = spdk_trace_get_next_register_fn(register_fn);
257 }
258
259 spdk_json_write_object_end(w);
260 spdk_jsonrpc_end_result(request, w);
261 }
262 SPDK_RPC_REGISTER("trace_get_info", rpc_trace_get_info,
263 SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
264