1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) 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 11 struct rpc_tpoint_group { 12 char *name; 13 uint64_t tpoint_mask; 14 }; 15 16 static void 17 free_rpc_tpoint_group(struct rpc_tpoint_group *p) 18 { 19 free(p->name); 20 } 21 22 static const struct spdk_json_object_decoder rpc_tpoint_mask_decoders[] = { 23 {"name", offsetof(struct rpc_tpoint_group, name), spdk_json_decode_string}, 24 {"tpoint_mask", offsetof(struct rpc_tpoint_group, tpoint_mask), spdk_json_decode_uint64, true}, 25 }; 26 27 static void 28 rpc_trace_set_tpoint_mask(struct spdk_jsonrpc_request *request, 29 const struct spdk_json_val *params) 30 { 31 struct rpc_tpoint_group req = {}; 32 uint64_t tpoint_group_mask = 0; 33 34 if (spdk_json_decode_object(params, rpc_tpoint_mask_decoders, 35 SPDK_COUNTOF(rpc_tpoint_mask_decoders), &req)) { 36 SPDK_DEBUGLOG(trace, "spdk_json_decode_object failed\n"); 37 goto invalid; 38 } 39 40 if (req.name == NULL) { 41 SPDK_DEBUGLOG(trace, "flag was NULL\n"); 42 goto invalid; 43 } 44 45 tpoint_group_mask = spdk_trace_create_tpoint_group_mask(req.name); 46 if (tpoint_group_mask == 0) { 47 goto invalid; 48 } 49 50 spdk_trace_set_tpoints(spdk_u64log2(tpoint_group_mask), req.tpoint_mask); 51 52 free_rpc_tpoint_group(&req); 53 54 spdk_jsonrpc_send_bool_response(request, true); 55 return; 56 57 invalid: 58 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 59 free_rpc_tpoint_group(&req); 60 } 61 SPDK_RPC_REGISTER("trace_set_tpoint_mask", rpc_trace_set_tpoint_mask, 62 SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 63 64 static void 65 rpc_trace_clear_tpoint_mask(struct spdk_jsonrpc_request *request, 66 const struct spdk_json_val *params) 67 { 68 struct rpc_tpoint_group req = {}; 69 uint64_t tpoint_group_mask = 0; 70 71 if (spdk_json_decode_object(params, rpc_tpoint_mask_decoders, 72 SPDK_COUNTOF(rpc_tpoint_mask_decoders), &req)) { 73 SPDK_DEBUGLOG(trace, "spdk_json_decode_object failed\n"); 74 goto invalid; 75 } 76 77 if (req.name == NULL) { 78 SPDK_DEBUGLOG(trace, "flag was NULL\n"); 79 goto invalid; 80 } 81 82 tpoint_group_mask = spdk_trace_create_tpoint_group_mask(req.name); 83 if (tpoint_group_mask == 0) { 84 goto invalid; 85 } 86 87 spdk_trace_clear_tpoints(spdk_u64log2(tpoint_group_mask), req.tpoint_mask); 88 89 free_rpc_tpoint_group(&req); 90 91 spdk_jsonrpc_send_bool_response(request, true); 92 return; 93 94 invalid: 95 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 96 free_rpc_tpoint_group(&req); 97 } 98 SPDK_RPC_REGISTER("trace_clear_tpoint_mask", rpc_trace_clear_tpoint_mask, 99 SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 100 101 static const struct spdk_json_object_decoder rpc_tpoint_group_decoders[] = { 102 {"name", offsetof(struct rpc_tpoint_group, name), spdk_json_decode_string}, 103 }; 104 105 static void 106 rpc_trace_enable_tpoint_group(struct spdk_jsonrpc_request *request, 107 const struct spdk_json_val *params) 108 { 109 struct rpc_tpoint_group req = {}; 110 111 if (spdk_json_decode_object(params, rpc_tpoint_group_decoders, 112 SPDK_COUNTOF(rpc_tpoint_group_decoders), &req)) { 113 SPDK_DEBUGLOG(trace, "spdk_json_decode_object failed\n"); 114 goto invalid; 115 } 116 117 if (req.name == NULL) { 118 SPDK_DEBUGLOG(trace, "flag was NULL\n"); 119 goto invalid; 120 } 121 122 if (spdk_trace_enable_tpoint_group(req.name)) { 123 goto invalid; 124 } 125 126 free_rpc_tpoint_group(&req); 127 128 spdk_jsonrpc_send_bool_response(request, true); 129 return; 130 131 invalid: 132 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 133 free_rpc_tpoint_group(&req); 134 } 135 SPDK_RPC_REGISTER("trace_enable_tpoint_group", rpc_trace_enable_tpoint_group, 136 SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 137 138 static void 139 rpc_trace_disable_tpoint_group(struct spdk_jsonrpc_request *request, 140 const struct spdk_json_val *params) 141 { 142 struct rpc_tpoint_group req = {}; 143 144 if (spdk_json_decode_object(params, rpc_tpoint_group_decoders, 145 SPDK_COUNTOF(rpc_tpoint_group_decoders), &req)) { 146 SPDK_DEBUGLOG(trace, "spdk_json_decode_object failed\n"); 147 goto invalid; 148 } 149 150 if (req.name == NULL) { 151 SPDK_DEBUGLOG(trace, "flag was NULL\n"); 152 goto invalid; 153 } 154 155 if (spdk_trace_disable_tpoint_group(req.name)) { 156 goto invalid; 157 } 158 159 free_rpc_tpoint_group(&req); 160 161 spdk_jsonrpc_send_bool_response(request, true); 162 return; 163 164 invalid: 165 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 166 free_rpc_tpoint_group(&req); 167 } 168 SPDK_RPC_REGISTER("trace_disable_tpoint_group", rpc_trace_disable_tpoint_group, 169 SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 170 171 static void 172 rpc_trace_get_tpoint_group_mask(struct spdk_jsonrpc_request *request, 173 const struct spdk_json_val *params) 174 { 175 uint64_t tpoint_group_mask; 176 char mask_str[20]; 177 bool enabled; 178 struct spdk_json_write_ctx *w; 179 struct spdk_trace_register_fn *register_fn; 180 181 if (params != NULL) { 182 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 183 "trace_get_tpoint_group_mask requires no parameters"); 184 return; 185 } 186 187 w = spdk_jsonrpc_begin_result(request); 188 tpoint_group_mask = spdk_trace_get_tpoint_group_mask(); 189 190 spdk_json_write_object_begin(w); 191 192 snprintf(mask_str, sizeof(mask_str), "0x%" PRIx64, tpoint_group_mask); 193 spdk_json_write_named_string(w, "tpoint_group_mask", mask_str); 194 195 register_fn = spdk_trace_get_first_register_fn(); 196 while (register_fn) { 197 enabled = spdk_trace_get_tpoint_mask(register_fn->tgroup_id) != 0; 198 199 spdk_json_write_named_object_begin(w, register_fn->name); 200 spdk_json_write_named_bool(w, "enabled", enabled); 201 202 snprintf(mask_str, sizeof(mask_str), "0x%lx", (1UL << register_fn->tgroup_id)); 203 spdk_json_write_named_string(w, "mask", mask_str); 204 spdk_json_write_object_end(w); 205 206 register_fn = spdk_trace_get_next_register_fn(register_fn); 207 } 208 209 spdk_json_write_object_end(w); 210 spdk_jsonrpc_end_result(request, w); 211 } 212 SPDK_RPC_REGISTER("trace_get_tpoint_group_mask", rpc_trace_get_tpoint_group_mask, 213 SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME) 214