xref: /linux/kernel/trace/trace_seq.c (revision 2cddfc2e8fc78c13b0f5286ea5dd48cdf527ad41)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * trace_seq.c
4  *
5  * Copyright (C) 2008-2014 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
6  *
7  * The trace_seq is a handy tool that allows you to pass a descriptor around
8  * to a buffer that other functions can write to. It is similar to the
9  * seq_file functionality but has some differences.
10  *
11  * To use it, the trace_seq must be initialized with trace_seq_init().
12  * This will set up the counters within the descriptor. You can call
13  * trace_seq_init() more than once to reset the trace_seq to start
14  * from scratch.
15  *
16  * A write to the buffer will either succeed or fail. That is, unlike
17  * sprintf() there will not be a partial write (well it may write into
18  * the buffer but it won't update the pointers). This allows users to
19  * try to write something into the trace_seq buffer and if it fails
20  * they can flush it and try again.
21  *
22  */
23 #include <linux/uaccess.h>
24 #include <linux/seq_file.h>
25 #include <linux/trace_seq.h>
26 
27 /* How much buffer is left on the trace_seq? */
28 #define TRACE_SEQ_BUF_LEFT(s) seq_buf_buffer_left(&(s)->seq)
29 
30 /*
31  * trace_seq should work with being initialized with 0s.
32  */
33 static inline void __trace_seq_init(struct trace_seq *s)
34 {
35 	if (unlikely(!s->seq.size))
36 		trace_seq_init(s);
37 }
38 
39 /**
40  * trace_print_seq - move the contents of trace_seq into a seq_file
41  * @m: the seq_file descriptor that is the destination
42  * @s: the trace_seq descriptor that is the source.
43  *
44  * Returns 0 on success and non zero on error. If it succeeds to
45  * write to the seq_file it will reset the trace_seq, otherwise
46  * it does not modify the trace_seq to let the caller try again.
47  */
48 int trace_print_seq(struct seq_file *m, struct trace_seq *s)
49 {
50 	int ret;
51 
52 	__trace_seq_init(s);
53 
54 	ret = seq_buf_print_seq(m, &s->seq);
55 
56 	/*
57 	 * Only reset this buffer if we successfully wrote to the
58 	 * seq_file buffer. This lets the caller try again or
59 	 * do something else with the contents.
60 	 */
61 	if (!ret)
62 		trace_seq_init(s);
63 
64 	return ret;
65 }
66 
67 /**
68  * trace_seq_printf - sequence printing of trace information
69  * @s: trace sequence descriptor
70  * @fmt: printf format string
71  *
72  * The tracer may use either sequence operations or its own
73  * copy to user routines. To simplify formatting of a trace
74  * trace_seq_printf() is used to store strings into a special
75  * buffer (@s). Then the output may be either used by
76  * the sequencer or pulled into another buffer.
77  */
78 void trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
79 {
80 	unsigned int save_len = s->seq.len;
81 	va_list ap;
82 
83 	if (s->full)
84 		return;
85 
86 	__trace_seq_init(s);
87 
88 	va_start(ap, fmt);
89 	seq_buf_vprintf(&s->seq, fmt, ap);
90 	va_end(ap);
91 
92 	/* If we can't write it all, don't bother writing anything */
93 	if (unlikely(seq_buf_has_overflowed(&s->seq))) {
94 		s->seq.len = save_len;
95 		s->full = 1;
96 	}
97 }
98 EXPORT_SYMBOL_GPL(trace_seq_printf);
99 
100 /**
101  * trace_seq_bitmask - write a bitmask array in its ASCII representation
102  * @s:		trace sequence descriptor
103  * @maskp:	points to an array of unsigned longs that represent a bitmask
104  * @nmaskbits:	The number of bits that are valid in @maskp
105  *
106  * Writes a ASCII representation of a bitmask string into @s.
107  */
108 void trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp,
109 		       int nmaskbits)
110 {
111 	unsigned int save_len = s->seq.len;
112 
113 	if (s->full)
114 		return;
115 
116 	__trace_seq_init(s);
117 
118 	seq_buf_printf(&s->seq, "%*pb", nmaskbits, maskp);
119 
120 	if (unlikely(seq_buf_has_overflowed(&s->seq))) {
121 		s->seq.len = save_len;
122 		s->full = 1;
123 	}
124 }
125 EXPORT_SYMBOL_GPL(trace_seq_bitmask);
126 
127 /**
128  * trace_seq_bitmask_list - write a bitmask array in its list representation
129  * @s:		trace sequence descriptor
130  * @maskp:	points to an array of unsigned longs that represent a bitmask
131  * @nmaskbits:	The number of bits that are valid in @maskp
132  *
133  * Writes a list representation (e.g., 0-3,5-7) of a bitmask string into @s.
134  */
135 void trace_seq_bitmask_list(struct trace_seq *s, const unsigned long *maskp,
136 		       int nmaskbits)
137 {
138 	unsigned int save_len = s->seq.len;
139 
140 	if (s->full)
141 		return;
142 
143 	__trace_seq_init(s);
144 
145 	seq_buf_printf(&s->seq, "%*pbl", nmaskbits, maskp);
146 
147 	if (unlikely(seq_buf_has_overflowed(&s->seq))) {
148 		s->seq.len = save_len;
149 		s->full = 1;
150 	}
151 }
152 EXPORT_SYMBOL_GPL(trace_seq_bitmask_list);
153 
154 /**
155  * trace_seq_vprintf - sequence printing of trace information
156  * @s: trace sequence descriptor
157  * @fmt: printf format string
158  * @args: Arguments for the format string
159  *
160  * The tracer may use either sequence operations or its own
161  * copy to user routines. To simplify formatting of a trace
162  * trace_seq_printf is used to store strings into a special
163  * buffer (@s). Then the output may be either used by
164  * the sequencer or pulled into another buffer.
165  */
166 void trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args)
167 {
168 	unsigned int save_len = s->seq.len;
169 
170 	if (s->full)
171 		return;
172 
173 	__trace_seq_init(s);
174 
175 	seq_buf_vprintf(&s->seq, fmt, args);
176 
177 	/* If we can't write it all, don't bother writing anything */
178 	if (unlikely(seq_buf_has_overflowed(&s->seq))) {
179 		s->seq.len = save_len;
180 		s->full = 1;
181 	}
182 }
183 EXPORT_SYMBOL_GPL(trace_seq_vprintf);
184 
185 /**
186  * trace_seq_bprintf - Write the printf string from binary arguments
187  * @s: trace sequence descriptor
188  * @fmt: The format string for the @binary arguments
189  * @binary: The binary arguments for @fmt.
190  *
191  * When recording in a fast path, a printf may be recorded with just
192  * saving the format and the arguments as they were passed to the
193  * function, instead of wasting cycles converting the arguments into
194  * ASCII characters. Instead, the arguments are saved in a 32 bit
195  * word array that is defined by the format string constraints.
196  *
197  * This function will take the format and the binary array and finish
198  * the conversion into the ASCII string within the buffer.
199  */
200 void trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary)
201 {
202 	unsigned int save_len = s->seq.len;
203 
204 	if (s->full)
205 		return;
206 
207 	__trace_seq_init(s);
208 
209 	seq_buf_bprintf(&s->seq, fmt, binary);
210 
211 	/* If we can't write it all, don't bother writing anything */
212 	if (unlikely(seq_buf_has_overflowed(&s->seq))) {
213 		s->seq.len = save_len;
214 		s->full = 1;
215 		return;
216 	}
217 }
218 EXPORT_SYMBOL_GPL(trace_seq_bprintf);
219 
220 /**
221  * trace_seq_puts - trace sequence printing of simple string
222  * @s: trace sequence descriptor
223  * @str: simple string to record
224  *
225  * The tracer may use either the sequence operations or its own
226  * copy to user routines. This function records a simple string
227  * into a special buffer (@s) for later retrieval by a sequencer
228  * or other mechanism.
229  */
230 void trace_seq_puts(struct trace_seq *s, const char *str)
231 {
232 	unsigned int len = strlen(str);
233 
234 	if (s->full)
235 		return;
236 
237 	__trace_seq_init(s);
238 
239 	if (len > TRACE_SEQ_BUF_LEFT(s)) {
240 		s->full = 1;
241 		return;
242 	}
243 
244 	seq_buf_putmem(&s->seq, str, len);
245 }
246 EXPORT_SYMBOL_GPL(trace_seq_puts);
247 
248 /**
249  * trace_seq_putc - trace sequence printing of simple character
250  * @s: trace sequence descriptor
251  * @c: simple character to record
252  *
253  * The tracer may use either the sequence operations or its own
254  * copy to user routines. This function records a simple character
255  * into a special buffer (@s) for later retrieval by a sequencer
256  * or other mechanism.
257  */
258 void trace_seq_putc(struct trace_seq *s, unsigned char c)
259 {
260 	if (s->full)
261 		return;
262 
263 	__trace_seq_init(s);
264 
265 	if (TRACE_SEQ_BUF_LEFT(s) < 1) {
266 		s->full = 1;
267 		return;
268 	}
269 
270 	seq_buf_putc(&s->seq, c);
271 }
272 EXPORT_SYMBOL_GPL(trace_seq_putc);
273 
274 /**
275  * trace_seq_putmem - write raw data into the trace_seq buffer
276  * @s: trace sequence descriptor
277  * @mem: The raw memory to copy into the buffer
278  * @len: The length of the raw memory to copy (in bytes)
279  *
280  * There may be cases where raw memory needs to be written into the
281  * buffer and a strcpy() would not work. Using this function allows
282  * for such cases.
283  */
284 void trace_seq_putmem(struct trace_seq *s, const void *mem, unsigned int len)
285 {
286 	if (s->full)
287 		return;
288 
289 	__trace_seq_init(s);
290 
291 	if (len > TRACE_SEQ_BUF_LEFT(s)) {
292 		s->full = 1;
293 		return;
294 	}
295 
296 	seq_buf_putmem(&s->seq, mem, len);
297 }
298 EXPORT_SYMBOL_GPL(trace_seq_putmem);
299 
300 /**
301  * trace_seq_putmem_hex - write raw memory into the buffer in ASCII hex
302  * @s: trace sequence descriptor
303  * @mem: The raw memory to write its hex ASCII representation of
304  * @len: The length of the raw memory to copy (in bytes)
305  *
306  * This is similar to trace_seq_putmem() except instead of just copying the
307  * raw memory into the buffer it writes its ASCII representation of it
308  * in hex characters.
309  */
310 void trace_seq_putmem_hex(struct trace_seq *s, const void *mem,
311 			 unsigned int len)
312 {
313 	unsigned int save_len = s->seq.len;
314 
315 	if (s->full)
316 		return;
317 
318 	__trace_seq_init(s);
319 
320 	/* Each byte is represented by two chars */
321 	if (len * 2 > TRACE_SEQ_BUF_LEFT(s)) {
322 		s->full = 1;
323 		return;
324 	}
325 
326 	/* The added spaces can still cause an overflow */
327 	seq_buf_putmem_hex(&s->seq, mem, len);
328 
329 	if (unlikely(seq_buf_has_overflowed(&s->seq))) {
330 		s->seq.len = save_len;
331 		s->full = 1;
332 		return;
333 	}
334 }
335 EXPORT_SYMBOL_GPL(trace_seq_putmem_hex);
336 
337 /**
338  * trace_seq_path - copy a path into the sequence buffer
339  * @s: trace sequence descriptor
340  * @path: path to write into the sequence buffer.
341  *
342  * Write a path name into the sequence buffer.
343  *
344  * Returns 1 if we successfully written all the contents to
345  *   the buffer.
346  * Returns 0 if we the length to write is bigger than the
347  *   reserved buffer space. In this case, nothing gets written.
348  */
349 int trace_seq_path(struct trace_seq *s, const struct path *path)
350 {
351 	unsigned int save_len = s->seq.len;
352 
353 	if (s->full)
354 		return 0;
355 
356 	__trace_seq_init(s);
357 
358 	if (TRACE_SEQ_BUF_LEFT(s) < 1) {
359 		s->full = 1;
360 		return 0;
361 	}
362 
363 	seq_buf_path(&s->seq, path, "\n");
364 
365 	if (unlikely(seq_buf_has_overflowed(&s->seq))) {
366 		s->seq.len = save_len;
367 		s->full = 1;
368 		return 0;
369 	}
370 
371 	return 1;
372 }
373 EXPORT_SYMBOL_GPL(trace_seq_path);
374 
375 /**
376  * trace_seq_to_user - copy the sequence buffer to user space
377  * @s: trace sequence descriptor
378  * @ubuf: The userspace memory location to copy to
379  * @cnt: The amount to copy
380  *
381  * Copies the sequence buffer into the userspace memory pointed to
382  * by @ubuf. It starts from the last read position (@s->readpos)
383  * and writes up to @cnt characters or till it reaches the end of
384  * the content in the buffer (@s->len), which ever comes first.
385  *
386  * On success, it returns a positive number of the number of bytes
387  * it copied.
388  *
389  * On failure it returns -EBUSY if all of the content in the
390  * sequence has been already read, which includes nothing in the
391  * sequence (@s->len == @s->readpos).
392  *
393  * Returns -EFAULT if the copy to userspace fails.
394  */
395 int trace_seq_to_user(struct trace_seq *s, char __user *ubuf, int cnt)
396 {
397 	int ret;
398 	__trace_seq_init(s);
399 	ret = seq_buf_to_user(&s->seq, ubuf, s->readpos, cnt);
400 	if (ret > 0)
401 		s->readpos += ret;
402 	return ret;
403 }
404 EXPORT_SYMBOL_GPL(trace_seq_to_user);
405 
406 int trace_seq_hex_dump(struct trace_seq *s, const char *prefix_str,
407 		       int prefix_type, int rowsize, int groupsize,
408 		       const void *buf, size_t len, bool ascii)
409 {
410 	unsigned int save_len = s->seq.len;
411 
412 	if (s->full)
413 		return 0;
414 
415 	__trace_seq_init(s);
416 
417 	if (TRACE_SEQ_BUF_LEFT(s) < 1) {
418 		s->full = 1;
419 		return 0;
420 	}
421 
422 	seq_buf_hex_dump(&(s->seq), prefix_str,
423 		   prefix_type, rowsize, groupsize,
424 		   buf, len, ascii);
425 
426 	if (unlikely(seq_buf_has_overflowed(&s->seq))) {
427 		s->seq.len = save_len;
428 		s->full = 1;
429 		return 0;
430 	}
431 
432 	return 1;
433 }
434 EXPORT_SYMBOL(trace_seq_hex_dump);
435 
436 /*
437  * trace_seq_acquire - acquire seq buffer with size len
438  * @s: trace sequence descriptor
439  * @len: size of buffer to be acquired
440  *
441  * acquire buffer with size of @len from trace_seq for output usage,
442  * user can fill string into that buffer.
443  *
444  * Returns start address of acquired buffer.
445  *
446  * it allow multiple usage in one trace output function call.
447  */
448 char *trace_seq_acquire(struct trace_seq *s, unsigned int len)
449 {
450 	char *ret = trace_seq_buffer_ptr(s);
451 
452 	if (!WARN_ON_ONCE(seq_buf_buffer_left(&s->seq) < len))
453 		seq_buf_commit(&s->seq, len);
454 
455 	return ret;
456 }
457 EXPORT_SYMBOL(trace_seq_acquire);
458