aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt (Red Hat) <rostedt@goodmis.org>2014-06-20 17:38:01 -0400
committerSteven Rostedt <rostedt@goodmis.org>2014-07-01 07:13:36 -0400
commit36aabfff50b6a03bcfd2c3cfbd7b83eb0a9ce0c1 (patch)
treea8e9df6eb61e93288596fcd3e60ba138214118a2
parent12306276fabcb746a14979e96f43a13c724dec49 (diff)
tracing: Clean up trace_seq.c
For using trace_seq_*() functions in NMI context, I posted a patch to move it to the lib/ directory. This caused Andrew Morton to take a look at the code. He went through and gave a lot of comments about missing kernel doc, inconsistent types for the save variable, mix match of EXPORT_SYMBOL_GPL() and EXPORT_SYMBOL() as well as missing EXPORT_SYMBOL*()s. There were a few comments about the way variables were being compared (int vs uint). All these were good review comments and should be implemented regardless of if trace_seq.c should be moved to lib/ or not. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--include/linux/trace_seq.h20
-rw-r--r--kernel/trace/trace_seq.c207
2 files changed, 185 insertions, 42 deletions
diff --git a/include/linux/trace_seq.h b/include/linux/trace_seq.h
index 66ea365acf01..1f05317f51c4 100644
--- a/include/linux/trace_seq.h
+++ b/include/linux/trace_seq.h
@@ -38,14 +38,14 @@ int trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args);
38extern int 38extern int
39trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary); 39trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary);
40extern int trace_print_seq(struct seq_file *m, struct trace_seq *s); 40extern int trace_print_seq(struct seq_file *m, struct trace_seq *s);
41extern ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, 41extern int trace_seq_to_user(struct trace_seq *s, char __user *ubuf,
42 size_t cnt); 42 int cnt);
43extern int trace_seq_puts(struct trace_seq *s, const char *str); 43extern int trace_seq_puts(struct trace_seq *s, const char *str);
44extern int trace_seq_putc(struct trace_seq *s, unsigned char c); 44extern int trace_seq_putc(struct trace_seq *s, unsigned char c);
45extern int trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len); 45extern int trace_seq_putmem(struct trace_seq *s, const void *mem, unsigned int len);
46extern int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, 46extern int trace_seq_putmem_hex(struct trace_seq *s, const void *mem,
47 size_t len); 47 unsigned int len);
48extern void *trace_seq_reserve(struct trace_seq *s, size_t len); 48extern void *trace_seq_reserve(struct trace_seq *s, unsigned int len);
49extern int trace_seq_path(struct trace_seq *s, const struct path *path); 49extern int trace_seq_path(struct trace_seq *s, const struct path *path);
50 50
51extern int trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp, 51extern int trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp,
@@ -73,8 +73,8 @@ static inline int trace_print_seq(struct seq_file *m, struct trace_seq *s)
73{ 73{
74 return 0; 74 return 0;
75} 75}
76static inline ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, 76static inline int trace_seq_to_user(struct trace_seq *s, char __user *ubuf,
77 size_t cnt) 77 int cnt)
78{ 78{
79 return 0; 79 return 0;
80} 80}
@@ -87,16 +87,16 @@ static inline int trace_seq_putc(struct trace_seq *s, unsigned char c)
87 return 0; 87 return 0;
88} 88}
89static inline int 89static inline int
90trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len) 90trace_seq_putmem(struct trace_seq *s, const void *mem, unsigned int len)
91{ 91{
92 return 0; 92 return 0;
93} 93}
94static inline int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, 94static inline int trace_seq_putmem_hex(struct trace_seq *s, const void *mem,
95 size_t len) 95 unsigned int len)
96{ 96{
97 return 0; 97 return 0;
98} 98}
99static inline void *trace_seq_reserve(struct trace_seq *s, size_t len) 99static inline void *trace_seq_reserve(struct trace_seq *s, unsigned int len)
100{ 100{
101 return NULL; 101 return NULL;
102} 102}
diff --git a/kernel/trace/trace_seq.c b/kernel/trace/trace_seq.c
index 5ba99c6cf834..0fabca773e51 100644
--- a/kernel/trace/trace_seq.c
+++ b/kernel/trace/trace_seq.c
@@ -3,21 +3,55 @@
3 * 3 *
4 * Copyright (C) 2008-2014 Red Hat Inc, Steven Rostedt <srostedt@redhat.com> 4 * Copyright (C) 2008-2014 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
5 * 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 *
6 */ 24 */
7#include <linux/uaccess.h> 25#include <linux/uaccess.h>
8#include <linux/seq_file.h> 26#include <linux/seq_file.h>
9#include <linux/trace_seq.h> 27#include <linux/trace_seq.h>
10 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 */
11int trace_print_seq(struct seq_file *m, struct trace_seq *s) 44int trace_print_seq(struct seq_file *m, struct trace_seq *s)
12{ 45{
13 int len = s->len >= PAGE_SIZE ? PAGE_SIZE - 1 : s->len; 46 unsigned int len = TRACE_SEQ_BUF_USED(s);
14 int ret; 47 int ret;
15 48
16 ret = seq_write(m, s->buffer, len); 49 ret = seq_write(m, s->buffer, len);
17 50
18 /* 51 /*
19 * Only reset this buffer if we successfully wrote to the 52 * Only reset this buffer if we successfully wrote to the
20 * seq_file buffer. 53 * seq_file buffer. This lets the caller try again or
54 * do something else with the contents.
21 */ 55 */
22 if (!ret) 56 if (!ret)
23 trace_seq_init(s); 57 trace_seq_init(s);
@@ -30,19 +64,20 @@ int trace_print_seq(struct seq_file *m, struct trace_seq *s)
30 * @s: trace sequence descriptor 64 * @s: trace sequence descriptor
31 * @fmt: printf format string 65 * @fmt: printf format string
32 * 66 *
33 * It returns 0 if the trace oversizes the buffer's free
34 * space, 1 otherwise.
35 *
36 * The tracer may use either sequence operations or its own 67 * The tracer may use either sequence operations or its own
37 * copy to user routines. To simplify formating of a trace 68 * copy to user routines. To simplify formating of a trace
38 * trace_seq_printf is used to store strings into a special 69 * trace_seq_printf() is used to store strings into a special
39 * buffer (@s). Then the output may be either used by 70 * buffer (@s). Then the output may be either used by
40 * the sequencer or pulled into another buffer. 71 * the sequencer or pulled into another buffer.
72 *
73 * Returns 1 if we successfully written all the contents to
74 * the buffer.
75 * Returns 0 if we the length to write is bigger than the
76 * reserved buffer space. In this case, nothing gets written.
41 */ 77 */
42int 78int trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
43trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
44{ 79{
45 int len = (PAGE_SIZE - 1) - s->len; 80 unsigned int len = TRACE_SEQ_BUF_LEFT(s);
46 va_list ap; 81 va_list ap;
47 int ret; 82 int ret;
48 83
@@ -66,21 +101,22 @@ trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
66EXPORT_SYMBOL_GPL(trace_seq_printf); 101EXPORT_SYMBOL_GPL(trace_seq_printf);
67 102
68/** 103/**
69 * trace_seq_bitmask - put a list of longs as a bitmask print output 104 * trace_seq_bitmask - write a bitmask array in its ASCII representation
70 * @s: trace sequence descriptor 105 * @s: trace sequence descriptor
71 * @maskp: points to an array of unsigned longs that represent a bitmask 106 * @maskp: points to an array of unsigned longs that represent a bitmask
72 * @nmaskbits: The number of bits that are valid in @maskp 107 * @nmaskbits: The number of bits that are valid in @maskp
73 * 108 *
74 * It returns 0 if the trace oversizes the buffer's free
75 * space, 1 otherwise.
76 *
77 * Writes a ASCII representation of a bitmask string into @s. 109 * Writes a ASCII representation of a bitmask string into @s.
110 *
111 * Returns 1 if we successfully written all the contents to
112 * the buffer.
113 * Returns 0 if we the length to write is bigger than the
114 * reserved buffer space. In this case, nothing gets written.
78 */ 115 */
79int 116int trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp,
80trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp, 117 int nmaskbits)
81 int nmaskbits)
82{ 118{
83 int len = (PAGE_SIZE - 1) - s->len; 119 unsigned int len = TRACE_SEQ_BUF_LEFT(s);
84 int ret; 120 int ret;
85 121
86 if (s->full || !len) 122 if (s->full || !len)
@@ -103,11 +139,12 @@ EXPORT_SYMBOL_GPL(trace_seq_bitmask);
103 * trace_seq_printf is used to store strings into a special 139 * trace_seq_printf is used to store strings into a special
104 * buffer (@s). Then the output may be either used by 140 * buffer (@s). Then the output may be either used by
105 * the sequencer or pulled into another buffer. 141 * the sequencer or pulled into another buffer.
142 *
143 * Returns how much it wrote to the buffer.
106 */ 144 */
107int 145int trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args)
108trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args)
109{ 146{
110 int len = (PAGE_SIZE - 1) - s->len; 147 unsigned int len = TRACE_SEQ_BUF_LEFT(s);
111 int ret; 148 int ret;
112 149
113 if (s->full || !len) 150 if (s->full || !len)
@@ -127,9 +164,26 @@ trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args)
127} 164}
128EXPORT_SYMBOL_GPL(trace_seq_vprintf); 165EXPORT_SYMBOL_GPL(trace_seq_vprintf);
129 166
167/**
168 * trace_seq_bprintf - Write the printf string from binary arguments
169 * @s: trace sequence descriptor
170 * @fmt: The format string for the @binary arguments
171 * @binary: The binary arguments for @fmt.
172 *
173 * When recording in a fast path, a printf may be recorded with just
174 * saving the format and the arguments as they were passed to the
175 * function, instead of wasting cycles converting the arguments into
176 * ASCII characters. Instead, the arguments are saved in a 32 bit
177 * word array that is defined by the format string constraints.
178 *
179 * This function will take the format and the binary array and finish
180 * the conversion into the ASCII string within the buffer.
181 *
182 * Returns how much it wrote to the buffer.
183 */
130int trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary) 184int trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary)
131{ 185{
132 int len = (PAGE_SIZE - 1) - s->len; 186 unsigned int len = TRACE_SEQ_BUF_LEFT(s);
133 int ret; 187 int ret;
134 188
135 if (s->full || !len) 189 if (s->full || !len)
@@ -147,6 +201,7 @@ int trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary)
147 201
148 return len; 202 return len;
149} 203}
204EXPORT_SYMBOL_GPL(trace_seq_bprintf);
150 205
151/** 206/**
152 * trace_seq_puts - trace sequence printing of simple string 207 * trace_seq_puts - trace sequence printing of simple string
@@ -157,15 +212,17 @@ int trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary)
157 * copy to user routines. This function records a simple string 212 * copy to user routines. This function records a simple string
158 * into a special buffer (@s) for later retrieval by a sequencer 213 * into a special buffer (@s) for later retrieval by a sequencer
159 * or other mechanism. 214 * or other mechanism.
215 *
216 * Returns how much it wrote to the buffer.
160 */ 217 */
161int trace_seq_puts(struct trace_seq *s, const char *str) 218int trace_seq_puts(struct trace_seq *s, const char *str)
162{ 219{
163 int len = strlen(str); 220 unsigned int len = strlen(str);
164 221
165 if (s->full) 222 if (s->full)
166 return 0; 223 return 0;
167 224
168 if (len > ((PAGE_SIZE - 1) - s->len)) { 225 if (len > TRACE_SEQ_BUF_LEFT(s)) {
169 s->full = 1; 226 s->full = 1;
170 return 0; 227 return 0;
171 } 228 }
@@ -175,13 +232,26 @@ int trace_seq_puts(struct trace_seq *s, const char *str)
175 232
176 return len; 233 return len;
177} 234}
235EXPORT_SYMBOL_GPL(trace_seq_puts);
178 236
237/**
238 * trace_seq_putc - trace sequence printing of simple character
239 * @s: trace sequence descriptor
240 * @c: simple character to record
241 *
242 * The tracer may use either the sequence operations or its own
243 * copy to user routines. This function records a simple charater
244 * into a special buffer (@s) for later retrieval by a sequencer
245 * or other mechanism.
246 *
247 * Returns how much it wrote to the buffer.
248 */
179int trace_seq_putc(struct trace_seq *s, unsigned char c) 249int trace_seq_putc(struct trace_seq *s, unsigned char c)
180{ 250{
181 if (s->full) 251 if (s->full)
182 return 0; 252 return 0;
183 253
184 if (s->len >= (PAGE_SIZE - 1)) { 254 if (TRACE_SEQ_BUF_LEFT(s) < 1) {
185 s->full = 1; 255 s->full = 1;
186 return 0; 256 return 0;
187 } 257 }
@@ -190,14 +260,26 @@ int trace_seq_putc(struct trace_seq *s, unsigned char c)
190 260
191 return 1; 261 return 1;
192} 262}
193EXPORT_SYMBOL(trace_seq_putc); 263EXPORT_SYMBOL_GPL(trace_seq_putc);
194 264
195int trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len) 265/**
266 * trace_seq_putmem - write raw data into the trace_seq buffer
267 * @s: trace sequence descriptor
268 * @mem: The raw memory to copy into the buffer
269 * @len: The length of the raw memory to copy (in bytes)
270 *
271 * There may be cases where raw memory needs to be written into the
272 * buffer and a strcpy() would not work. Using this function allows
273 * for such cases.
274 *
275 * Returns how much it wrote to the buffer.
276 */
277int trace_seq_putmem(struct trace_seq *s, const void *mem, unsigned int len)
196{ 278{
197 if (s->full) 279 if (s->full)
198 return 0; 280 return 0;
199 281
200 if (len > ((PAGE_SIZE - 1) - s->len)) { 282 if (len > TRACE_SEQ_BUF_LEFT(s)) {
201 s->full = 1; 283 s->full = 1;
202 return 0; 284 return 0;
203 } 285 }
@@ -207,10 +289,24 @@ int trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len)
207 289
208 return len; 290 return len;
209} 291}
292EXPORT_SYMBOL_GPL(trace_seq_putmem);
210 293
211#define HEX_CHARS (MAX_MEMHEX_BYTES*2 + 1) 294#define HEX_CHARS (MAX_MEMHEX_BYTES*2 + 1)
212 295
213int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, size_t len) 296/**
297 * trace_seq_putmem_hex - write raw memory into the buffer in ASCII hex
298 * @s: trace sequence descriptor
299 * @mem: The raw memory to write its hex ASCII representation of
300 * @len: The length of the raw memory to copy (in bytes)
301 *
302 * This is similar to trace_seq_putmem() except instead of just copying the
303 * raw memory into the buffer it writes its ASCII representation of it
304 * in hex characters.
305 *
306 * Returns how much it wrote to the buffer.
307 */
308int trace_seq_putmem_hex(struct trace_seq *s, const void *mem,
309 unsigned int len)
214{ 310{
215 unsigned char hex[HEX_CHARS]; 311 unsigned char hex[HEX_CHARS];
216 const unsigned char *data = mem; 312 const unsigned char *data = mem;
@@ -231,15 +327,27 @@ int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, size_t len)
231 327
232 return trace_seq_putmem(s, hex, j); 328 return trace_seq_putmem(s, hex, j);
233} 329}
330EXPORT_SYMBOL_GPL(trace_seq_putmem_hex);
234 331
235void *trace_seq_reserve(struct trace_seq *s, size_t len) 332/**
333 * trace_seq_reserve - reserve space on the sequence buffer
334 * @s: trace sequence descriptor
335 * @len: The amount to reserver.
336 *
337 * If for some reason there is a need to save some space on the
338 * buffer to fill in later, this function is used for that purpose.
339 * The given length will be reserved and the pointer to that
340 * location on the buffer is returned, unless there is not enough
341 * buffer left to hold the given length then NULL is returned.
342 */
343void *trace_seq_reserve(struct trace_seq *s, unsigned int len)
236{ 344{
237 void *ret; 345 void *ret;
238 346
239 if (s->full) 347 if (s->full)
240 return NULL; 348 return NULL;
241 349
242 if (len > ((PAGE_SIZE - 1) - s->len)) { 350 if (len > TRACE_SEQ_BUF_LEFT(s)) {
243 s->full = 1; 351 s->full = 1;
244 return NULL; 352 return NULL;
245 } 353 }
@@ -249,7 +357,20 @@ void *trace_seq_reserve(struct trace_seq *s, size_t len)
249 357
250 return ret; 358 return ret;
251} 359}
360EXPORT_SYMBOL_GPL(trace_seq_reserve);
252 361
362/**
363 * trace_seq_path - copy a path into the sequence buffer
364 * @s: trace sequence descriptor
365 * @path: path to write into the sequence buffer.
366 *
367 * Write a path name into the sequence buffer.
368 *
369 * Returns 1 if we successfully written all the contents to
370 * the buffer.
371 * Returns 0 if we the length to write is bigger than the
372 * reserved buffer space. In this case, nothing gets written.
373 */
253int trace_seq_path(struct trace_seq *s, const struct path *path) 374int trace_seq_path(struct trace_seq *s, const struct path *path)
254{ 375{
255 unsigned char *p; 376 unsigned char *p;
@@ -257,7 +378,7 @@ int trace_seq_path(struct trace_seq *s, const struct path *path)
257 if (s->full) 378 if (s->full)
258 return 0; 379 return 0;
259 380
260 if (s->len >= (PAGE_SIZE - 1)) { 381 if (TRACE_SEQ_BUF_LEFT(s) < 1) {
261 s->full = 1; 382 s->full = 1;
262 return 0; 383 return 0;
263 } 384 }
@@ -277,8 +398,29 @@ int trace_seq_path(struct trace_seq *s, const struct path *path)
277 s->full = 1; 398 s->full = 1;
278 return 0; 399 return 0;
279} 400}
401EXPORT_SYMBOL_GPL(trace_seq_path);
280 402
281ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, size_t cnt) 403/**
404 * trace_seq_to_user - copy the squence buffer to user space
405 * @s: trace sequence descriptor
406 * @ubuf: The userspace memory location to copy to
407 * @cnt: The amount to copy
408 *
409 * Copies the sequence buffer into the userspace memory pointed to
410 * by @ubuf. It starts from the last read position (@s->readpos)
411 * and writes up to @cnt characters or till it reaches the end of
412 * the content in the buffer (@s->len), which ever comes first.
413 *
414 * On success, it returns a positive number of the number of bytes
415 * it copied.
416 *
417 * On failure it returns -EBUSY if all of the content in the
418 * sequence has been already read, which includes nothing in the
419 * sequenc (@s->len == @s->readpos).
420 *
421 * Returns -EFAULT if the copy to userspace fails.
422 */
423int trace_seq_to_user(struct trace_seq *s, char __user *ubuf, int cnt)
282{ 424{
283 int len; 425 int len;
284 int ret; 426 int ret;
@@ -301,3 +443,4 @@ ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, size_t cnt)
301 s->readpos += cnt; 443 s->readpos += cnt;
302 return cnt; 444 return cnt;
303} 445}
446EXPORT_SYMBOL_GPL(trace_seq_to_user);