1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
2 | /* Network filesystem support module tracepoints |
3 | * |
4 | * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved. |
5 | * Written by David Howells (dhowells@redhat.com) |
6 | */ |
7 | #undef TRACE_SYSTEM |
8 | #define TRACE_SYSTEM netfs |
9 | |
10 | #if !defined(_TRACE_NETFS_H) || defined(TRACE_HEADER_MULTI_READ) |
11 | #define _TRACE_NETFS_H |
12 | |
13 | #include <linux/tracepoint.h> |
14 | |
15 | /* |
16 | * Define enums for tracing information. |
17 | */ |
18 | #define netfs_read_traces \ |
19 | EM(netfs_read_trace_dio_read, "DIO-READ ") \ |
20 | EM(netfs_read_trace_expanded, "EXPANDED ") \ |
21 | EM(netfs_read_trace_readahead, "READAHEAD") \ |
22 | EM(netfs_read_trace_readpage, "READPAGE ") \ |
23 | EM(netfs_read_trace_prefetch_for_write, "PREFETCHW") \ |
24 | E_(netfs_read_trace_write_begin, "WRITEBEGN") |
25 | |
26 | #define netfs_write_traces \ |
27 | EM(netfs_write_trace_dio_write, "DIO-WRITE") \ |
28 | EM(netfs_write_trace_launder, "LAUNDER ") \ |
29 | EM(netfs_write_trace_unbuffered_write, "UNB-WRITE") \ |
30 | EM(netfs_write_trace_writeback, "WRITEBACK") \ |
31 | E_(netfs_write_trace_writethrough, "WRITETHRU") |
32 | |
33 | #define netfs_rreq_origins \ |
34 | EM(NETFS_READAHEAD, "RA") \ |
35 | EM(NETFS_READPAGE, "RP") \ |
36 | EM(NETFS_READ_FOR_WRITE, "RW") \ |
37 | EM(NETFS_WRITEBACK, "WB") \ |
38 | EM(NETFS_WRITETHROUGH, "WT") \ |
39 | EM(NETFS_LAUNDER_WRITE, "LW") \ |
40 | EM(NETFS_UNBUFFERED_WRITE, "UW") \ |
41 | EM(NETFS_DIO_READ, "DR") \ |
42 | E_(NETFS_DIO_WRITE, "DW") |
43 | |
44 | #define netfs_rreq_traces \ |
45 | EM(netfs_rreq_trace_assess, "ASSESS ") \ |
46 | EM(netfs_rreq_trace_copy, "COPY ") \ |
47 | EM(netfs_rreq_trace_done, "DONE ") \ |
48 | EM(netfs_rreq_trace_free, "FREE ") \ |
49 | EM(netfs_rreq_trace_redirty, "REDIRTY") \ |
50 | EM(netfs_rreq_trace_resubmit, "RESUBMT") \ |
51 | EM(netfs_rreq_trace_unlock, "UNLOCK ") \ |
52 | EM(netfs_rreq_trace_unmark, "UNMARK ") \ |
53 | EM(netfs_rreq_trace_wait_ip, "WAIT-IP") \ |
54 | EM(netfs_rreq_trace_wake_ip, "WAKE-IP") \ |
55 | E_(netfs_rreq_trace_write_done, "WR-DONE") |
56 | |
57 | #define netfs_sreq_sources \ |
58 | EM(NETFS_FILL_WITH_ZEROES, "ZERO") \ |
59 | EM(NETFS_DOWNLOAD_FROM_SERVER, "DOWN") \ |
60 | EM(NETFS_READ_FROM_CACHE, "READ") \ |
61 | EM(NETFS_INVALID_READ, "INVL") \ |
62 | EM(NETFS_UPLOAD_TO_SERVER, "UPLD") \ |
63 | EM(NETFS_WRITE_TO_CACHE, "WRIT") \ |
64 | E_(NETFS_INVALID_WRITE, "INVL") |
65 | |
66 | #define netfs_sreq_traces \ |
67 | EM(netfs_sreq_trace_download_instead, "RDOWN") \ |
68 | EM(netfs_sreq_trace_free, "FREE ") \ |
69 | EM(netfs_sreq_trace_limited, "LIMIT") \ |
70 | EM(netfs_sreq_trace_prepare, "PREP ") \ |
71 | EM(netfs_sreq_trace_resubmit_short, "SHORT") \ |
72 | EM(netfs_sreq_trace_submit, "SUBMT") \ |
73 | EM(netfs_sreq_trace_terminated, "TERM ") \ |
74 | EM(netfs_sreq_trace_write, "WRITE") \ |
75 | EM(netfs_sreq_trace_write_skip, "SKIP ") \ |
76 | E_(netfs_sreq_trace_write_term, "WTERM") |
77 | |
78 | #define netfs_failures \ |
79 | EM(netfs_fail_check_write_begin, "check-write-begin") \ |
80 | EM(netfs_fail_copy_to_cache, "copy-to-cache") \ |
81 | EM(netfs_fail_dio_read_short, "dio-read-short") \ |
82 | EM(netfs_fail_dio_read_zero, "dio-read-zero") \ |
83 | EM(netfs_fail_read, "read") \ |
84 | EM(netfs_fail_short_read, "short-read") \ |
85 | EM(netfs_fail_prepare_write, "prep-write") \ |
86 | E_(netfs_fail_write, "write") |
87 | |
88 | #define netfs_rreq_ref_traces \ |
89 | EM(netfs_rreq_trace_get_for_outstanding,"GET OUTSTND") \ |
90 | EM(netfs_rreq_trace_get_subreq, "GET SUBREQ ") \ |
91 | EM(netfs_rreq_trace_put_complete, "PUT COMPLT ") \ |
92 | EM(netfs_rreq_trace_put_discard, "PUT DISCARD") \ |
93 | EM(netfs_rreq_trace_put_failed, "PUT FAILED ") \ |
94 | EM(netfs_rreq_trace_put_no_submit, "PUT NO-SUBM") \ |
95 | EM(netfs_rreq_trace_put_return, "PUT RETURN ") \ |
96 | EM(netfs_rreq_trace_put_subreq, "PUT SUBREQ ") \ |
97 | EM(netfs_rreq_trace_put_work, "PUT WORK ") \ |
98 | EM(netfs_rreq_trace_see_work, "SEE WORK ") \ |
99 | E_(netfs_rreq_trace_new, "NEW ") |
100 | |
101 | #define netfs_sreq_ref_traces \ |
102 | EM(netfs_sreq_trace_get_copy_to_cache, "GET COPY2C ") \ |
103 | EM(netfs_sreq_trace_get_resubmit, "GET RESUBMIT") \ |
104 | EM(netfs_sreq_trace_get_short_read, "GET SHORTRD") \ |
105 | EM(netfs_sreq_trace_new, "NEW ") \ |
106 | EM(netfs_sreq_trace_put_clear, "PUT CLEAR ") \ |
107 | EM(netfs_sreq_trace_put_discard, "PUT DISCARD") \ |
108 | EM(netfs_sreq_trace_put_failed, "PUT FAILED ") \ |
109 | EM(netfs_sreq_trace_put_merged, "PUT MERGED ") \ |
110 | EM(netfs_sreq_trace_put_no_copy, "PUT NO COPY") \ |
111 | EM(netfs_sreq_trace_put_wip, "PUT WIP ") \ |
112 | EM(netfs_sreq_trace_put_work, "PUT WORK ") \ |
113 | E_(netfs_sreq_trace_put_terminated, "PUT TERM ") |
114 | |
115 | #define netfs_folio_traces \ |
116 | /* The first few correspond to enum netfs_how_to_modify */ \ |
117 | EM(netfs_folio_is_uptodate, "mod-uptodate") \ |
118 | EM(netfs_just_prefetch, "mod-prefetch") \ |
119 | EM(netfs_whole_folio_modify, "mod-whole-f") \ |
120 | EM(netfs_modify_and_clear, "mod-n-clear") \ |
121 | EM(netfs_streaming_write, "mod-streamw") \ |
122 | EM(netfs_streaming_write_cont, "mod-streamw+") \ |
123 | EM(netfs_flush_content, "flush") \ |
124 | EM(netfs_streaming_filled_page, "mod-streamw-f") \ |
125 | EM(netfs_streaming_cont_filled_page, "mod-streamw-f+") \ |
126 | /* The rest are for writeback */ \ |
127 | EM(netfs_folio_trace_clear, "clear") \ |
128 | EM(netfs_folio_trace_clear_s, "clear-s") \ |
129 | EM(netfs_folio_trace_clear_g, "clear-g") \ |
130 | EM(netfs_folio_trace_copy_to_cache, "copy") \ |
131 | EM(netfs_folio_trace_end_copy, "end-copy") \ |
132 | EM(netfs_folio_trace_filled_gaps, "filled-gaps") \ |
133 | EM(netfs_folio_trace_kill, "kill") \ |
134 | EM(netfs_folio_trace_launder, "launder") \ |
135 | EM(netfs_folio_trace_mkwrite, "mkwrite") \ |
136 | EM(netfs_folio_trace_mkwrite_plus, "mkwrite+") \ |
137 | EM(netfs_folio_trace_read_gaps, "read-gaps") \ |
138 | EM(netfs_folio_trace_redirty, "redirty") \ |
139 | EM(netfs_folio_trace_redirtied, "redirtied") \ |
140 | EM(netfs_folio_trace_store, "store") \ |
141 | EM(netfs_folio_trace_store_plus, "store+") \ |
142 | EM(netfs_folio_trace_wthru, "wthru") \ |
143 | E_(netfs_folio_trace_wthru_plus, "wthru+") |
144 | |
145 | #ifndef __NETFS_DECLARE_TRACE_ENUMS_ONCE_ONLY |
146 | #define __NETFS_DECLARE_TRACE_ENUMS_ONCE_ONLY |
147 | |
148 | #undef EM |
149 | #undef E_ |
150 | #define EM(a, b) a, |
151 | #define E_(a, b) a |
152 | |
153 | enum netfs_read_trace { netfs_read_traces } __mode(byte); |
154 | enum netfs_write_trace { netfs_write_traces } __mode(byte); |
155 | enum netfs_rreq_trace { netfs_rreq_traces } __mode(byte); |
156 | enum netfs_sreq_trace { netfs_sreq_traces } __mode(byte); |
157 | enum netfs_failure { netfs_failures } __mode(byte); |
158 | enum netfs_rreq_ref_trace { netfs_rreq_ref_traces } __mode(byte); |
159 | enum netfs_sreq_ref_trace { netfs_sreq_ref_traces } __mode(byte); |
160 | enum netfs_folio_trace { netfs_folio_traces } __mode(byte); |
161 | |
162 | #endif |
163 | |
164 | /* |
165 | * Export enum symbols via userspace. |
166 | */ |
167 | #undef EM |
168 | #undef E_ |
169 | #define EM(a, b) TRACE_DEFINE_ENUM(a); |
170 | #define E_(a, b) TRACE_DEFINE_ENUM(a); |
171 | |
172 | netfs_read_traces; |
173 | netfs_write_traces; |
174 | netfs_rreq_origins; |
175 | netfs_rreq_traces; |
176 | netfs_sreq_sources; |
177 | netfs_sreq_traces; |
178 | netfs_failures; |
179 | netfs_rreq_ref_traces; |
180 | netfs_sreq_ref_traces; |
181 | netfs_folio_traces; |
182 | |
183 | /* |
184 | * Now redefine the EM() and E_() macros to map the enums to the strings that |
185 | * will be printed in the output. |
186 | */ |
187 | #undef EM |
188 | #undef E_ |
189 | #define EM(a, b) { a, b }, |
190 | #define E_(a, b) { a, b } |
191 | |
192 | TRACE_EVENT(netfs_read, |
193 | TP_PROTO(struct netfs_io_request *rreq, |
194 | loff_t start, size_t len, |
195 | enum netfs_read_trace what), |
196 | |
197 | TP_ARGS(rreq, start, len, what), |
198 | |
199 | TP_STRUCT__entry( |
200 | __field(unsigned int, rreq ) |
201 | __field(unsigned int, cookie ) |
202 | __field(loff_t, start ) |
203 | __field(size_t, len ) |
204 | __field(enum netfs_read_trace, what ) |
205 | __field(unsigned int, netfs_inode ) |
206 | ), |
207 | |
208 | TP_fast_assign( |
209 | __entry->rreq = rreq->debug_id; |
210 | __entry->cookie = rreq->cache_resources.debug_id; |
211 | __entry->start = start; |
212 | __entry->len = len; |
213 | __entry->what = what; |
214 | __entry->netfs_inode = rreq->inode->i_ino; |
215 | ), |
216 | |
217 | TP_printk("R=%08x %s c=%08x ni=%x s=%llx %zx" , |
218 | __entry->rreq, |
219 | __print_symbolic(__entry->what, netfs_read_traces), |
220 | __entry->cookie, |
221 | __entry->netfs_inode, |
222 | __entry->start, __entry->len) |
223 | ); |
224 | |
225 | TRACE_EVENT(netfs_rreq, |
226 | TP_PROTO(struct netfs_io_request *rreq, |
227 | enum netfs_rreq_trace what), |
228 | |
229 | TP_ARGS(rreq, what), |
230 | |
231 | TP_STRUCT__entry( |
232 | __field(unsigned int, rreq ) |
233 | __field(unsigned int, flags ) |
234 | __field(enum netfs_io_origin, origin ) |
235 | __field(enum netfs_rreq_trace, what ) |
236 | ), |
237 | |
238 | TP_fast_assign( |
239 | __entry->rreq = rreq->debug_id; |
240 | __entry->flags = rreq->flags; |
241 | __entry->origin = rreq->origin; |
242 | __entry->what = what; |
243 | ), |
244 | |
245 | TP_printk("R=%08x %s %s f=%02x" , |
246 | __entry->rreq, |
247 | __print_symbolic(__entry->origin, netfs_rreq_origins), |
248 | __print_symbolic(__entry->what, netfs_rreq_traces), |
249 | __entry->flags) |
250 | ); |
251 | |
252 | TRACE_EVENT(netfs_sreq, |
253 | TP_PROTO(struct netfs_io_subrequest *sreq, |
254 | enum netfs_sreq_trace what), |
255 | |
256 | TP_ARGS(sreq, what), |
257 | |
258 | TP_STRUCT__entry( |
259 | __field(unsigned int, rreq ) |
260 | __field(unsigned short, index ) |
261 | __field(short, error ) |
262 | __field(unsigned short, flags ) |
263 | __field(enum netfs_io_source, source ) |
264 | __field(enum netfs_sreq_trace, what ) |
265 | __field(size_t, len ) |
266 | __field(size_t, transferred ) |
267 | __field(loff_t, start ) |
268 | ), |
269 | |
270 | TP_fast_assign( |
271 | __entry->rreq = sreq->rreq->debug_id; |
272 | __entry->index = sreq->debug_index; |
273 | __entry->error = sreq->error; |
274 | __entry->flags = sreq->flags; |
275 | __entry->source = sreq->source; |
276 | __entry->what = what; |
277 | __entry->len = sreq->len; |
278 | __entry->transferred = sreq->transferred; |
279 | __entry->start = sreq->start; |
280 | ), |
281 | |
282 | TP_printk("R=%08x[%u] %s %s f=%02x s=%llx %zx/%zx e=%d" , |
283 | __entry->rreq, __entry->index, |
284 | __print_symbolic(__entry->source, netfs_sreq_sources), |
285 | __print_symbolic(__entry->what, netfs_sreq_traces), |
286 | __entry->flags, |
287 | __entry->start, __entry->transferred, __entry->len, |
288 | __entry->error) |
289 | ); |
290 | |
291 | TRACE_EVENT(netfs_failure, |
292 | TP_PROTO(struct netfs_io_request *rreq, |
293 | struct netfs_io_subrequest *sreq, |
294 | int error, enum netfs_failure what), |
295 | |
296 | TP_ARGS(rreq, sreq, error, what), |
297 | |
298 | TP_STRUCT__entry( |
299 | __field(unsigned int, rreq ) |
300 | __field(short, index ) |
301 | __field(short, error ) |
302 | __field(unsigned short, flags ) |
303 | __field(enum netfs_io_source, source ) |
304 | __field(enum netfs_failure, what ) |
305 | __field(size_t, len ) |
306 | __field(size_t, transferred ) |
307 | __field(loff_t, start ) |
308 | ), |
309 | |
310 | TP_fast_assign( |
311 | __entry->rreq = rreq->debug_id; |
312 | __entry->index = sreq ? sreq->debug_index : -1; |
313 | __entry->error = error; |
314 | __entry->flags = sreq ? sreq->flags : 0; |
315 | __entry->source = sreq ? sreq->source : NETFS_INVALID_READ; |
316 | __entry->what = what; |
317 | __entry->len = sreq ? sreq->len : rreq->len; |
318 | __entry->transferred = sreq ? sreq->transferred : 0; |
319 | __entry->start = sreq ? sreq->start : 0; |
320 | ), |
321 | |
322 | TP_printk("R=%08x[%d] %s f=%02x s=%llx %zx/%zx %s e=%d" , |
323 | __entry->rreq, __entry->index, |
324 | __print_symbolic(__entry->source, netfs_sreq_sources), |
325 | __entry->flags, |
326 | __entry->start, __entry->transferred, __entry->len, |
327 | __print_symbolic(__entry->what, netfs_failures), |
328 | __entry->error) |
329 | ); |
330 | |
331 | TRACE_EVENT(netfs_rreq_ref, |
332 | TP_PROTO(unsigned int rreq_debug_id, int ref, |
333 | enum netfs_rreq_ref_trace what), |
334 | |
335 | TP_ARGS(rreq_debug_id, ref, what), |
336 | |
337 | TP_STRUCT__entry( |
338 | __field(unsigned int, rreq ) |
339 | __field(int, ref ) |
340 | __field(enum netfs_rreq_ref_trace, what ) |
341 | ), |
342 | |
343 | TP_fast_assign( |
344 | __entry->rreq = rreq_debug_id; |
345 | __entry->ref = ref; |
346 | __entry->what = what; |
347 | ), |
348 | |
349 | TP_printk("R=%08x %s r=%u" , |
350 | __entry->rreq, |
351 | __print_symbolic(__entry->what, netfs_rreq_ref_traces), |
352 | __entry->ref) |
353 | ); |
354 | |
355 | TRACE_EVENT(netfs_sreq_ref, |
356 | TP_PROTO(unsigned int rreq_debug_id, unsigned int subreq_debug_index, |
357 | int ref, enum netfs_sreq_ref_trace what), |
358 | |
359 | TP_ARGS(rreq_debug_id, subreq_debug_index, ref, what), |
360 | |
361 | TP_STRUCT__entry( |
362 | __field(unsigned int, rreq ) |
363 | __field(unsigned int, subreq ) |
364 | __field(int, ref ) |
365 | __field(enum netfs_sreq_ref_trace, what ) |
366 | ), |
367 | |
368 | TP_fast_assign( |
369 | __entry->rreq = rreq_debug_id; |
370 | __entry->subreq = subreq_debug_index; |
371 | __entry->ref = ref; |
372 | __entry->what = what; |
373 | ), |
374 | |
375 | TP_printk("R=%08x[%x] %s r=%u" , |
376 | __entry->rreq, |
377 | __entry->subreq, |
378 | __print_symbolic(__entry->what, netfs_sreq_ref_traces), |
379 | __entry->ref) |
380 | ); |
381 | |
382 | TRACE_EVENT(netfs_folio, |
383 | TP_PROTO(struct folio *folio, enum netfs_folio_trace why), |
384 | |
385 | TP_ARGS(folio, why), |
386 | |
387 | TP_STRUCT__entry( |
388 | __field(ino_t, ino) |
389 | __field(pgoff_t, index) |
390 | __field(unsigned int, nr) |
391 | __field(enum netfs_folio_trace, why) |
392 | ), |
393 | |
394 | TP_fast_assign( |
395 | __entry->ino = folio->mapping->host->i_ino; |
396 | __entry->why = why; |
397 | __entry->index = folio_index(folio); |
398 | __entry->nr = folio_nr_pages(folio); |
399 | ), |
400 | |
401 | TP_printk("i=%05lx ix=%05lx-%05lx %s" , |
402 | __entry->ino, __entry->index, __entry->index + __entry->nr - 1, |
403 | __print_symbolic(__entry->why, netfs_folio_traces)) |
404 | ); |
405 | |
406 | TRACE_EVENT(netfs_write_iter, |
407 | TP_PROTO(const struct kiocb *iocb, const struct iov_iter *from), |
408 | |
409 | TP_ARGS(iocb, from), |
410 | |
411 | TP_STRUCT__entry( |
412 | __field(unsigned long long, start ) |
413 | __field(size_t, len ) |
414 | __field(unsigned int, flags ) |
415 | ), |
416 | |
417 | TP_fast_assign( |
418 | __entry->start = iocb->ki_pos; |
419 | __entry->len = iov_iter_count(from); |
420 | __entry->flags = iocb->ki_flags; |
421 | ), |
422 | |
423 | TP_printk("WRITE-ITER s=%llx l=%zx f=%x" , |
424 | __entry->start, __entry->len, __entry->flags) |
425 | ); |
426 | |
427 | TRACE_EVENT(netfs_write, |
428 | TP_PROTO(const struct netfs_io_request *wreq, |
429 | enum netfs_write_trace what), |
430 | |
431 | TP_ARGS(wreq, what), |
432 | |
433 | TP_STRUCT__entry( |
434 | __field(unsigned int, wreq ) |
435 | __field(unsigned int, cookie ) |
436 | __field(enum netfs_write_trace, what ) |
437 | __field(unsigned long long, start ) |
438 | __field(size_t, len ) |
439 | ), |
440 | |
441 | TP_fast_assign( |
442 | struct netfs_inode *__ctx = netfs_inode(wreq->inode); |
443 | struct fscache_cookie *__cookie = netfs_i_cookie(__ctx); |
444 | __entry->wreq = wreq->debug_id; |
445 | __entry->cookie = __cookie ? __cookie->debug_id : 0; |
446 | __entry->what = what; |
447 | __entry->start = wreq->start; |
448 | __entry->len = wreq->len; |
449 | ), |
450 | |
451 | TP_printk("R=%08x %s c=%08x by=%llx-%llx" , |
452 | __entry->wreq, |
453 | __print_symbolic(__entry->what, netfs_write_traces), |
454 | __entry->cookie, |
455 | __entry->start, __entry->start + __entry->len - 1) |
456 | ); |
457 | |
458 | #undef EM |
459 | #undef E_ |
460 | #endif /* _TRACE_NETFS_H */ |
461 | |
462 | /* This part must be outside protection */ |
463 | #include <trace/define_trace.h> |
464 | |