Merge tag 'ftracetest-3.19' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt...
[firefly-linux-kernel-4.4.55.git] / kernel / trace / trace_seq.c
1 /*
2  * trace_seq.c
3  *
4  * Copyright (C) 2008-2014 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
5  *
6  * The trace_seq is a handy tool that allows you to pass a descriptor around
7  * to a buffer that other functions can write to. It is similar to the
8  * seq_file functionality but has some differences.
9  *
10  * To use it, the trace_seq must be initialized with trace_seq_init().
11  * This will set up the counters within the descriptor. You can call
12  * trace_seq_init() more than once to reset the trace_seq to start
13  * from scratch.
14  * 
15  * The buffer size is currently PAGE_SIZE, although it may become dynamic
16  * in the future.
17  *
18  * A write to the buffer will either succed or fail. That is, unlike
19  * sprintf() there will not be a partial write (well it may write into
20  * the buffer but it wont update the pointers). This allows users to
21  * try to write something into the trace_seq buffer and if it fails
22  * they can flush it and try again.
23  *
24  */
25 #include <linux/uaccess.h>
26 #include <linux/seq_file.h>
27 #include <linux/trace_seq.h>
28
29 /* How much buffer is left on the trace_seq? */
30 #define TRACE_SEQ_BUF_LEFT(s) ((PAGE_SIZE - 1) - (s)->len)
31
32 /* How much buffer is written? */
33 #define TRACE_SEQ_BUF_USED(s) min((s)->len, (unsigned int)(PAGE_SIZE - 1))
34
35 /**
36  * trace_print_seq - move the contents of trace_seq into a seq_file
37  * @m: the seq_file descriptor that is the destination
38  * @s: the trace_seq descriptor that is the source.
39  *
40  * Returns 0 on success and non zero on error. If it succeeds to
41  * write to the seq_file it will reset the trace_seq, otherwise
42  * it does not modify the trace_seq to let the caller try again.
43  */
44 int trace_print_seq(struct seq_file *m, struct trace_seq *s)
45 {
46         unsigned int len = TRACE_SEQ_BUF_USED(s);
47         int ret;
48
49         ret = seq_write(m, s->buffer, len);
50
51         /*
52          * Only reset this buffer if we successfully wrote to the
53          * seq_file buffer. This lets the caller try again or
54          * do something else with the contents.
55          */
56         if (!ret)
57                 trace_seq_init(s);
58
59         return ret;
60 }
61
62 /**
63  * trace_seq_printf - sequence printing of trace information
64  * @s: trace sequence descriptor
65  * @fmt: printf format string
66  *
67  * The tracer may use either sequence operations or its own
68  * copy to user routines. To simplify formating of a trace
69  * trace_seq_printf() is used to store strings into a special
70  * buffer (@s). Then the output may be either used by
71  * the sequencer or pulled into another buffer.
72  */
73 void trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
74 {
75         unsigned int len = TRACE_SEQ_BUF_LEFT(s);
76         va_list ap;
77         int ret;
78
79         if (s->full || !len)
80                 return;
81
82         va_start(ap, fmt);
83         ret = vsnprintf(s->buffer + s->len, len, fmt, ap);
84         va_end(ap);
85
86         /* If we can't write it all, don't bother writing anything */
87         if (ret >= len) {
88                 s->full = 1;
89                 return;
90         }
91
92         s->len += ret;
93 }
94 EXPORT_SYMBOL_GPL(trace_seq_printf);
95
96 /**
97  * trace_seq_bitmask - write a bitmask array in its ASCII representation
98  * @s:          trace sequence descriptor
99  * @maskp:      points to an array of unsigned longs that represent a bitmask
100  * @nmaskbits:  The number of bits that are valid in @maskp
101  *
102  * Writes a ASCII representation of a bitmask string into @s.
103  */
104 void trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp,
105                       int nmaskbits)
106 {
107         unsigned int len = TRACE_SEQ_BUF_LEFT(s);
108         int ret;
109
110         if (s->full || !len)
111                 return;
112
113         ret = bitmap_scnprintf(s->buffer + s->len, len, maskp, nmaskbits);
114         s->len += ret;
115 }
116 EXPORT_SYMBOL_GPL(trace_seq_bitmask);
117
118 /**
119  * trace_seq_vprintf - sequence printing of trace information
120  * @s: trace sequence descriptor
121  * @fmt: printf format string
122  *
123  * The tracer may use either sequence operations or its own
124  * copy to user routines. To simplify formating of a trace
125  * trace_seq_printf is used to store strings into a special
126  * buffer (@s). Then the output may be either used by
127  * the sequencer or pulled into another buffer.
128  */
129 void trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args)
130 {
131         unsigned int len = TRACE_SEQ_BUF_LEFT(s);
132         int ret;
133
134         if (s->full || !len)
135                 return;
136
137         ret = vsnprintf(s->buffer + s->len, len, fmt, args);
138
139         /* If we can't write it all, don't bother writing anything */
140         if (ret >= len) {
141                 s->full = 1;
142                 return;
143         }
144
145         s->len += ret;
146 }
147 EXPORT_SYMBOL_GPL(trace_seq_vprintf);
148
149 /**
150  * trace_seq_bprintf - Write the printf string from binary arguments
151  * @s: trace sequence descriptor
152  * @fmt: The format string for the @binary arguments
153  * @binary: The binary arguments for @fmt.
154  *
155  * When recording in a fast path, a printf may be recorded with just
156  * saving the format and the arguments as they were passed to the
157  * function, instead of wasting cycles converting the arguments into
158  * ASCII characters. Instead, the arguments are saved in a 32 bit
159  * word array that is defined by the format string constraints.
160  *
161  * This function will take the format and the binary array and finish
162  * the conversion into the ASCII string within the buffer.
163  */
164 void trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary)
165 {
166         unsigned int len = TRACE_SEQ_BUF_LEFT(s);
167         int ret;
168
169         if (s->full || !len)
170                 return;
171
172         ret = bstr_printf(s->buffer + s->len, len, fmt, binary);
173
174         /* If we can't write it all, don't bother writing anything */
175         if (ret >= len) {
176                 s->full = 1;
177                 return;
178         }
179
180         s->len += ret;
181 }
182 EXPORT_SYMBOL_GPL(trace_seq_bprintf);
183
184 /**
185  * trace_seq_puts - trace sequence printing of simple string
186  * @s: trace sequence descriptor
187  * @str: simple string to record
188  *
189  * The tracer may use either the sequence operations or its own
190  * copy to user routines. This function records a simple string
191  * into a special buffer (@s) for later retrieval by a sequencer
192  * or other mechanism.
193  */
194 void trace_seq_puts(struct trace_seq *s, const char *str)
195 {
196         unsigned int len = strlen(str);
197
198         if (s->full)
199                 return;
200
201         if (len > TRACE_SEQ_BUF_LEFT(s)) {
202                 s->full = 1;
203                 return;
204         }
205
206         memcpy(s->buffer + s->len, str, len);
207         s->len += len;
208 }
209 EXPORT_SYMBOL_GPL(trace_seq_puts);
210
211 /**
212  * trace_seq_putc - trace sequence printing of simple character
213  * @s: trace sequence descriptor
214  * @c: simple character to record
215  *
216  * The tracer may use either the sequence operations or its own
217  * copy to user routines. This function records a simple charater
218  * into a special buffer (@s) for later retrieval by a sequencer
219  * or other mechanism.
220  */
221 void trace_seq_putc(struct trace_seq *s, unsigned char c)
222 {
223         if (s->full)
224                 return;
225
226         if (TRACE_SEQ_BUF_LEFT(s) < 1) {
227                 s->full = 1;
228                 return;
229         }
230
231         s->buffer[s->len++] = c;
232 }
233 EXPORT_SYMBOL_GPL(trace_seq_putc);
234
235 /**
236  * trace_seq_putmem - write raw data into the trace_seq buffer
237  * @s: trace sequence descriptor
238  * @mem: The raw memory to copy into the buffer
239  * @len: The length of the raw memory to copy (in bytes)
240  *
241  * There may be cases where raw memory needs to be written into the
242  * buffer and a strcpy() would not work. Using this function allows
243  * for such cases.
244  */
245 void trace_seq_putmem(struct trace_seq *s, const void *mem, unsigned int len)
246 {
247         if (s->full)
248                 return;
249
250         if (len > TRACE_SEQ_BUF_LEFT(s)) {
251                 s->full = 1;
252                 return;
253         }
254
255         memcpy(s->buffer + s->len, mem, len);
256         s->len += len;
257 }
258 EXPORT_SYMBOL_GPL(trace_seq_putmem);
259
260 #define MAX_MEMHEX_BYTES        8U
261 #define HEX_CHARS               (MAX_MEMHEX_BYTES*2 + 1)
262
263 /**
264  * trace_seq_putmem_hex - write raw memory into the buffer in ASCII hex
265  * @s: trace sequence descriptor
266  * @mem: The raw memory to write its hex ASCII representation of
267  * @len: The length of the raw memory to copy (in bytes)
268  *
269  * This is similar to trace_seq_putmem() except instead of just copying the
270  * raw memory into the buffer it writes its ASCII representation of it
271  * in hex characters.
272  */
273 void trace_seq_putmem_hex(struct trace_seq *s, const void *mem,
274                          unsigned int len)
275 {
276         unsigned char hex[HEX_CHARS];
277         const unsigned char *data = mem;
278         unsigned int start_len;
279         int i, j;
280
281         if (s->full)
282                 return;
283
284         while (len) {
285                 start_len = min(len, HEX_CHARS - 1);
286 #ifdef __BIG_ENDIAN
287                 for (i = 0, j = 0; i < start_len; i++) {
288 #else
289                 for (i = start_len-1, j = 0; i >= 0; i--) {
290 #endif
291                         hex[j++] = hex_asc_hi(data[i]);
292                         hex[j++] = hex_asc_lo(data[i]);
293                 }
294                 if (WARN_ON_ONCE(j == 0 || j/2 > len))
295                         break;
296
297                 /* j increments twice per loop */
298                 len -= j / 2;
299                 hex[j++] = ' ';
300
301                 trace_seq_putmem(s, hex, j);
302         }
303 }
304 EXPORT_SYMBOL_GPL(trace_seq_putmem_hex);
305
306 /**
307  * trace_seq_path - copy a path into the sequence buffer
308  * @s: trace sequence descriptor
309  * @path: path to write into the sequence buffer.
310  *
311  * Write a path name into the sequence buffer.
312  *
313  * Returns 1 if we successfully written all the contents to
314  *   the buffer.
315  * Returns 0 if we the length to write is bigger than the
316  *   reserved buffer space. In this case, nothing gets written.
317  */
318 int trace_seq_path(struct trace_seq *s, const struct path *path)
319 {
320         unsigned char *p;
321
322         if (s->full)
323                 return 0;
324
325         if (TRACE_SEQ_BUF_LEFT(s) < 1) {
326                 s->full = 1;
327                 return 0;
328         }
329
330         p = d_path(path, s->buffer + s->len, PAGE_SIZE - s->len);
331         if (!IS_ERR(p)) {
332                 p = mangle_path(s->buffer + s->len, p, "\n");
333                 if (p) {
334                         s->len = p - s->buffer;
335                         return 1;
336                 }
337         } else {
338                 s->buffer[s->len++] = '?';
339                 return 1;
340         }
341
342         s->full = 1;
343         return 0;
344 }
345 EXPORT_SYMBOL_GPL(trace_seq_path);
346
347 /**
348  * trace_seq_to_user - copy the squence buffer to user space
349  * @s: trace sequence descriptor
350  * @ubuf: The userspace memory location to copy to
351  * @cnt: The amount to copy
352  *
353  * Copies the sequence buffer into the userspace memory pointed to
354  * by @ubuf. It starts from the last read position (@s->readpos)
355  * and writes up to @cnt characters or till it reaches the end of
356  * the content in the buffer (@s->len), which ever comes first.
357  *
358  * On success, it returns a positive number of the number of bytes
359  * it copied.
360  *
361  * On failure it returns -EBUSY if all of the content in the
362  * sequence has been already read, which includes nothing in the
363  * sequenc (@s->len == @s->readpos).
364  *
365  * Returns -EFAULT if the copy to userspace fails.
366  */
367 int trace_seq_to_user(struct trace_seq *s, char __user *ubuf, int cnt)
368 {
369         int len;
370         int ret;
371
372         if (!cnt)
373                 return 0;
374
375         if (s->len <= s->readpos)
376                 return -EBUSY;
377
378         len = s->len - s->readpos;
379         if (cnt > len)
380                 cnt = len;
381         ret = copy_to_user(ubuf, s->buffer + s->readpos, cnt);
382         if (ret == cnt)
383                 return -EFAULT;
384
385         cnt -= ret;
386
387         s->readpos += cnt;
388         return cnt;
389 }
390 EXPORT_SYMBOL_GPL(trace_seq_to_user);