]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /*- |
2 | * BSD LICENSE | |
3 | * | |
4 | * Copyright (c) Intel Corporation. | |
5 | * All rights reserved. | |
6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | |
10 | * | |
11 | * * Redistributions of source code must retain the above copyright | |
12 | * notice, this list of conditions and the following disclaimer. | |
13 | * * Redistributions in binary form must reproduce the above copyright | |
14 | * notice, this list of conditions and the following disclaimer in | |
15 | * the documentation and/or other materials provided with the | |
16 | * distribution. | |
17 | * * Neither the name of Intel Corporation nor the names of its | |
18 | * contributors may be used to endorse or promote products derived | |
19 | * from this software without specific prior written permission. | |
20 | * | |
21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
24 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
25 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
27 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
32 | */ | |
33 | ||
34 | /** | |
35 | * \file | |
36 | * Tracepoint library | |
37 | */ | |
38 | ||
39 | #ifndef _SPDK_TRACE_H_ | |
40 | #define _SPDK_TRACE_H_ | |
41 | ||
11fdf7f2 | 42 | #include "spdk/stdinc.h" |
7c673cae FG |
43 | |
44 | #ifdef __cplusplus | |
45 | extern "C" { | |
46 | #endif | |
47 | ||
9f95a23c | 48 | #define SPDK_DEFAULT_NUM_TRACE_ENTRIES (32 * 1024) |
7c673cae FG |
49 | |
50 | struct spdk_trace_entry { | |
51 | uint64_t tsc; | |
52 | uint16_t tpoint_id; | |
53 | uint16_t poller_id; | |
54 | uint32_t size; | |
55 | uint64_t object_id; | |
56 | uint64_t arg1; | |
57 | }; | |
58 | ||
59 | /* If type changes from a uint8_t, change this value. */ | |
60 | #define SPDK_TRACE_MAX_OWNER (UCHAR_MAX + 1) | |
61 | ||
62 | struct spdk_trace_owner { | |
63 | uint8_t type; | |
64 | char id_prefix; | |
65 | }; | |
66 | ||
67 | /* If type changes from a uint8_t, change this value. */ | |
68 | #define SPDK_TRACE_MAX_OBJECT (UCHAR_MAX + 1) | |
69 | ||
70 | struct spdk_trace_object { | |
71 | uint8_t type; | |
72 | char id_prefix; | |
73 | }; | |
74 | ||
75 | #define SPDK_TRACE_MAX_GROUP_ID 16 | |
76 | #define SPDK_TRACE_MAX_TPOINT_ID (SPDK_TRACE_MAX_GROUP_ID * 64) | |
77 | #define SPDK_TPOINT_ID(group, tpoint) ((group * 64) + tpoint) | |
78 | ||
9f95a23c TL |
79 | #define SPDK_TRACE_ARG_TYPE_INT 0 |
80 | #define SPDK_TRACE_ARG_TYPE_PTR 1 | |
81 | #define SPDK_TRACE_ARG_TYPE_STR 2 | |
82 | ||
7c673cae | 83 | struct spdk_trace_tpoint { |
9f95a23c | 84 | char name[24]; |
7c673cae FG |
85 | uint16_t tpoint_id; |
86 | uint8_t owner_type; | |
87 | uint8_t object_type; | |
88 | uint8_t new_object; | |
9f95a23c | 89 | uint8_t arg1_type; |
11fdf7f2 | 90 | uint8_t reserved; |
7c673cae FG |
91 | char arg1_name[8]; |
92 | }; | |
93 | ||
94 | struct spdk_trace_history { | |
95 | /** Logical core number associated with this structure instance. */ | |
96 | int lcore; | |
97 | ||
9f95a23c TL |
98 | /** Number of trace_entries contained in each trace_history. */ |
99 | uint64_t num_entries; | |
7c673cae FG |
100 | |
101 | /** | |
102 | * Running count of number of occurrences of each tracepoint on this | |
103 | * lcore. Debug tools can use this to easily count tracepoints such as | |
104 | * number of SCSI tasks completed or PDUs read. | |
105 | */ | |
106 | uint64_t tpoint_count[SPDK_TRACE_MAX_TPOINT_ID]; | |
107 | ||
9f95a23c TL |
108 | /** Index to next spdk_trace_entry to fill. */ |
109 | uint64_t next_entry; | |
7c673cae | 110 | |
9f95a23c TL |
111 | /** |
112 | * Circular buffer of spdk_trace_entry structures for tracing | |
113 | * tpoints on this core. Debug tool spdk_trace reads this | |
114 | * buffer from shared memory to post-process the tpoint entries and | |
115 | * display in a human-readable format. | |
116 | */ | |
117 | struct spdk_trace_entry entries[0]; | |
7c673cae FG |
118 | }; |
119 | ||
120 | #define SPDK_TRACE_MAX_LCORE 128 | |
121 | ||
11fdf7f2 | 122 | struct spdk_trace_flags { |
7c673cae FG |
123 | uint64_t tsc_rate; |
124 | uint64_t tpoint_mask[SPDK_TRACE_MAX_GROUP_ID]; | |
7c673cae FG |
125 | struct spdk_trace_owner owner[UCHAR_MAX + 1]; |
126 | struct spdk_trace_object object[UCHAR_MAX + 1]; | |
127 | struct spdk_trace_tpoint tpoint[SPDK_TRACE_MAX_TPOINT_ID]; | |
9f95a23c TL |
128 | |
129 | /** Offset of each trace_history from the beginning of this data structure. | |
130 | * The last one is the offset of the file end. | |
131 | */ | |
132 | uint64_t lcore_history_offsets[SPDK_TRACE_MAX_LCORE + 1]; | |
7c673cae | 133 | }; |
11fdf7f2 TL |
134 | extern struct spdk_trace_flags *g_trace_flags; |
135 | extern struct spdk_trace_histories *g_trace_histories; | |
136 | ||
137 | ||
138 | struct spdk_trace_histories { | |
139 | struct spdk_trace_flags flags; | |
9f95a23c TL |
140 | |
141 | /** | |
142 | * struct spdk_trace_history has a dynamic size determined by num_entries | |
143 | * in spdk_trace_init. Mark array size of per_lcore_history to be 0 in uint8_t | |
144 | * as a reminder that each per_lcore_history pointer should be gotten by | |
145 | * proper API, instead of directly referencing by struct element. | |
146 | */ | |
147 | uint8_t per_lcore_history[0]; | |
11fdf7f2 | 148 | }; |
7c673cae | 149 | |
9f95a23c TL |
150 | static inline uint64_t |
151 | spdk_get_trace_history_size(uint64_t num_entries) | |
152 | { | |
153 | return sizeof(struct spdk_trace_history) + num_entries * sizeof(struct spdk_trace_entry); | |
154 | } | |
155 | ||
156 | static inline uint64_t | |
157 | spdk_get_trace_histories_size(struct spdk_trace_histories *trace_histories) | |
158 | { | |
159 | return trace_histories->flags.lcore_history_offsets[SPDK_TRACE_MAX_LCORE]; | |
160 | } | |
161 | ||
162 | static inline struct spdk_trace_history * | |
163 | spdk_get_per_lcore_history(struct spdk_trace_histories *trace_histories, unsigned lcore) | |
164 | { | |
165 | char *lcore_history_offset; | |
166 | ||
167 | if (lcore >= SPDK_TRACE_MAX_LCORE) { | |
168 | return NULL; | |
169 | } | |
170 | ||
171 | lcore_history_offset = (char *)trace_histories; | |
172 | lcore_history_offset += trace_histories->flags.lcore_history_offsets[lcore]; | |
173 | ||
174 | return (struct spdk_trace_history *)lcore_history_offset; | |
175 | } | |
176 | ||
11fdf7f2 TL |
177 | void _spdk_trace_record(uint64_t tsc, uint16_t tpoint_id, uint16_t poller_id, |
178 | uint32_t size, uint64_t object_id, uint64_t arg1); | |
7c673cae | 179 | |
11fdf7f2 TL |
180 | /** |
181 | * Record the current trace state for tracing tpoints. Debug tool can read the | |
182 | * information from shared memory to post-process the tpoint entries and display | |
183 | * in a human-readable format. This function will call spdk_get_ticks() to get | |
184 | * the current tsc to save in the tracepoint. | |
185 | * | |
186 | * \param tpoint_id Tracepoint id to record. | |
187 | * \param poller_id Poller id to record. | |
188 | * \param size Size to record. | |
189 | * \param object_id Object id to record. | |
190 | * \param arg1 Argument to record. | |
191 | */ | |
192 | static inline | |
7c673cae | 193 | void spdk_trace_record(uint16_t tpoint_id, uint16_t poller_id, uint32_t size, |
11fdf7f2 TL |
194 | uint64_t object_id, uint64_t arg1) |
195 | { | |
196 | /* | |
197 | * Tracepoint group ID is encoded in the tpoint_id. Lower 6 bits determine the tracepoint | |
198 | * within the group, the remaining upper bits determine the tracepoint group. Each | |
199 | * tracepoint group has its own tracepoint mask. | |
200 | */ | |
9f95a23c | 201 | assert(tpoint_id < SPDK_TRACE_MAX_TPOINT_ID); |
11fdf7f2 TL |
202 | if (g_trace_histories == NULL || |
203 | !((1ULL << (tpoint_id & 0x3F)) & g_trace_histories->flags.tpoint_mask[tpoint_id >> 6])) { | |
204 | return; | |
205 | } | |
206 | ||
207 | _spdk_trace_record(0, tpoint_id, poller_id, size, object_id, arg1); | |
208 | } | |
209 | ||
210 | /** | |
211 | * Record the current trace state for tracing tpoints. Debug tool can read the | |
212 | * information from shared memory to post-process the tpoint entries and display | |
213 | * in a human-readable format. | |
214 | * | |
215 | * \param tsc Current tsc. | |
216 | * \param tpoint_id Tracepoint id to record. | |
217 | * \param poller_id Poller id to record. | |
218 | * \param size Size to record. | |
219 | * \param object_id Object id to record. | |
220 | * \param arg1 Argument to record. | |
221 | */ | |
222 | static inline | |
223 | void spdk_trace_record_tsc(uint64_t tsc, uint16_t tpoint_id, uint16_t poller_id, | |
224 | uint32_t size, uint64_t object_id, uint64_t arg1) | |
225 | { | |
226 | /* | |
227 | * Tracepoint group ID is encoded in the tpoint_id. Lower 6 bits determine the tracepoint | |
228 | * within the group, the remaining upper bits determine the tracepoint group. Each | |
229 | * tracepoint group has its own tracepoint mask. | |
230 | */ | |
9f95a23c | 231 | assert(tpoint_id < SPDK_TRACE_MAX_TPOINT_ID); |
11fdf7f2 TL |
232 | if (g_trace_histories == NULL || |
233 | !((1ULL << (tpoint_id & 0x3F)) & g_trace_histories->flags.tpoint_mask[tpoint_id >> 6])) { | |
234 | return; | |
235 | } | |
236 | ||
237 | _spdk_trace_record(tsc, tpoint_id, poller_id, size, object_id, arg1); | |
238 | } | |
7c673cae | 239 | |
11fdf7f2 TL |
240 | /** |
241 | * Get the current tpoint mask of the given tpoint group. | |
242 | * | |
243 | * \param group_id Tpoint group id associated with the tpoint mask. | |
244 | * | |
245 | * \return current tpoint mask. | |
246 | */ | |
7c673cae FG |
247 | uint64_t spdk_trace_get_tpoint_mask(uint32_t group_id); |
248 | ||
11fdf7f2 TL |
249 | /** |
250 | * Add the specified tpoints to the current tpoint mask for the given tpoint group. | |
251 | * | |
252 | * \param group_id Tpoint group id associated with the tpoint mask. | |
253 | * \param tpoint_mask Tpoint mask which indicates which tpoints to add to the | |
254 | * current tpoint mask. | |
255 | */ | |
7c673cae FG |
256 | void spdk_trace_set_tpoints(uint32_t group_id, uint64_t tpoint_mask); |
257 | ||
11fdf7f2 TL |
258 | /** |
259 | * Clear the specified tpoints from the current tpoint mask for the given tpoint group. | |
260 | * | |
261 | * \param group_id Tpoint group id associated with the tpoint mask. | |
262 | * \param tpoint_mask Tpoint mask which indicates which tpoints to clear from | |
263 | * the current tpoint mask. | |
264 | */ | |
7c673cae FG |
265 | void spdk_trace_clear_tpoints(uint32_t group_id, uint64_t tpoint_mask); |
266 | ||
11fdf7f2 TL |
267 | /** |
268 | * Get a mask of all tracepoint groups which have at least one tracepoint enabled. | |
269 | * | |
270 | * \return a mask of all tracepoint groups. | |
271 | */ | |
7c673cae FG |
272 | uint64_t spdk_trace_get_tpoint_group_mask(void); |
273 | ||
11fdf7f2 TL |
274 | /** |
275 | * For each tpoint group specified in the group mask, enable all of its tpoints. | |
276 | * | |
277 | * \param tpoint_group_mask Tpoint group mask that indicates which tpoints to enable. | |
278 | */ | |
7c673cae FG |
279 | void spdk_trace_set_tpoint_group_mask(uint64_t tpoint_group_mask); |
280 | ||
9f95a23c TL |
281 | /** |
282 | * For each tpoint group specified in the group mask, disable all of its tpoints. | |
283 | * | |
284 | * \param tpoint_group_mask Tpoint group mask that indicates which tpoints to disable. | |
285 | */ | |
286 | void spdk_trace_clear_tpoint_group_mask(uint64_t tpoint_group_mask); | |
287 | ||
11fdf7f2 TL |
288 | /** |
289 | * Initialize the trace environment. Debug tool can read the information from | |
290 | * the given shared memory to post-process the tpoint entries and display in a | |
291 | * human-readable format. | |
292 | * | |
293 | * \param shm_name Name of shared memory. | |
9f95a23c | 294 | * \param num_entries Number of trace entries per lcore. |
11fdf7f2 TL |
295 | * \return 0 on success, else non-zero indicates a failure. |
296 | */ | |
9f95a23c | 297 | int spdk_trace_init(const char *shm_name, uint64_t num_entries); |
11fdf7f2 TL |
298 | |
299 | /** | |
300 | * Unmap global trace memory structs. | |
301 | */ | |
7c673cae FG |
302 | void spdk_trace_cleanup(void); |
303 | ||
11fdf7f2 TL |
304 | /** |
305 | * Initialize trace flags. | |
306 | */ | |
307 | void spdk_trace_flags_init(void); | |
308 | ||
7c673cae FG |
309 | #define OWNER_NONE 0 |
310 | #define OBJECT_NONE 0 | |
311 | ||
11fdf7f2 TL |
312 | /** |
313 | * Register the trace owner. | |
314 | * | |
315 | * \param type Type of the trace owner. | |
316 | * \param id_prefix Prefix of id for the trace owner. | |
317 | */ | |
7c673cae | 318 | void spdk_trace_register_owner(uint8_t type, char id_prefix); |
11fdf7f2 TL |
319 | |
320 | /** | |
321 | * Register the trace object. | |
322 | * | |
323 | * \param type Type of the trace object. | |
324 | * \param id_prefix Prefix of id for the trace object. | |
325 | */ | |
7c673cae | 326 | void spdk_trace_register_object(uint8_t type, char id_prefix); |
11fdf7f2 TL |
327 | |
328 | /** | |
329 | * Register the description for the tpoint. | |
330 | * | |
331 | * \param name Name for the tpoint. | |
11fdf7f2 TL |
332 | * \param tpoint_id Id for the tpoint. |
333 | * \param owner_type Owner type for the tpoint. | |
334 | * \param object_type Object type for the tpoint. | |
335 | * \param new_object New object for the tpoint. | |
9f95a23c | 336 | * \param arg1_type Type of arg1. |
11fdf7f2 TL |
337 | * \param arg1_name Name of argument. |
338 | */ | |
9f95a23c | 339 | void spdk_trace_register_description(const char *name, uint16_t tpoint_id, uint8_t owner_type, |
7c673cae | 340 | uint8_t object_type, uint8_t new_object, |
9f95a23c TL |
341 | uint8_t arg1_type, const char *arg1_name); |
342 | ||
343 | struct spdk_trace_register_fn *spdk_trace_get_first_register_fn(void); | |
344 | ||
345 | struct spdk_trace_register_fn *spdk_trace_get_next_register_fn(struct spdk_trace_register_fn | |
346 | *register_fn); | |
347 | ||
348 | /** | |
349 | * Enable trace on specific tpoint group | |
350 | * | |
351 | * \param group_name Name of group to enable, "all" for enabling all groups. | |
352 | * \return 0 on success, else non-zero indicates a failure. | |
353 | */ | |
354 | int spdk_trace_enable_tpoint_group(const char *group_name); | |
355 | ||
356 | /** | |
357 | * Disable trace on specific tpoint group | |
358 | * | |
359 | * \param group_name Name of group to disable, "all" for disabling all groups. | |
360 | * \return 0 on success, else non-zero indicates a failure. | |
361 | */ | |
362 | int spdk_trace_disable_tpoint_group(const char *group_name); | |
363 | ||
364 | /** | |
365 | * Show trace mask and its usage. | |
366 | * | |
367 | * \param f File to hold the mask's information. | |
368 | * \param tmask_arg Command line option to set the trace group mask. | |
369 | */ | |
370 | void spdk_trace_mask_usage(FILE *f, const char *tmask_arg); | |
7c673cae FG |
371 | |
372 | struct spdk_trace_register_fn { | |
9f95a23c TL |
373 | const char *name; |
374 | uint8_t tgroup_id; | |
7c673cae FG |
375 | void (*reg_fn)(void); |
376 | struct spdk_trace_register_fn *next; | |
377 | }; | |
378 | ||
11fdf7f2 TL |
379 | /** |
380 | * Add new trace register function. | |
381 | * | |
382 | * \param reg_fn Trace register function to add. | |
383 | */ | |
7c673cae FG |
384 | void spdk_trace_add_register_fn(struct spdk_trace_register_fn *reg_fn); |
385 | ||
9f95a23c | 386 | #define SPDK_TRACE_REGISTER_FN(fn, name_str, _tgroup_id) \ |
7c673cae FG |
387 | static void fn(void); \ |
388 | struct spdk_trace_register_fn reg_ ## fn = { \ | |
9f95a23c TL |
389 | .name = name_str, \ |
390 | .tgroup_id = _tgroup_id, \ | |
7c673cae FG |
391 | .reg_fn = fn, \ |
392 | .next = NULL, \ | |
393 | }; \ | |
394 | __attribute__((constructor)) static void _ ## fn(void) \ | |
395 | { \ | |
396 | spdk_trace_add_register_fn(®_ ## fn); \ | |
397 | } \ | |
398 | static void fn(void) | |
399 | ||
400 | #ifdef __cplusplus | |
401 | } | |
402 | #endif | |
403 | ||
404 | #endif |